2013-08-07 18 views
6

私は基本的なビデオマーキーをコーディングしています。重要な要件の1つは、ビデオをフルスクリーンでプレーヤを維持しながら進める必要があるということです。Video.jsのキャプション 'トラック'を動的に変更できません

Video.js(4.1.0)を使用すると、別のビデオに切り替えるときにキャプションを変更できないという点を除いて、すべて正常に動作するようになりました。

プレーヤーのHTMLを最初に作成するときに「トラック」タグを挿入するか、プレーヤーが初期化されたときに「オプション」オブジェクトにトラックを追加することは、プレイヤーに「CC」ボタンを表示させる唯一の方法です。キャプションを表示するしかし、全画面表示中にプレイヤーを再初期化することはできません。そのようにトラックを変更すると動作しません。

私はaddTextTrackとaddTextTracksを試してみましたが、console.log(videoObject.textTracks())のようなものを使ってトラックが追加されたことを示していますが、プレイヤーには表示されません。ここで

が私のコードで、任意のヘルプは大歓迎です。

;(function(window,undefined) { 

    // VIDEOS OBJECT 
    var videos = [ 
     {"volume":"70","title":"TEST 1","url":"test1.mp4","type":"mp4"}, 
     {"volume":"80","title":"TEST 2","url":"test2.mp4","type":"mp4"}, 
     {"volume":"90","title":"TEST 3","url":"test3.mp4","type":"mp4"} 
    ]; 

    // CONSTANTS 
    var VIDEO_BOX_ID = "jbunow_marquee_video_box", NAV_TEXT_ID = "jbunow_marquee_nav_text", NAV_ARROWS_ID = "jbunow_marquee_nav_arrows", VIDEO_OBJ_ID = "jbunow_marquee_video", NAV_PREV_ID = "jbunow_nav_prev", NAV_NEXT_ID = "jbunow_nav_next"; 

    // GLOBAL VARIABLS 
    var videoObject; 
    var currentTrack = 0; 
    var videoObjectCreated = false; 
    var controlBarHideTimeout; 

    jQuery(document).ready(function(){ 
     // CREATE NAV ARROWS AND LISTENERS, THEN START MARQUEE 
     var navArrowsHtml = "<div id='" + NAV_PREV_ID + "' title='Play Previous Video'></div>"; 
     navArrowsHtml += "<div id='" + NAV_NEXT_ID + "' title='Play Next Video'></div>"; 
     jQuery('#' + NAV_ARROWS_ID).html(navArrowsHtml); 
     jQuery('#' + NAV_PREV_ID).on('click',function() { ChangeVideo(GetPrevVideo()); }); 
     jQuery('#' + NAV_NEXT_ID).on('click',function() { ChangeVideo(GetNextVideo()); }); 

     ChangeVideo(currentTrack); 
    }); 

    var ChangeVideo = function(newIndex) { 
     var videoBox = jQuery('#' + VIDEO_BOX_ID); 
     if (!videoObjectCreated) { 
      // LOAD PLAYER HTML 
      videoBox.html(GetPlayerHtml()); 

      // INITIALIZE VIDEO-JS 
      videojs(VIDEO_OBJ_ID, {}, function(){ 
       videoObject = this; 

       // LISTENERS 
       videoObject.on("ended", function() { ChangeVideo(GetNextVideo()); }); 
       videoObject.on("loadeddata", function() { videoObject.play(); }); 

       videoObjectCreated = true; 
       PlayVideo(newIndex); 
      }); 

     } else { PlayVideo(newIndex); } 
    } 

    var PlayVideo = function(newIndex) { 

     // TRY ADDING MULTIPLE TRACKS 
     videoObject.addTextTracks([{ kind: 'captions', label: 'English2', language: 'en', srclang: 'en', src: 'track2.vtt' }]); 

     // TRY ADDING HTML 
     //jQuery('#' + VIDEO_OBJ_ID + ' video').eq(0).append("<track kind='captions' src='track2.vtt' srclang='en' label='English' default />"); 

     // TRY ADDING SINGLE TRACK THEN SHOWING USING RETURNED ID 
     //var newTrack = videoObject.addTextTrack('captions', 'English2', 'en', { kind: 'captions', label: 'English2', language: 'en', srclang: 'en', src: 'track2.vtt' }); 
     //videoObject.showTextTrack(newTrack.id_, newTrack.kind_);   

     videoObject.volume(parseFloat(videos[newIndex]["volume"])/100); // SET START VOLUME 
     videoObject.src({ type: "video/" + videos[newIndex]["type"], src: videos[newIndex]["url"] }); // SET NEW SRC 
     videoObject.load(); 

     videoObject.ready(function() { 
      videoObject.play(); 

      clearTimeout(controlBarHideTimeout); 
      controlBarHideTimeout = setTimeout(function() { videoObject.controlBar.fadeOut(); }, 2000); 

      jQuery('#' + NAV_TEXT_ID).fadeOut(150, function() { 
       currentTrack = newIndex; 
       var navHtml = ""; 
       navHtml += "<h1>Now&nbsp;Playing</h1><h2>" + videos[newIndex]["title"] + "</h2>"; 
       if (videos.length > 1) { navHtml += "<h1>Up&nbsp;Next</h1><h2>" + videos[GetNextVideo()]["title"] + "</h2>"; } 
       jQuery('#' + NAV_TEXT_ID).html(navHtml).fadeIn(250); 
      }); 
     }); 
    } 

    var GetPlayerHtml = function() { 
     var playerHtml = "";   
     playerHtml += "<video id='" + VIDEO_OBJ_ID + "' class='video-js vjs-default-skin' controls='controls' preload='auto' width='560' height='315'>"; 
     playerHtml += "<source src='' type='video/mp4' />"; 
     //playerHtml += "<track kind='captions' src='track.vtt' srclang='en' label='English' default='default' />"; 
     playerHtml += "</video>"; 
     return playerHtml; 
    } 

    var GetNextVideo = function() { 
     if (currentTrack >= videos.length - 1) { return 0; } 
     else { return (currentTrack + 1); } 
    } 

    var GetPrevVideo = function() { 
     if (currentTrack <= 0) { return videos.length - 1; } 
     else { return (currentTrack - 1); } 
    } 

})(window); 
+0

こんにちは - これでどこにいらしましたか?私も同様の問題があります。私はそれをビデオsrcをプログラム的に変更するときにVTT urlを与えたいとします – Phil

+0

いいえ、ちょうどこれを昨日投稿しました。知識豊かな人がチャイムしてくれることを願っています。Video.jsの古いバージョンの様々なフォーラムでは、しかしこれまでのところ私は答えが見つからなかった。 – fodder

答えて

1

はまったく同じことをやって(というかまったく同じことをやっていない)...本当にダイナミックに変更する方法を把握する必要があり/キャプショントラックを追加します。

これは、基盤となるHTML5を経由して再生を取得する動作しますが、それはvideojsのCCボタンは表示されません。

document.getElementById("HtmlFiveMediaPlayer_html5_api").innerHTML = '<track label="English Captions" srclang="en" kind="captions" src="http://localhost/media/captiontest/demo_Brian/demo_h264_1.vtt" type="text/vtt" default />'; 
6

現在VideoJSの実装(4.4.2)は、テキストトラック(字幕のすべての種類をロードし、キャプション、チャプター)を取得するので、<video>タグの間に定義されているものだけを正確に取得します。

EDIT:addTextTrackを呼び出すときにロードすることを意味しましたが、プレーヤUIは初期化時間の後に決して更新されず、常に初期化時間のテキストトラックを表示します。

可能な回避策の1つは、完全なvideojsプレーヤーを破棄し、<video>タグの間でコンテンツを更新した後にビデオソースの変更でビデオを再作成する場合です。このようにして、videojsプレーヤー経由でソースを更新するのではなく、必要なDOM要素を動的に追加し、新しいプレーヤーを初期化します。おそらく、この解決策はいくつかのUIフラッシュを引き起こし、問題に対しては非常に最適ではありません。 Here is a link about destroying the videojs player

第2の選択肢は、動的なテキストトラックの処理を既存のコードに追加することです。これは、見た目がわかるほど難しくありません(私はチャプタでのみ行いましたが、他のテキストトラック同じように)。以下のコードは最新の公式ビルド4.4.2で動作します。 jQueryをテキストトラック要素を削除するために使用していることに注意してください。誰でもこれらの変更をそのまま適用する場合、jQueryをvideojsの前にロードする必要があります。

video.devを編集します。JSファイルは、次のように

1:プレーヤー

vjs.Player.prototype.clearTextTracks = function() { 
    var tracks = this.textTracks_ = this.textTracks_ || []; 
    for (var i = 0; i != tracks.length; ++i) 
     $(tracks[i].el()).remove(); 
    tracks.splice(0, tracks.length); 
    this.trigger("textTracksChanged"); 
}; 

2にclearTextTracks機能を追加します。既存のaddTextTrack方法

vjs.Player.prototype.addTextTrack = function(kind, label, language, options) { 
    ... 
    this.trigger("textTracksChanged"); 
} 

の最後に新しい 'textTracksChanged' イベントトリガを追加します。 3:TextTrackButtonコンストラクタ関数の新しいイベントを処理します。

vjs.TextTrackButton = vjs.MenuButton.extend({ 
    /** @constructor */ 
    init: function(player, options) { 
     vjs.MenuButton.call(this, player, options); 
     if (this.items.length <= 1) { 
      this.hide(); 
     } 
     player.on('textTracksChanged', vjs.bind(this, this.refresh)); 
    } 
}); 

4:申し訳ありませんが、今のところ、私は本当の実施例にリンクすることはできませんTextTrackButton

// removes and recreates the texttrack menu 
vjs.TextTrackButton.prototype.refresh = function() { 
    this.removeChild(this.menu); 
    this.menu = this.createMenu(); 
    this.addChild(this.menu); 
    if (this.items && this.items.length <= this.kind_ == "chapters" ? 0 : 1) { 
     this.hide(); 
    } else 
     this.show(); 
}; 

にリフレッシュ方法を実装し、私は、スニペットは、上記の本でintrestedて誰にも出発点として十分なことを願っています。

このコードは、ソースを新しいビデオに更新するときに使用できます。 clearTextTracksメソッドを呼び出して、addTextTrackメソッドで新しいテキストトラックを追加するだけで、メニューが更新されます。

+0

申し訳ありません、ゾルタン、私はちょうどこの反応を見ました(何らかの理由で電子メールを受け取っていませんでした)。私はそれがうまくいくかどうかを確かめるためにこれを試してみます。去年は何の反応もなかったので、あなたが言ったように、確かに最適ではないが少なくとも動作するvideojsオブジェクトを完全に廃棄するルート。 – fodder

+0

ありがとうございます。 jQueryを使用したくない人のための1つの変更は、これを切り替えてください: $(tracks [i] .el())。 この場合: tracks [i] .disable(); –

+0

私はこれが私のために正しく動作していないことに気づいた:if(this.items && this.items.length <= this.kind_ == "chapters"?0:1)だから私はちょうどif(this.items && this.items.length <= 1) –

関連する問題