MediaSource 不适用于支持的编解码器

问题描述

我尝试使用 MediaSource,但它仅适用于 MDN 示例中的视频文件。

尽管 MediaSource.isTypeSupported(mimeCodec) 为我测试的视频返回 true,但无论如何这些视频都没有显示。

这是我用过的视频列表和评论:

// Only with this video it works
var assetURL = 'https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4';
var mimeCodec = 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"'; // ./mp4info frag_bunny.mp4 | grep Codec

// It does not work
var assetURL = 'https://giant.gfycat.com/HandmadeMajesticIndianjackal.mp4';
var mimeCodec = 'video/mp4; codecs="avc1.64002A,mp4a.40.2"';

// The previous video,but encoded by Youtube. The same codecs,but reduced size. (it does not work too)
var assetURL = 'https://giant.gfycat.com/NaturalBraveHoneycreeper.mp4';
var mimeCodec = 'video/mp4; codecs="avc1.64002A,mp4a.40.2"';


// Another random not working examples:

// var assetURL = 'https://giant.gfycat.com/DigitalPolishedDassie.mp4';
// var mimeCodec = 'video/mp4; codecs="avc1.640033"';

// var assetURL = 'https://giant.gfycat.com/AncientAllAmericanavocet.mp4';
// var mimeCodec = 'video/mp4; codecs="avc1.42C01F"';

简短的例子。 它仅适用于第一个视频。

(查看下面的完整演示。)

let video = document.querySelector("video");
let mediaSource = new MediaSource();
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener("sourceopen",sourceOpen);

async function sourceOpen(_) {
  const mediaSource = this;
  const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);

  const resp = await fetch(assetURL);  
  const reader = resp.body.getReader();
  let updated = Promise.resolve();
  while (true) {    
    const {done,value} = await reader.read();
    await updated;
    if (done) {
      break;
    }
    sourceBuffer.appendBuffer(value);
    updated = sourceBufferUpdated(sourceBuffer);    
  }
  reader.releaseLock();
  mediaSource.endOfStream();
  await video.play();
};

function sourceBufferUpdated(sourceBuffer) {
  return new Promise(resolve => {
    if (sourceBuffer.updating) {        
      sourceBuffer.onupdate = resolve;
    } else {
      resolve();
    }
  });
}

完整的“工作”演示。单击“下一步”按钮。

const entries = [
    {
        url: 'https://nickdesaulniers.github.io/netfix/demo/frag_bunny.mp4',// ./mp4info frag_bunny.mp4 | grep Codec
        mimeCodec: 'video/mp4; codecs="avc1.42E01E,mp4a.40.2"'
    },{
        url: 'https://giant.gfycat.com/HandmadeMajesticIndianjackal.mp4',mimeCodec: 'video/mp4; codecs="avc1.64002A,{
        url: 'https://giant.gfycat.com/NaturalBraveHoneycreeper.mp4',{
        url: 'https://giant.gfycat.com/DigitalPolishedDassie.mp4',mimeCodec: 'video/mp4; codecs="avc1.640033"'
    },{
        url: 'https://giant.gfycat.com/AncientAllAmericanavocet.mp4',mimeCodec: 'video/mp4; codecs="avc1.42C01F"'
    }
];

let index = 0;
main(entries[index]);

function main({url,mimeCodec}) {
    document.querySelector("#url").textContent = url;
    document.querySelector("#mimeCodec").textContent = mimeCodec;

    if (!MediaSource.isTypeSupported(mimeCodec)) {
        document.querySelector("#mimeCodec").textContent += " (mimeCodec is not supported)";
        return;
    }

    const video = document.querySelector("video");
    const mediaSource = new MediaSource();
    video.src = URL.createObjectURL(mediaSource);
    mediaSource.addEventListener("sourceopen",sourceOpenHandler);

    async function sourceOpenHandler() {
        const mediaSource = this;
        const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);

        const resp = await fetch(url);
        const reader = resp.body.getReader();
        let updated = Promise.resolve();
        while (true) {
            const {done,value} = await reader.read();
            await updated;
            if (done) {
                break;
            }
            sourceBuffer.appendBuffer(value);
            updated = sourceBufferUpdated(sourceBuffer);
        }
        reader.releaseLock();
        mediaSource.endOfStream();

        await video.play();
    };
}

function sourceBufferUpdated(sourceBuffer) {
    return new Promise(resolve => {
        if (sourceBuffer.updating) {
            sourceBuffer.onupdate = resolve;
        } else {
            resolve();
        }
    });
}

document.querySelector("body").addEventListener("click",event => {
    if (event.target.id === "next") {
        ++index;
    } else if (event.target.id === "pre") {
        --index;
    } else {
        return;
    }

    const {length} = entries;
    const possition = (length + (index % length)) % length;
    main(entries[possition]);
});
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>MediaSourse Demo</title>
  </head>
  <body>  
    <button id="pre">pre</button>
    <button id="next">next</button>
    <div id="mimeCodec"></div>
    <div id="url"></div>

    <video controls="" src="" crossorigin="anonymous" muted></video>
    <script src="script.js"></script>

  </body>
</html>

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...