Audio和Video API
- 兩個重要概念:容器+解碼器
- 視頻容器中包括:音頻軌道+視頻軌道+一些其他元數(shù)據(jù)(封面、標(biāo)題、子標(biāo)題、字幕等等),視頻格式包括avi、flv、mp4、mkv、ogv等
- 解碼器:音頻解碼器包括AAC\MPEG-3\Ogg Vorbis,視頻解碼器包括H.264\vp8\Ogg Theora
- 使用API的好處:1. 作為瀏覽器的原生支持功能,無需安裝 2. 媒體元素向web頁面提供了通用、集成和可腳本制作的API
- vedio瀏覽器支持性檢測(控制臺返回為true則支持)
<!DOCTYPE html>
<html>
<title>HTML5 Video</title>
</html>
<body></body>
<script>
var hasVideo = !!(document.createElement('video').canPlayType);
console.log(hasVideo);
</script>
- 簡單的vedio元素(為了防止瀏覽器不支持HTML5視頻,可以將以flash方式插入的視頻放在相同的位置作為備選內(nèi)容)
<!DOCTYPE html>
<html>
<title>HTML5 Video</title>
</html>
<body>
<video src="video.webm" controls>
Your broswer does not support HTML5 video.
</video>
</body>
- 在影片中添加字幕,首先創(chuàng)建一個
subtitles_en.vtt文件,然后將該文件嵌入到vedio中
WEBVTT
1
00:00:01.000 --> 00:00:03.000
What do you think about HTML5 Video and WebVTT?...
2
00:00:04.000 --> 00:00:08.000
I think it's great.I can't wait for all the browsers to support it!
<video src="video.webm" controls>
<track label="English" kind="subtitles" srclang="en" src="subtitles_en.vtt" default>
Your browser does not support HTML5 video.
</video>
- audio音頻文件的加載和vedio類似
<!DOCTYPE html>
<html>
<title>HTML5 Audio</title>
</html>
<audio src="Backroad.ogg" controls>
An audio clip from Johann Sebastian Bach.
</audio>
- 為了防止瀏覽器不支持相關(guān)容器或者編解碼器,可以用source進(jìn)行備用聲明,瀏覽器會根據(jù)自身播放能力自動選擇,挑選最佳的來源進(jìn)行播放(可以在source元素中制定type屬性,指明容器類型和解碼方式)
<audio controls>
<source src="Backroad.ogg">
<source src="Backroad.mp3">
An audio clip from Johann Sebastian Bach.
</audio>
- vedio和audio中的
controls屬性是為了抗議用戶進(jìn)行控制,如果不寫這個屬性,音頻文件就看不見界面了,為了防止這種情況的發(fā)生,不寫controls屬性的時候要寫autoplay屬性,文件就會自動播放了 - 如果內(nèi)置的控件不適應(yīng)用戶界面的布局,或者希望可以通過默認(rèn)控件中沒有的的條件和動作來來控制音頻或視頻,可以通過一些內(nèi)置的javascript函數(shù)和特性。具體的不做列舉了
- 添加play按鈕控制音頻
<!DOCTYPE html>
<html>
<title>HTML5 Audio</title>
</html>
<audio id="clickSound">
<source src="Backroad.ogg">
</audio>
<button id="toggle" onclick="toggleSound()">Play</button>
<script type="text/javascript">
function toggleSound() {
var music = document.getElementById("clickSound");
var toggle = document.getElementById("toggle");
if(music.paused){
music.play();
toggle.innerHTML = "Pause";
}else {
music.pause();
toggle.innerHTML = "Play";
}
}
</script>
- 完整實例(每隔5s中抓取一個視頻幀,將該幀展示在canvas中,點擊canvas對應(yīng)的幀,視頻會從對應(yīng)幀的位置重新開始播放)
<!DOCTYPE html>
<html>
<title>HTML5 Video</title>
<video id="movies" autoplay oncanplay="startVideo()" onended="stopTimeLine()"
autobuffer="true" width="400px" height="300px">
<source src="video.webm">
</video>
<canvas id="timeline" width="400px" height="300px"></canvas>
<script>
//抓取幀的時間間隔:單位是ms
var updateInterval = 5000;
//時序中幀的尺寸
var frameWidth = 100;
var frameHeight = 75;
//時序的總幀數(shù)
var frameRows = 4;
var frameColumns = 4;
var frameGrid = frameRows * frameColumns;
//當(dāng)前幀
var frameCount = 0;
//播放完后取消計時器
var intervalId;
var videoStarted = false;
//把幀繪制到畫布上
function updateFrame() {
var video = document.getElementById("movies");
var ctx = timeline.getContext("2d");
//根據(jù)幀計算出當(dāng)前播放位置,然后以視頻為輸入?yún)?shù),繪制圖像
var framePosition = frameCount % frameGrid;
var frameX = (framePosition % frameColumns) * frameWidth;
var frameY = (Math.floor(framePosition / frameRows)) * frameHeight;
ctx.drawImage(video,0,0,400,300,frameX,frameY,frameWidth,frameHeight);
frameCount++;
}
function startVideo() {
//只在視頻第一次播放的時候設(shè)置計時器
if(videoStarted)
return;
//計算初始幀,然后以規(guī)定時間間隔創(chuàng)建其他幀
updateFrame();
intervalId = setInterval(updateFrame,updateInterval);
//單擊幀時設(shè)置處理器搜索視頻
var timeline = document.getElementById("timeline");
timeline.onclick = function (evt) {
var offX = evt.layerX - timeline.offsetLeft;
var offY = evt.layerY - timeline.offsetTop;
//從索引0開始計算單擊的是網(wǎng)絡(luò)中的哪個幀
var clickedFrame = Math.floor(offY/frameHeight)*frameRows;
clickedFrame += Math.floor(offX/frameWidth);
//打開啟頻后,找到實際幀
var seekFrame = (((Math.floor(frameCount/frameGrid))*frameGrid)+clickedFrame);
//如果用戶單擊當(dāng)前幀前面的幀,那么假設(shè)它是最后一幀
if(clickedFrame>(frameCount%16))
seekFrame-=frameGrid;
//不能再視頻播放前搜索
if(seekFrame<0)
return;
//搜索視頻到那一幀(以秒為單位)
var video = document.getElementById("movies");
video.currentTime = seekFrame*updateInterval/1000;
//然后將幀數(shù)設(shè)置給目標(biāo)
frameCount = seekFrame;
}
}
//停止收集時間線幀
function stopTimeLine() {
clearInterval(intervalId);
}
</script>
</html>
重點:計算canvas中每一個幀存放的位置,drawImage()函數(shù),計算點擊的canvas中幀是第幾個(目前沒有完全弄懂)