【问题标题】:Could not append segments by Media Source API, get "InvalidStateError : An attempt was made to use an object that is not, or is no longer, usable无法通过媒体源 API 附加片段,获取“InvalidStateError:尝试使用不可用或不再可用的对象
【发布时间】:2013-12-01 06:24:12
【问题描述】:

我使用以下示例程序附加媒体文件,但在第一次遇到代码“mediaSource.sourceBuffers”时出现“未捕获的 InvalidStateError:尝试使用不可用或不再可用的对象”错误[0].appendBuffer(mediaSegment);"。我正在使用 Chrome 31.0.1650.57。谁能建议我解决这个问题?

https://github.com/jbochi/media-source-playground/blob/master/test.html

我已经对附加文件进行了以下修改。

var buffer_len = 0;

function HaveMoreMediaSegments(){
    //return false; //return buffers.length > 0;
    return buffers.length > buffer_len;
}

// var GetNextMediaSegment = GetInitializationSegment;

function GetNextMediaSegment(){
    var buffer = buffers[buffer_len];
    buffers = buffers.slice(1);
    buffer_len = buffer_len + 1;
    return buffer;
}

又变了

mediaSource.sourceBuffers[0].append(mediaSegment);

mediaSource.sourceBuffers[0].appendBuffer(mediaSegment);

还有

sourceBuffer.append(initSegment);

sourceBuffer.appendBuffer(initSegment);

因为 append 方法在我的环境中不起作用。

我在 window.setTimeout() 事件中使用 sourceopen 而不是 webkitsourceopen。

mediaSource.addEventListener('sourceopen', onSourceOpen.bind(this, video));

【问题讨论】:

    标签: javascript html5-video media-source


    【解决方案1】:

    问题在于,在您追加数据后,SourceBuffer 实例在其工作时会暂时无法使用。在此期间,SourceBufferupdating 属性将设置为true,因此很容易检查。

    但处理此问题的最简单方法可能是监听updateend 事件,然后将所有缓冲区排队并仅在SourceBuffer 告诉您已准备好接收新缓冲区时才附加它们。像这样:

    // store the buffers until you're ready for them
    var queue = [];
    
    // whatever normally would have called appendBuffer(buffer) can 
    // now just call queue.push(buffer) instead
    
    sourceBuffer.addEventListener('updateend', function() {
      if ( queue.length ) {
        sourceBuffer.appendBuffer(queue.shift());
      }
    }, false);
    

    请记住,为了触发第一个事件,您需要手动附加第一个缓冲区,而不是推送到 queue。之后,只需将所有内容转储到数组中即可。

    【讨论】:

    • 如果 updateend 触发并且队列中没有任何内容,然后您将某些内容添加到队列中,那么它将永远不会添加到源缓冲区。
    • 当然。所以,queue.push = function( buffer ) { if ( !sourceBuffer.updating ) { sourceBuffer.appendBuffer( buffer ) } else { Array.prototype.push.call( this, buffer ) } }
    【解决方案2】:

    你找到答案了吗?同样的问题:(

    我有一个临时解决方案,它为每个缓冲区追加设置 setTimeout,因为您必须等待前一个缓冲区完成更新(sourceBuffer.updating == false)。代码可能如下所示:

    var i = 0;
    stream.on('data', function (buffer) {
        setTimeout(function(){
            sourceBuffer.appendBuffer(buffer);
        }, (i++) * 200);
    });
    

    【讨论】:

      猜你喜欢
      • 2016-04-30
      • 2014-05-21
      • 2019-03-05
      • 2014-05-19
      • 2013-10-08
      • 2013-09-24
      • 2013-12-08
      • 2022-08-18
      • 2013-06-17
      相关资源
      最近更新 更多