2013-08-07 61 views
6

Tôi đang mã hóa vùng chọn video cơ bản và một trong những yêu cầu chính là video cần có khả năng thăng tiến trong khi vẫn giữ nguyên trình phát toàn màn hình.Không thể tự động thay đổi phụ đề '' trong Video.js

Sử dụng Video.js (4.1.0) Tôi có thể làm mọi thứ hoạt động chính xác ngoại trừ việc tôi không thể thay đổi phụ đề khi chuyển sang video khác.

Hoặc chèn thẻ "theo dõi" khi trình phát HTML được tạo lần đầu hoặc thêm bản nhạc vào đối tượng 'tùy chọn' khi trình phát được khởi tạo là cách duy nhất tôi có thể khiến người chơi hiển thị nút "CC" và hiển thị chú thích. Tuy nhiên, tôi không thể khởi tạo lại trình phát trong khi ở chế độ toàn màn hình để thay đổi bản nhạc theo cách đó sẽ không hoạt động.

Tôi đã thử addTextTrack và addTextTracks và cả hai cho thấy các bản nhạc đã được thêm vào - sử dụng một cái gì đó như console.log (videoObject.textTracks()) - nhưng người chơi không bao giờ hiển thị chúng hoặc nút "CC".

Đây là mã của tôi, bất kỳ sự giúp đỡ được đánh giá rất cao:

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

Xin chào - bạn có nhận được bất cứ đâu với điều này không? Tôi gặp một vấn đề tương tự. Tôi muốn cung cấp cho nó một url VTT khi tôi thay đổi video src programtically – Phil

+0

Không, chỉ cần đăng ngày hôm qua và tôi hy vọng rằng ai đó am hiểu sẽ kêu vang. Có khá nhiều câu hỏi tương tự trong các diễn đàn khác nhau cho phiên bản cũ hơn của Video.js, nhưng cho đến nay tôi đã không tìm thấy bất kỳ câu trả lời nào có hiệu quả. – fodder

Trả lời

1

Làm điều tương tự (hay đúng hơn là không làm điều tương tự) ... thực sự cần phải tìm ra cách để tự động thay đổi/thêm phụ đề gốc.

này hoạt động để có được nó chơi thông qua HTML5 cơ bản, nhưng nó không hiển thị các nút 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

Việc thực hiện VideoJS hiện tại (4.4.2) tải tất cả các loại dấu vết văn bản (phụ đề, chú thích, chương) vào thời gian khởi tạo của chính trình phát, do đó, nó chỉ lấy đúng các thẻ được xác định giữa các thẻ <video>.

EDIT: Tôi có nghĩa là nó tải chúng khi gọi addTextTrack, nhưng giao diện người chơi sẽ không bao giờ cập nhật sau thời gian khởi tạo và sẽ luôn hiển thị các bản nhạc văn bản khởi tạo.

Một giải pháp có thể xảy ra là nếu bạn hủy trình phát video hoàn chỉnh và tạo lại video đó trên thay đổi nguồn video sau khi bạn đã làm mới nội dung giữa các thẻ <video>. Vì vậy, theo cách này bạn không cập nhật nguồn thông qua trình phát videojs, nhưng thông qua việc thêm động các phần tử DOM được yêu cầu và khởi tạo trình phát mới trên chúng. Có lẽ giải pháp này sẽ gây ra một số nhấp nháy giao diện người dùng và hoàn toàn không tối ưu cho vấn đề. Here is a link about destroying the videojs player

Tùy chọn thứ hai là thêm xử lý theo dõi văn bản động vào mã hiện có, không khó bằng âm thanh nếu người ta biết nơi cần tìm (tôi đã làm nó chỉ cho các chương, nhưng có thể tương tự với các đoạn văn bản khác cũng). Mã bên dưới hoạt động với phiên bản chính thức mới nhất 4.4.2. Lưu ý rằng tôi đang sử dụng jQuery để xóa các phần tử theo dõi văn bản, vì vậy nếu bất kỳ ai áp dụng các thay đổi này, jQuery cần được tải trước các videoj.

Chỉnh sửa video.dev.file js như sau:

1: Thêm một chức năng 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: Thêm mới 'textTracksChanged' kích hoạt sự kiện đến hết phương pháp addTextTrack hiện

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

3: Xử lý sự kiện mới trong hàm tạo hàm 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: Thực hiện phương pháp làm mới trên 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(); 
}; 

Xin lỗi, nhưng bây giờ tôi không thể liên kết đến một ví dụ làm việc thực tế, tôi hy vọng các đoạn trên sẽ đủ như là một điểm khởi đầu cho bất cứ ai Intrested trong việc này.

Bạn có thể sử dụng mã này khi bạn cập nhật nguồn thành video mới. Chỉ cần gọi phương thức clearTextTracks và thêm các bản nhạc văn bản mới bằng phương thức addTextTrack và các menu bây giờ sẽ tự cập nhật.

+0

Xin lỗi, Zoltán, tôi vừa thấy phản hồi này (không nhận được email vì lý do nào đó.) Tôi chắc chắn sẽ thử điều này để xem liệu nó có hoạt động hay không. Vì tôi không nhận được bất kỳ phản hồi nào vào năm ngoái, tôi phải đi lộ trình xử lý hoàn toàn đối tượng videoj, giống như bạn đã nói, chắc chắn không tối ưu, nhưng ít nhất nó hoạt động. – fodder

+0

Cảm ơn vì điều này. Một thay đổi cho những người không muốn sử dụng jQuery, hãy chuyển đổi điều này: $ (theo dõi [i] .el()). Remove(); Đối với điều này: bản nhạc [i] .disable(); –

+0

Tôi cũng nhận thấy điều này không hoạt động chính xác với tôi: if (this.items && this.items.length <= this.kind_ == "chapter"? 0: 1) vì vậy tôi chỉ thay đổi nó thành if (this.items && this.items.length <= 1) –