You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Media Source Extension切换新视频分片无响应问题求助

问题根因

你的代码在切换新视频分片时存在4个核心错误,导致播放失效:

  • 仅调用sourceBuffer.abort()没有清空已缓冲的旧数据,旧分片内容仍留在SourceBuffer缓存中,新分片的时间戳与旧缓存冲突无法正常播放
  • 每次调用appendFirstSegment都会重复绑定updateend事件,导致appendNextSegment被多次触发,缓存逻辑完全混乱
  • 切换视频时没有重置Transmuxer的状态,旧视频的转封装上下文残留,处理新分片时会生成错误的MP4片段
  • 没有重置MediaSource的时长、播放头位置,播放逻辑仍基于旧视频的时间轴运行

正确切换流程与代码修改

切换新视频分片需要按以下流程修改代码:

  1. 暂停视频,先移除SourceBuffer上已绑定的updateend事件,避免旧事件异常触发
  2. 调用sourceBuffer.remove()清空所有已缓冲的旧数据,等待remove操作完成后再执行后续逻辑
  3. 重置Transmuxer实例,清空旧的转封装状态
  4. 重置segments数组为新视频的分片列表,将播放头复位到0
  5. 重新调用分片加载逻辑

修改后的核心代码如下:

// 新增重置播放状态的通用函数,切换视频时调用
function resetPlayState(newSegments) {
  // 暂停视频
  video.pause();
  // 移除旧的updateend事件监听
  if (sourceBuffer) {
    sourceBuffer.removeEventListener('updateend', appendNextSegment);
    // 清空所有缓冲内容
    if (!sourceBuffer.updating) {
      sourceBuffer.remove(0, mediaSource.duration || Infinity);
    }
    // 等待清空操作完成
    const onRemoveDone = () => {
      sourceBuffer.removeEventListener('updateend', onRemoveDone);
      // 重置转码器
      transmuxer = new muxjs.mp4.Transmuxer();
      // 重置分片列表
      segments = newSegments;
      // 播放头归0
      video.currentTime = 0;
      appendFirstSegment();
      video.play();
    };
    sourceBuffer.addEventListener('updateend', onRemoveDone);
  }
}

// 修改play1函数,切换video2时调用这个函数传新分片列表即可
function play1() {
  const newSegments = [
    "segment_0.ts",
    "segment_1.ts",
    "segment_2.ts",
    "segment_3.ts",
    "segment_4.ts",
    "segment_5.ts",
    "segment_6.ts",
    "segment_7.ts",
    "segment_8.ts",
    "segment_9.ts"
  ];
  resetPlayState(newSegments);
}

// 修改appendFirstSegment,避免重复绑定事件
function appendFirstSegment(){
  if (segments.length == 0){
    return;
  }
  console.log('appendFirstSegment')
  if(!sourceBuffer){
    sourceBuffer = mediaSource.addSourceBuffer(mime);
    sourceBuffer.mode = 'sequence';
  }
  // 先移除再绑定,避免重复绑定
  sourceBuffer.removeEventListener('updateend', appendNextSegment);
  sourceBuffer.addEventListener('updateend', appendNextSegment,false);

  transmuxer.off('data');
  transmuxer.on('data', (segment) => {
    let data = new Uint8Array(segment.initSegment.byteLength + segment.data.byteLength);
    data.set(segment.initSegment, 0);
    data.set(segment.data, segment.initSegment.byteLength);
    console.log(muxjs.mp4.tools.inspect(data));
    sourceBuffer.appendBuffer(data);
  })

  fetch(segments.shift()).then((response)=>{
    return response.arrayBuffer();
  }).then((response)=>{
    transmuxer.push(new Uint8Array(response));
    transmuxer.flush();
  })
}

内容的提问来源于stack exchange,提问作者Vitalii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:39:03