Html5視頻播放器-VideoJS+Audio標簽實現視頻,音頻及字幕同步播放


一,VideoJS介紹

  1. 引用腳本,videojs很為你着想,直接cdn了,你都不需要下載這些代碼放入自己的網站

    <link href=”http://vjs.zencdn.net/c/video-js.css” rel=”stylesheet”>
    <script src=”http://vjs.zencdn.net/c/video.js”></script>
    
  2. 如果需要支持IE8,這個js可以自動生成flash

    <!-- If you'd like to support IE8 -->
    <script src="http://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script>
    
  3. 頁面中加入一個Html5的video標簽

    <video id="my_video_1" class="video-js vjs-default-skin" 
        controls preload="auto" width="640" height="264" poster="my_video_poster.png" data-setup="{}">
        <source src="my_video.mp4" type="video/mp4">
        <source src="my_video.webm" type="video/webm">
    </video>
    

其中post就是視頻的縮略圖,那倆source一個指向mp4視頻,一個指向webm視頻,在頁面加載過程中,video.js會判斷瀏覽器支持哪個格式視頻,會自動加載可播放的視頻。 
簡單吧!

進階:使用api

獲取對象: 
后面那個就是就是video標簽的id值,這是myPlayer就是播放器對象了。

videojs("my-video").ready(function(){
    window.myPlayer = this;
    // EXAMPLE: Start playing the video.
    myPlayer.play();
});

方法:

獲取對象

var videoObj = videojs(“videoId”);

ready:

myPlayer.ready(function(){
    //在回調函數中,this代表當前播放器,
    //可以調用方法,也可以綁定事件。
})

播放:

myPlayer.play();

暫停:

myPlayer.pause();

獲取播放進度:

var whereYouAt = myPlayer.currentTime();

設置播放進度:

myPlayer.currentTime(120);

視頻持續時間,加載完成視頻才可以知道視頻時長,且在flash情況下無效

var howLongIsThis = myPlayer.duration();

緩沖,就是返回下載了多少

var whatHasBeenBuffered = myPlayer.buffered();

百分比的緩沖

var howMuchIsDownloaded = myPlayer.bufferedPercent();

聲音大小(0-1之間)

var howLoudIsIt = myPlayer.volume();

設置聲音大小

myPlayer.volume(0.5);

取得視頻的寬度

var howWideIsIt = myPlayer.width();

設置寬度:

myPlayer.width(640);

獲取高度

var howTallIsIt = myPlayer.height();

設置高度:

myPlayer.height(480);

一步到位的設置大小:

myPlayer.size(640,480);

全屏

myPlayer.enterFullScreen();

離開全屏

myPlayer.enterFullScreen();

添加事件

durationchange
ended //播放結束
firstplay
fullscreenchange
loadedalldata
loadeddata
loadedmetadata
loadstart
pause //暫停
play  //播放
progress
seeked
seeking
timeupdate
volumechange
waiting
resize inherited

var myFunc = function(){
// Do something when the event is fired
};

事件綁定

myPlayer.on("ended", function(){
    console.log("end", this.currentTime());
});
myPlayer.on("pause", function(){
    console.log("pause")
});

刪除事件

myPlayer.removeEvent(“eventName”, myFunc); 

雖然文章說明在不支持html5的情況下,會以flash播放,但在支持html5的firefox下播放mp4時,卻遇到很大的困難,雖然調用了flash,但一直無法播放(不過我也一直懷疑我的firefox下的flash有問題,不知道是不是真的)。不過如果你聽從videojs的建議,放兩個格式的視頻,就不會有這個問題了。

另外video的寫法中還有專門針對flash的寫法,當然你也可以用這個插件實現純粹的flash播放(只寫flash那部分就好,可以保證統一的瀏覽效果,不過iOS的瀏覽器不兼容flash,這就要你自己進行判斷來處理

 

二、Audio標簽介紹

javascript動態創建audio標簽

在頁面中添加audio元素的方法主要是兩種,一種是在html中加入audio代碼,可以加入一些屬性(autoplay,preload)等,這些在之前的文章已經說過了。另外一種是js動態加載進來的。代碼如下:

var audio=document.creatElement(“audio”);
audio.src=”audio/source.ogg”;//路徑
audio.play();

或者更簡單一些
audio=new Audio(“audio/source.ogg”);//路徑
audio.play();

另外audio的屬性,preload有三種不同的載入方式,我們可以通過preload=”auto”來實現音頻的自動加載,但是我們無法通過直觀的方式了解音頻加載的進度,以及是否准備播放。這里提供了一個“canplaythrough”事件來監聽音頻是否已經加載完成。代碼示例如下:

<!DOCTYPE html >
<html lang="en">
<head>
<title>Preload Ready</title>
<script type="text/javascript">
        var audio = document.createElement("audio");
        audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
        audio.addEventListener("canplaythrough", function () {
            alert('音頻文件已經准備好,隨時待命');
        }, false);
    </script>
</head>
<body>
</body>
</html>

運行代碼復制代碼另存代碼(提示:可以編輯后運行)

第一次運行時間會長一些,第二次運行由於文件已經緩存到本地,所以會直接彈出提示框。

javascript控制audio的播放,暫停,停止

js如何控制audio標簽的播放比較簡單,在上面好多案例中已經提到了。主要是audio.play();同樣暫停也比較簡單audio.pause();就能很輕易搞定,看到這里你估計以為想要停止的話,也會使用這種語義化的函數了,呵呵,其實不是這樣的audio.stop()並不能停止audio的播放。

如果你需要停止或者重新播放audio,必須設置它的currentTime,可見如下語句:

audio.currentTime = 0;

下面我給出一個完成的示例,包括了開始播放,暫停播放,停止播放

<!DOCTYPE html >
<html lang="en">
<head>
<title>Preload Ready</title>
<script type="text/javascript">
var audio = document.createElement("audio");
audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
audio.addEventListener("canplaythrough",
function() {
	alert('音頻文件已經准備好,隨時待命');
},
false);
function aPlay() {
	audio.play();
}
function aPause() {
	audio.pause();
}
function aStop() {
	audio.currentTime = 0;
	audio.pause();
}
function aSkip() {
	audio.currentTime = 50;
	audio.play();
 }
    </script>
</head>
<body>
<input type="button" onclick="aPlay();" value="播放音頻">
<input type="button" onclick="aPause();" value="暫停音頻">
<input type="button" onclick="aStop();" value="停止音頻">
<input type="button" onclick="aSkip();" value="跳到第50秒">
</body>
</html>

運行代碼復制代碼另存代碼(提示:可以編輯后運行)

注意:以上代碼中的停止加上了pause(),另外跳到50秒加上了play()。這里主要是因為一旦play開始運行無法停止的,所以需要設置currentTime后使得音頻暫停。另外跳轉到50秒后,加上play()的做法是如果音頻在沒有播放的情況下,跳轉到50秒時音頻不會自動播放;而如果音頻在播放中,那么跳到50秒的時候還是播放的,這里的play()可以忽略。當然具體情況可以自行定義。

 javascript控制audio的聲音大小:

控制聲音的大小比較簡單,大概同play,pause那一套一樣,主要是多了一個參數。

示例:audio.volume = 0;//表示靜音  audio.volume = 1; 表示聲音最大 ,聲音值可以取0-1之間

演示不寫了,可以自己修改上面代碼運行框中的內容。

javascript控制audio的快進,快退,以及顯示進度與時長

控制快進,快退的原理比較簡單,只不過是設置audio的currentTime,案例如下

比如:audio.currentTime += 10;//10秒快進

<!DOCTYPE html >
<html lang="en">
<head>
<title>Preload Ready</title>
<script type="text/javascript">
var audio = document.createElement("audio");
audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
audio.addEventListener("canplaythrough",
function() {
	alert('音頻文件已經准備好,隨時待命');
},
false);
function aPlay() {
	audio.play();
}
function go() {
	audio.currentTime += 10;
	audio.play();
}
function back() {
	audio.currentTime -= 10;
	audio.play();;
}
    </script>
</head>
<body>
<input type="button" onclick="aPlay();" value="播放音頻">
<input type="button" onclick="go();" value="快進10秒">
<input type="button" onclick="back();" value="快退10秒">
</body>
</html>

運行代碼復制代碼另存代碼(提示:可以編輯后運行)

關於顯示進度的方法也不是很復雜,不過如果你想實現js配合css做一個進度條的模擬也許復雜一點。如果你對js以及css比較熟悉的話,解決的思路有很多。甚至可以做出很多酷炫的效果。我在這里只是點一下如何調用出該音頻文件的時長以及播放到進度的時間。

調用出音頻的時長不難解決 “audio.duration;” 就是了

調用處該文件的播放進度,這里需要用到一個時間監聽。currentTime代表當前播放的時間,而且當currentTime改變的時候會觸發timeupdate事件。因此,我們監聽timeupdate,並且輸出currentTime即可完成進度的判斷。不多說,看示例代碼:

<!DOCTYPE html >
<html lang="en">
<head>
<title>Preload Ready</title>
<script type="text/javascript">
var audio = document.createElement("audio");
audio.src = "http://www.niumowang.org/wp-content/uploads/2012/03/beyond.ogg";
audio.addEventListener("canplaythrough",
function() {
	alert('音頻文件已經准備好,隨時待命');
},
false);
audio.addEventListener("timeupdate", showtime, true);
function showtime() {
	document.getElementById("ltime").innerHTML = audio.duration;
	document.getElementById("ctime").innerHTML = audio.currentTime;
}
function aPlay() {
	audio.play();
}
function go() {
	audio.currentTime += 10;
	audio.play();
}
function back() {
	audio.currentTime -= 10;
	audio.play();
}
</script>
</head>
<body>
 總時長:
<div id="ltime">
</div>
<br/>
當前播放:
<div id="ctime">
</div>
<br/>
<input type="button" onclick="aPlay();" value="播放音頻">
<input type="button" onclick="go();" value="快進10秒">
<input type="button" onclick="back();" value="快退10秒">
</body>
</html>

運行代碼復制代碼另存代碼(提示:可以編輯后運行)

OK,基本的操作已經說完了。

最后留下參考資料給大家:
http://msdn.microsoft.com/zh-CN/ie/hh377903
https://wiki.mozilla.org/Audio_Data_API
http://msdn.microsoft.com/en-us/library/gg589489(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/gg589528(v=vs.85).aspx

三、VideoJS+Audio標簽實現視頻與音頻同步播放

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Online Player</title>
<%@ include file="pages/common/include.jsp"%>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<link rel="stylesheet" type="text/css" href="${basePath }css/mobile.css"/>
<link rel="stylesheet" type="text/css" href="${basePath }css/index.css"/>
<link rel="stylesheet" type="text/css" href="${basePath }images/icons/iconfont.css"/>
<script type="text/javascript" src="${basePath }scripts/rem.js"></script>
<!--VideoJS的引用文件-->
<link href="${basePath }jslib/videoJS/video-js.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="${basePath }jslib/videoJS/video.js"></script>
<script>
videojs.options.flash.swf = "${basePath }jslib/videoJS/video-js.swf";
</script>
<script type="text/javascript">
var player;
//加載視頻
$(function() {
player = videojs('video');
var audio=new Audio(vt.basePath+"videos/${video.videoSubtitlePath}");//路徑

// 開始或恢復播放
player.on('play', function() {
audio.play();
console.log('開始/恢復播放');
});

// 暫停播放
player.on('pause', function() {
audio.pause();
console.log('暫停播放');
});

//調整音量
player.on('volumechange', function() {
audio.volume = player.volume();
console.log('調整音量');
});

//視頻跳轉
player.on('seeked', function() {
audio.currentTime = player.currentTime();
console.log('改變時長');
});

// 檢測播放時間
player.on('timeupdate', function () {
//播放結束
if (player.duration() != 0 && player.currentTime() == player.duration()) {
audio.currentTime = 0;
audio.pause();
console.log('播放結束');
}
var beginTime = 0;
var endTime = 0;
var currentTime = player.currentTime() * 1000;
$("#playerShow p").each(function(){
beginTime = $(this).attr("beginTime");
endTime = $(this).attr("endTime");
if(currentTime>beginTime && currentTime<endTime){
$(this).siblings("p").removeClass("fontStyle");
$(this).addClass("fontStyle");
var oHeight = $('#myCaptions').height();
var tmp = $(this).next().offset().top-$(this).parent().offset().top - oHeight*0.5;
tmp = tmp > 0 ? tmp * -1 : 0;
//$(this).animate($(this).parent()[0]).animate({marginTop: tmp + 'px'}, 500);
$(this).parent().animate({marginTop: tmp + 'px'}, 300);
}
});
});
});

//點擊字幕修改
function revise(obj){
//暫停播放
thePlayer.play(false);
//彈出點擊字幕及輸入框
$('.shak').slideDown(500);
$('.revise .reviseMain') .addClass("animationActive")
//點擊字幕時獲得每段字幕的開始時間的毫秒值
var beginTime = $(obj).attr("beginTime")/1000;
$("#beginTimeForSeek").val(beginTime);
$("#subtitleId").val($(obj).attr("id"));
$("#oneSrtBody").html($(obj).attr("oneSrtBody"));
var otherSrtBody = $(obj).attr("otherSrtBody")
if(otherSrtBody){
$("#otherSrtBody").html(otherSrtBody);
}
}

//點擊輸入后確認發送
function saveRevise(){
var reviseContent = $("#reviseContent").val();
if($.string.isNullOrEmpty(reviseContent)){
alertWarn("請輸入修正內容!");
return;
}
var data = getFormData("saveRevise");
$.ajax({
type: "POST",
url: vt.basePath+"saveRevise",
data: data,
success:function (result) {
if (result = "1") {
alertInfo("修訂已保存成功!", hideRevise);
} else {
alertWarn("修訂保存失敗!");
}
}
});
}

//隱藏輸入框
function hideRevise(){
var beginTime = $("#beginTimeForSeek").val();
thePlayer.seek(beginTime);
$('.shak').hide();
$('.revise .reviseMain') .removeClass("animationActive");
$("#reviseContent").val("");
layer.closeAll("dialog");
}

/**
*顯示修正記錄
*/
function proofRecord(videoId){
var layerObject = layer.load('加載中');
$.ajax({
type: "POST",
url: vt.basePath+"getRevisedSubtitle",
data: {"videoId":videoId},
success:function (data) {
fillFormByTpl(data, "reviseRecordTpl", "reviseRecord");
layer.close(layerObject);
}
});
}
</script>

<script type="text/html" id="reviseRecordTpl">
{{#
var len = d.length;
for(var i=0; i<len; i++){
}}
<li>
<div class="theLiLfet">{{d[i].beginTimeStr.substring(0, 8)}}</div>
<div class="theLiRight">
<div class="translateAll">
<p class="translateForm">{{d[i].oneSrtBody}}</p>
{{# if(!$.string.isNullOrEmpty(d[i].otherSrtBody)){ }}
<p class="translateTo">{{d[i].otherSrtBody}}</p>
{{# } }}
</div>
{{#
var subtitleReviseList = d[i].subtitleReviseList;
var len1 = subtitleReviseList.length;
for(var j=0; j<len1; j++){
var srcBody = subtitleReviseList[j].srtBody;
}}
<div class="translate">{{srcBody}}</div>
{{# } }}
</div>
<div style="clear:both;"></div>
</li>
{{# } }}
</script>
</head>
<body ondblclick="return false;">
<header>
<a href="javascript:history.go(-1)" class="iconfont icon-fanhui"></a>
<span>電影字幕翻譯較對</span>
</header>
<section>
<div id="myElement">
<video id="video" class="video-js vjs-default-skin vjs-big-play-centered"
controls preload="auto" width="100%" height="250px"
poster="${basePath}videos/${video.videoFirstThumbPath}" data-setup='{"example_option":true}'>
<source src="http://7xl9b8.dl1.z0.glb.clouddn.com/b2d53773-614f-4e75-af76-3fd19eb26d10" type='video/mp4' />
</div>
<div id="myCaptions">
<div id="playerShow" class="srt">
<c:forEach items="${subtitleList}" var="subtitle">
<p class="p" id="${subtitle.id }"
onclick = "revise(this);"
beginTime="${subtitle.beginTime }"
endTime="${subtitle.endTime }"
beginTimeStr="${subtitle.beginTimeStr }"
oneSrtBody="${subtitle.oneSrtBody }"
otherSrtBody="${subtitle.otherSrtBody }">${subtitle.oneSrtBody }<br/>${subtitle.otherSrtBody }</p>
</c:forEach>
</div>
</div>
</section>
<footer>
<a class="proofBtn" onclick="proofRecord('${video.id }');">校對記錄</a>
</footer>

<div class="takeNotes">
<div class="close iconfont icon-shanchu"></div>
<ul>
<div id="reviseRecord"></div>
</ul>
</div>


<div class="shak">
<div class="close1 iconfont icon-shanchu"></div>
<div class="revise">
<div class="reviseTop">
<p id="oneSrtBody"></p>
<p id="otherSrtBody"></p>
</div>
<div class="reviseMain ">
<div class="reviseMainLeft">
<form id="saveRevise">
<input type="hidden" name="userId" value="${opUser.id }"/>
<input type="hidden" name="subtitleId" id="subtitleId"/>
<input type="hidden" name="videoId" value="${video.id }"/>
<input type="hidden" id="beginTimeForSeek"/>
<textarea name="srtBody" id="reviseContent"></textarea>
</form>
</div>
<div class="reviseMainRight iconfont icon-qiepian13" onclick="saveRevise()"></div>
<div style="clear: both;"></div>
</div>
</div>
</div>

<script>
$(function(){
//點擊 校對記錄
$('.proofBtn').on('click',function(){
thePlayer.play(false);
$('.takeNotes').slideDown(500);
})
//點擊關閉修改記錄
$('.takeNotes .close').on('click',function(){
thePlayer.play(true);
$('.takeNotes').slideUp(500);
})

//點擊關閉修改記錄1
$('.shak .close1').on('click',function(){
$('.shak').slideUp(500);
var beginTime = $("#beginTimeForSeek").val();
thePlayer.seek(beginTime);
})
})

//暫停狀態下執行
function stopanything(){
//播放狀態執行
function biginanything(){
var MyMar=setInterval(Marquee,speed);
}
}
//暫停狀態下執行
function stopanything(){

}
(function bottonm(){
if($(document).height()<$(window).height()){
$('.bottom_fix').css({'position':'fixed','bottom':'0px'});
$(document).height($(window).height()+'px');
}
})();
</script>
</body>
</html>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM