7

私は基本的なビデオ マーキーをコーディングしています。重要な要件の 1 つは、プレーヤーを全画面表示にしたままビデオを進める必要があるということです。

Video.js (4.1.0) を使用すると、別のビデオに切り替えるときにキャプションを変更できないことを除いて、すべてを正しく機能させることができました。

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

addTextTrack と addTextTracks を試してみましたが、どちらも console.log(videoObject.textTracks()) のようなものを使用してトラックが追加されたことを示していますが、プレーヤーにはそれらも「CC」ボタンも表示されません。

これが私のコードです。どんな助けでも大歓迎です:

;(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);
4

2 に答える 2

6

現在の VideoJS 実装 (4.4.2) は、プレーヤー自体の初期化時にあらゆる種類のテキスト トラック (サブタイトル、キャプション、チャプター) をロードするため、<video> タグ間で定義されたもののみを正しく取得します。

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

考えられる回避策の 1 つは、完全な videojs プレーヤーを破棄し、<video>タグ間のコンテンツを更新した後、ビデオ ソースの変更時にプレーヤーを再作成することです。したがって、この方法では、videojs プレーヤーを介してソースを更新するのではなく、必要な DOM 要素を動的に追加し、それらに新しいプレーヤーを初期化することにより、ソースを更新します。おそらく、この解決策はいくつかの UI フラッシュを引き起こし、問題に対して最適ではありません。これは、videojsプレーヤーの破棄に関するリンクです

2 番目のオプションは、動的テキスト トラックの処理を既存のコードに追加することです。これは、どこを見ればよいかを知っていれば、思ったほど難しくはありません (チャプターだけで行いましたが、他のテキスト トラックでも同様である可能性があります)。以下のコードは、最新の公式ビルド 4.4.2 で動作します。テキスト トラック要素を削除するために jQuery を使用していることに注意してください。したがって、誰かがこれらの変更をそのまま適用する場合は、videojs の前に jQuery をロードする必要があります。

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

1: clearTextTracks 関数を Player に追加する

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: 新しい「textTracksChanged」イベント トリガーを既存の addTextTrack メソッドの最後に追加します。

vjs.Player.prototype.addTextTrack = function(kind, label, language, options) {
    ...
    this.trigger("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 に refresh メソッドを実装する

// 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();
};

申し訳ありませんが、今のところ、実際に機能する例にリンクすることはできません。上記のスニペットが、これに関心のある人にとっての出発点として十分であることを願っています.

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

于 2014-03-13T20:42:00.323 に答える
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 />';
于 2014-02-13T17:23:27.353 に答える