1. 程式人生 > >HTML5無外掛多媒體Media——音訊audio與視訊video

HTML5無外掛多媒體Media——音訊audio與視訊video

音訊與視訊現在已經變得越來越流行
各個網站為了保證跨瀏覽器的相容性
仍然選擇使用flash


(原始碼截自優酷)

多媒體標籤

使用

HTML5增加了audio與video兩個多媒體標籤
相容性還不錯,低版本IE不支援
可以使我們不需要使用任何瀏覽器外掛就能夠插入音訊與視訊控制元件
而且非常的簡單


(原始碼截自Bilibili)

元素用法如下:

<audio src="media/xi-Halcyon.mp3" id="demoAudio">不支援H5-audio</audio>
<video src="media/Animation.mp4"
id="demoVideo">
不支援H5-video</video>

標籤中內容如果瀏覽器不支援該標籤就會顯示
當然使用這兩個元素的時候
最起碼要新增src屬性,屬性值就是資源的url

但是每個瀏覽器由於版權問題支援的媒體格式也不同
所以就可以使用下面的方式

<audio id="demoAudio">
    <source src="media/xi-Halcyon.mp3">
    <source src="media/xi-Halcyon.ogg">
    ...
    不支援H5-audio
</audio>

<video id="demoVideo"
> <source src="media/Animation.mp4"> <source src="media/Animation.webm"> ... 不支援H5-video </video>

這樣指定不同的資源格式
也保證了各個瀏覽器的相容性

屬性

audio和video標籤除了src外
還有一些公有的屬性

屬性 描述
autoplay 設定該屬性後,音/視訊資源就緒後立即播放
controls 設定該屬性後,則顯示瀏覽器播放控制控制元件
loop 設定該屬性後,則音/視訊結束後重新迴圈開始播放
preload 設定該屬性後,則音/視訊在頁面載入時進行載入,並預備播放(使用autoplay會忽略該屬性)


前三個屬性屬性名與屬性值相同,直接新增屬性名即可
preload有如下屬性值

  • none 不載入資料
  • metedata 僅載入元資料(時長、位元率、幀大小等)
  • auto 瀏覽器載入它認為適量的媒體內容

比如想要在瀏覽器新增一段音樂
並且載入後立即播放,迴圈播放
使用瀏覽器的播放控制元件

<audio src="media/xi-Halcyon.mp3" id="demoVideo" autoplay controls loop></audio>

控制元件的樣式各個瀏覽器都不一樣
隨著瀏覽器版本的更新,可能還會更新樣式

video元素還有獨有的屬性poster
屬性值是圖片資源的url
用來設定視訊播放前的一張佔位圖片

<video src="media/Animation.mp4" id="demoVideo" width="500" height="400" poster="images/preimg.jpg" controls></video>

點選播放後,視訊正常播放

指令碼化音視訊

元素

使用js獲取dom節點就很簡單了

var a = document.getElementById('demoAudio');
var v = document.getElementById('demoVideo');

類似於image的Image建構函式
Audio也可以通過類似的方式建立(Video不可以)
區別在於Image建立的圖片是要插入文件的
但是Audio不需要

var a = new Audio('song.mp3');

然後可以為它新增autoplay、loop等屬性
然後新增到頁面

介面

在獲取的DOM節點上可以使用瀏覽器提供的介面屬性和方法
常用的屬性、方法如下

  • currentSrc 媒體資料的URL地址
  • volume 播放音量
    • 介於0~1(注意超範圍會報錯),預設1最大音量
  • muted 是否靜音
    • 設定true進入靜音模式
  • playbackRate 媒體播放速度
    • 預設1.0常速,>1快進,<1慢放(負值表回放但無瀏覽器實現此功能)
  • defaultPlaybackRate 媒體預設的播放速度
  • currentTime 當前播放時間(單位s)
  • duration 媒體時長(單位s)
  • play() 播放音/視訊
  • pause() 暫停音/視訊
  • load() 重新載入音/視訊(通常用於修改元素屬性後)

除此之外還有

  • played 已經播放的時間段
  • buffered 已經緩衝的時間段
  • seekable 使用者可以跳轉的時間段

它們都是TimeRanges物件
每個物件都有一個length屬性(表示當前時間段)
以及start()和end()方法(返回當前時間段的起始時間點和結束時間點,單位s)
start()和end()都有一個數字引數,表示第一個時間段
確定當前快取內容百分比:

var percentLoaded = Math.floor(song.buffered.end(0)/song.duration*100)

下面三個布林屬性表示媒體播放器的狀態

  • paused 是否暫停
  • seeking 是否正調到一個新的播放點
  • ended 是否播放結束並停止

並不是所有瀏覽器都支援video和audio的所有編解碼器
canPlayType()方法就是用來鑑定時候支援某一格式的媒體資源
返回字串maybe、probably或空字串
如果只傳入MIME型別,則返回maybe
如果同時傳入MIME型別和編解碼器,則返回probably(可能性增加了)
只是因為媒體檔案只不過是音/視訊的容器
真正決定檔案能否播放的還得是編碼格式

console.log(a.canPlayType('audio/mp4')); //maybe
console.log(a.canPlayType('audio/mp4;codecs="mp4a.40.2"')); //probably

下面的狀態位屬性也瞭解一下

  • readyState 就緒狀態
    • 0 = HAVE_NOTHING - 沒有關於音/視訊是否就緒的資訊
    • 1 = HAVE_METADATA - 關於音訊/視訊就緒的元資料
    • 2 = HAVE_CURRENT_DATA - 關於當前播放位置的資料是可用的,但沒有足夠的資料來播放下一幀/ms
    • 3 = HAVE_FUTURE_DATA - 當前及至少下一幀的資料可用
    • 4 = HAVE_ENOUGH_DATA - 可用資料足以開始播放
  • netWorkState 網路狀態
    • 0 = NETWORK_EMPTY - 音/視訊尚未初始化
    • 1 = NETWORK_IDLE - 音/視訊是活動的且已選取資源,但並未使用網路
    • 2 = NETWORK_LOADING - 瀏覽器正在下載資料
    • 3 = NETWORK_NO_SOURCE - 未找到音/視訊來源
  • error.code 錯誤狀態
    • 1 = MEDIA_ERR_ABORTED - 取回過程被使用者中止
    • 2 = MEDIA_ERR_NETWORK - 當下載時發生錯誤
    • 3 = MEDIA_ERR_DECODE - 當解碼時發生錯誤
    • 4 = MEDIA_ERR_SRC_NOT_SUPPORTED - 不支援音訊/視訊

事件

除了介面屬性方法以外
還有必不可少的事件模型
如果我們不想使用瀏覽器的控制元件而是定義自己的播放控制組件
就要使用這套事件了

  • play 播放時觸發
  • pause 暫停時觸發
  • loadedmetadata 瀏覽器獲取完媒體元資料時觸發
  • loadeddata 瀏覽器載入完當前幀媒體資料時觸發
  • ended 播放結束後停止時觸發

初次之外還有很多事件
很多不常用
在w3c截了一張圖

通過介面與事件
也可以簡單的實現自己簡陋的音樂播放器

<button id="btn">播放</button>
<span id="cur">0s</span>/<span id="dur">0s</span><br>
音量:<input type="range" id="vol">
var audio = new Audio('media/xi-Halcyon.mp3');
var btn = document.getElementById('btn');
var vol = document.getElementById('vol');
var cur = document.getElementById('cur');
var dur = document.getElementById('dur');
var state = 'pause';

vol.value = 100;
audio.onloadeddata = function(){
  dur.textContent = Math.floor(audio.duration) + 's';
}

setInterval(function(){
  cur.textContent = Math.floor(audio.currentTime) + 's';
}, 200);

btn.onclick = function(){
  if(state === 'play'){
    state = 'pause';
    btn.textContent = '播放';
    audio.pause();
  }else{
    state = 'play';
    btn.textContent = '暫停';
    audio.play();
  }
}


vol.oninput = function(){
  audio.volume = vol.value/100;
}