簡體   English   中英

從 MediaSource 播放時無法搜索視頻

[英]Can't seek video when playing from MediaSource

我可以通過使用 GET 請求和 Range 標頭請求數據塊來播放 mp4 視頻。

var FILE = 'Momokuri_Ep_09-10_SUB_ITA_dashinit.mp4';
var NUM_CHUNKS = 10;
var chunk_size = 256 * 1024; // 2Kb
var current_chunk = 0;
var file_size = 1;

window.MediaSource = window.MediaSource || window.WebKitMediaSource;
if (!!!window.MediaSource) {
  alert('MediaSource API is not available');
}

var mediaSource = new MediaSource();
var sourceBuffer;

video.src = window.URL.createObjectURL(mediaSource);

function callback(e) {
    sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.640029, mp4a.40.5"');

    console.log('mediaSource readyState: ' + this.readyState);

    var readChunk = function() {
        GET(FILE, current_chunk, function(uInt8Array) {
            sourceBuffer.appendBuffer(uInt8Array);
        });
    };

    sourceBuffer.addEventListener('update', function(e) {
        if (!sourceBuffer.updating) {
            if (current_chunk == Math.ceil(file_size/chunk_size)-1) {
                if ( mediaSource.readyState!='ended' )
                    mediaSource.endOfStream();
            } else {
                current_chunk++;
                readChunk();
                if (video.paused) {
                    video.play();
                }
            }
        }
    });
    readChunk();
}

mediaSource.addEventListener('sourceopen', callback, false);
mediaSource.addEventListener('webkitsourceopen', callback, false);

mediaSource.addEventListener('webkitsourceended', function(e) {
  console.log('mediaSource readyState: ' + this.readyState);
}, false);

function GET(url, chunk_index, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.setRequestHeader('Range', 'bytes='+(chunk_index*chunk_size)+'-'+(++chunk_index*chunk_size-1));
    xhr.responseType = 'arraybuffer';
    xhr.send();

    xhr.onload = function(e) {
        if (xhr.status != 200 && xhr.status != 206) {
            alert("Unexpected status code " + xhr.status + " for " + url);
            return false;
        }

        file_size = parseInt(this.getResponseHeader('content-range').split("/").pop());
        callback(new Uint8Array(xhr.response));
    };
}

但是我找不到視頻。 所以任何人都可以告訴我如何解決這些問題:

  1. 當我尋找視頻時,我可以獲得 video.currentTime(比如說 2.5),如何將其轉換為字節范圍請求(如何獲得字節偏移量)
  2. 當我獲得正確的偏移量並從 Range GET 請求加載正確的數據時,我如何以正確的偏移量附加到 sourceBuffer

謝謝

我自己一直在尋找解決方案,我想我找到了。

看看這個例子

每當從視頻元素發出seeking事件時,表明用戶已請求搜索,使用sourceBuffer.abort();關閉舊的源sourceBuffer.abort(); .

然后 mediasource 發出一個新的sourceopen事件,它允許您以與第一次相同的方式創建新的源緩沖區,但這次不是從文件開頭附加數據,而是從與videoElem.currentTime對應的偏移量附加數據videoElem.currentTime

如何將時間偏移量轉換為字節偏移量似乎由您決定,因為這取決於您正在播放的媒體格式。

在恆定比特率文件中,您可能可以通過將文件長度(以字節為單位)除以視頻長度(以秒為單位)(並增加一點安全余量)而逃脫。 對於其他任何事情,您可能需要解析文件並獲取關鍵幀的時間戳和字節偏移量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM