2013-08-24 38 views
18

Tôi đang thiết kế một trình phát video tùy chỉnh HTML5. Do đó, nó sẽ có thanh trượt tùy chỉnh của riêng nó để bắt chước tiến trình video, vì vậy tôi cần phải hiểu toàn bộ bộ đệm đệm của video HTML5.Các tính năng thuộc tính video được đệm trong HTML5

Tôi đã xem qua bài viết này: Video Buffering. Nó nói rằng đối tượng đệm bao gồm một số phạm vi thời gian theo thứ tự tuyến tính của thời gian bắt đầu. Nhưng tôi không thể tìm thấy những điều sau đây:

  1. Giả sử video bắt đầu. Nó tiếp tục tối đa 1:45 một mình (thỉnh thoảng trì hoãn có lẽ, chờ đợi thêm dữ liệu), sau đó tôi đột nhiên nhảy tới 32:45. Bây giờ sau một thời gian, nếu tôi nhảy trở lại 1:27 (trong phạm vi thời gian ban đầu được nạp và chơi qua, trước khi tôi thực hiện bước nhảy), nó sẽ bắt đầu chơi ngay lập tức vì nó đã được nạp trước đó chưa? Hay là vì tôi đã nhảy, phần đó bị mất và sẽ phải lấy lại lần nữa? Dù bằng cách nào, hành vi có phù hợp với tất cả các tình huống như vậy không?

  2. Giả sử tôi thực hiện 5 hoặc 6 lần nhảy như vậy, mỗi lần đợi một vài giây để một số dữ liệu tải sau khi nhảy. Điều đó có nghĩa là đối tượng buffered sẽ có tất cả các phạm vi thời gian đó được lưu trữ không? Hoặc có thể một số bị lạc? Nó có phải là một loại đống điều, nơi mà các phạm vi trước đó sẽ nhận được popped off như nhiều phạm vi được tải do nhảy thêm?

  3. Sẽ kiểm tra xem đối tượng buffered có một phạm vi thời gian bắt đầu từ 0 (quên phát trực tiếp) và kết thúc ở độ dài thời lượng video đảm bảo rằng toàn bộ tài nguyên video đã được tải hoàn toàn chưa? Nếu không, có cách nào để biết rằng toàn bộ video đã được tải xuống và phần nào có thể tìm kiếm được hay không, từ đó video có thể phát liên tục tối đa mà không bị trễ một chút?

Thông số W3C không rõ ràng về điều này và tôi cũng không thể tìm thấy tài nguyên video từ xa lớn (hơn một giờ) để kiểm tra.

Trả lời

27

Cách đệm video là phụ thuộc vào việc triển khai trình duyệt và có thể khác nhau tùy theo trình duyệt.

Các trình duyệt khác nhau có thể sử dụng các yếu tố khác nhau để xác định giữ hoặc loại bỏ một phần của bộ đệm. Phân đoạn cũ, không gian đĩa, bộ nhớ và hiệu suất là những yếu tố tiêu biểu.

Cách duy nhất để thực sự biết là "xem" những gì trình duyệt có hoặc đang tải.

Đối với điều này, tôi đã tạo bộ đệm cho biết phần nào nằm trong bộ đệm.Người xem sẽ hiển thị hiện tại và tất cả các bộ phận của toàn bộ đệm:

ONLINE BUFFER VIEWER

Ví dụ - trong Chrome tôi đã chơi một vài giây sau đó tôi bỏ qua xuống còn khoảng 30 giây và bạn có thể thấy rằng nó bắt đầu tải một phần khác bắt đầu từ vị trí đó.

(Bộ đệm cũng dường như bị ràng buộc với khung hình chính để có thể giải mã n-khung trong bộ đệm đó. Điều này có nghĩa bộ đệm có thể bắt đầu tải dữ liệu một chút trước vị trí thực tế).

Example

tôi cung cấp một đoạn video giới thiệu về 1 phút dài - tuy nhiên điều này là không đủ thời gian để làm thử nghiệm thích hợp. Miễn phí để cung cấp các liên kết video có chứa video dài hơn (hoặc xin vui lòng chia sẻ nếu bạn muốn tôi cập nhật bản demo với điều này).

Chức năng chính sẽ lặp qua đối tượng buffered trên phần tử video. Nó sẽ hiển thị tất cả các phần có trong canvas ngay bên dưới video hiển thị màu đỏ.

Bạn có thể nhấp (bit không kéo) trên trình xem này để di chuyển video đến các vị trí khác nhau.

/// buffer viewer loop (updates about every 2nd frame) 
function loop() { 

    var b = vid.buffered, /// get buffer object 
     i = b.length,  /// counter for loop 
     w = canvas.width, /// cache canvas width and height 
     h = canvas.height, 
     vl = vid.duration, /// total video duration in seconds 
     x1, x2;   /// buffer segment mark positions 

    /// clear canvas with black 
    ctx.fillStyle = '#000'; 
    ctx.fillRect(0, 0, w, h); 

    /// red color for loaded buffer(s) 
    ctx.fillStyle = '#d00'; 

    /// iterate through buffers 
    while (i--) { 
     x1 = b.start(i)/vl * w; 
     x2 = b.end(i)/vl * w; 
     ctx.fillRect(x1, 0, x2 - x1, h); 
    } 

    /// draw info 
    ctx.fillStyle = '#fff'; 

    ctx.textBaseline = 'top'; 
    ctx.textAlign = 'left'; 
    ctx.fillText(vid.currentTime.toFixed(1), 4, 4); 

    ctx.textAlign = 'right'; 
    ctx.fillText(vl.toFixed(1), w - 4, 4); 

    /// draw cursor for position 
    x1 = vid.currentTime/vl * w; 

    ctx.beginPath(); 
    ctx.arc(x1, h * 0.5, 7, 0, 2 * Math.PI); 
    ctx.fill(); 

    setTimeout(loop, 29); 
} 
+0

Khi bạn tạm dừng video và chạy buffered.end (index), nó trả về 1 và ngừng hoạt động. Đó có phải là một hành vi phổ biến? không thể tìm thấy các vấn đề liên quan. –

7

Theo

thuộc tính buffered chứa thông tin về tất cả các dãy thời gian hiện đệm. Theo hiểu biết của tôi, nếu phần đệm bị mất, nó sẽ bị loại bỏ khỏi đối tượng (trong trường hợp xảy ra).

Esepcially liên kết cuối cùng có vẻ rất hữu ích để hiểu vấn đề (vì nó cung cấp mẫu mã) nhưng hãy nhớ rằng đây là tài liệu mozilla và hỗ trợ có thể khác nhau trong các trình duyệt khác.

Để trả lời câu hỏi của bạn

Nói video bắt đầu. Nó tiếp tục tối đa 1:45 một mình (thỉnh thoảng trì hoãn có lẽ, chờ đợi thêm dữ liệu), sau đó tôi đột nhiên nhảy tới 32:45. Bây giờ sau một thời gian, nếu tôi nhảy trở lại 1:27 (trong phạm vi thời gian ban đầu được nạp và chơi qua, trước khi tôi thực hiện bước nhảy), nó sẽ bắt đầu chơi ngay lập tức vì nó đã được nạp trước đó chưa?

nên phát ngay lập tức khi nhảy trở lại trừ khi bộ đệm của phần đó được tải xuống. Tôi nghĩ rằng nó rất hợp lý để giả định rằng vùng đệm hoặc vùng đệm được giải nén tại một số điểm nếu tổng dung lượng đệm vượt quá một khối lượng nhất định.

Giả sử tôi thực hiện 5 hoặc 6 lần nhảy như vậy, mỗi lần đợi vài giây để một số dữ liệu tải sau khi nhảy. Điều đó có nghĩa là đối tượng đệm sẽ có tất cả các phạm vi thời gian đó được lưu trữ không?

Có, tất cả các dải đệm phải có thể đọc được thông qua thuộc tính.

Sẽ kiểm tra xem đối tượng đệm có một phạm vi thời gian bắt đầu từ 0 (quên phát trực tiếp) và kết thúc ở độ dài thời lượng video đảm bảo rằng toàn bộ tài nguyên video đã được tải hoàn toàn chưa?

Vâng, đây là ví dụ về mã trong liên kết cuối cùng. Rõ ràng đây là một phương pháp áp dụng để xác định xem toàn bộ video đã được tải chưa.

if (buf.start(0) == 0 && buf.end(0) == v.duration) 
+0

Vấn đề là tôi đã cố gắng thử nghiệm với bộ đệm. Tôi để luồng video trong 2-3 phút, sau đó nhảy lên 10 lẻ, sau đó cho phép luồng đó trong 2 phút, sau đó đến 20 và giống nhau. Sau đó, tôi dự kiến ​​sẽ có 3 phạm vi trong 'đệm ', trong khi tôi tìm thấy một, một trong những hiện đang đệm. – SexyBeast

+1

@Cupidvogel Vâng, hoặc bạn đã dành đủ thời gian ở mỗi vị trí mà nó có đủ thời gian để tải xuống một phần lớn liên tục của video hoặc việc dỡ hàng tôi đang nói đến thực sự đang diễn ra ở đó. Dù bằng cách nào, thuộc tính 'buffered' sẽ phản ánh những gì đang xảy ra. –

+0

Vâng, tôi cũng nghĩ như vậy. Nhưng tôi chỉ tìm kiếm 3 phần, có vẻ như một số quá nhỏ để bắt đầu xóa bộ nhớ cache.Và không, bộ đệm đơn kết quả không kết hợp bộ đệm trước đó và bộ đệm hiện tại (chúng được phân tách bằng khoảng thời gian 10 phút, với phần liên tục vẫn không được tải, vì vậy không thể kết hợp chúng), nó chỉ đề cập đến đến điểm bắt đầu nơi tôi tìm kiếm và điểm kết thúc được cập nhật khi có thêm dữ liệu được tải. – SexyBeast

3
  1. Hầu hết các trình duyệt giúp tiết kiệm dữ liệu đệm trong bộ nhớ cache cho phiên đó. Bộ nhớ cache sẽ hết hạn sau khi người dùng rời khỏi trang đó. Tôi không nghĩ rằng người dùng sẽ phải tải trang mỗi lần anh tải video từ một điểm mà video đã được tải. Người dùng sẽ chỉ gặp sự cố này khi máy chủ xóa tất cả dữ liệu bộ nhớ cache. Thẻ video HTML5 sẽ hỗ trợ tính năng này và sẽ lưu video tối đa cho đến khi nó được tải.

  2. Điều này không có nghĩa là phiên bị mất, điều đó có nghĩa là đối tượng (nếu bạn đang sử dụng trình phát flash) đang tìm một số dữ liệu từ điểm cụ thể đó hoặc thẻ video html5 đang gặp một số sự cố lỗi kết nối INTERNET hoặc một số lỗi máy chủ khác.

  3. Các siêu dữ liệu được tự động nạp, cho đến khi bạn sử dụng này <audio preload="none"... này sẽ làm cho trình duyệt không tải bất cứ thứ gì từ máy chủ, bạn có thể sử dụng nó như:
    <audio preload="auto|metadata|none"... Nếu bạn sử dụng không có, không có gì được tải xuống trừ khi người dùng nhấp chuột nút phát và siêu dữ liệu sẽ tải xuống tên, thời gian và dữ liệu meta khác từ máy chủ, nhưng không phải tệp bằng cách nào đó, tự động sẽ bắt đầu tải xuống ngay khi trang tải.

Tôi sẽ luôn giới thiệu bạn đọc một số tài liệu của jQuery. Khi jQuery sẽ cho phép bạn thay đổi và cập nhật nội dung bằng cách sử dụng API ajax và cũng sẽ hữu ích. Hy vọng bạn thành công! Chúc mừng.

0

Mặc dù mô tả các câu trả lời được chấp nhận là tuyệt vời, tôi đã quyết định cập nhật mẫu mã của nó, vì nhiều lý do:

  • Tiến độ làm việc thực sự nên bị sa thải chỉ trên một sự kiện progress.
  • Tác vụ hiển thị tiến trình được trộn lẫn với một số tác vụ khác như vẽ dấu thời gian và vị trí đầu phát.
  • Mã đề cập đến một số phần tử DOM theo ID của chúng mà không cần sử dụng document.getElementById().
  • Tất cả các tên biến đều bị che khuất.
  • Tôi nghĩ rằng vòng lặp chuyển tiếp for() là thanh lịch hơn vòng lặp while() lạc hậu.

Lưu ý rằng tôi đã xóa đầu phát và dấu thời gian để giữ mã sạch, vì câu trả lời này tập trung hoàn toàn vào việc trực quan hóa bộ đệm video.

LINK TO ONLINE VIDEO BUFFER VISUALISER

Rewrite chức năng chấp nhận câu trả lời của loop():

function drawProgress(canvas, buffered, duration){ 
    // I've turned off anti-aliasing since we're just drawing rectangles. 
    var context = canvas.getContext('2d', { antialias: false }); 
    context.fillStyle = 'blue'; 

    var width = canvas.width; 
    var height = canvas.height; 
    if(!width || !height) throw "Canvas's width or height weren't set!"; 
    context.clearRect(0, 0, width, height); // clear canvas 

    for(var i = 0; i < buffered.length; i++){ 
     var leadingEdge = buffered.start(i)/duration * width; 
     var trailingEdge = buffered.end(i)/duration * width; 
     context.fillRect(leadingEdge, 0, trailingEdge - leadingEdge, height); 
    } 
} 
Các vấn đề liên quan