javascript - 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, mp4a.40.2"'
}, {
url: 'https://giant.gfycat.com/NaturalBraveHoneycreeper.mp4',
mimeCodec: 'video/mp4; codecs="avc1.64002A, mp4a.40.2"'
}, {
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>
解决方案
推荐阅读
- html - 是否可以通过直接包含 html 文件中的 html 来创建邮件?
- python - 响应回调访问正文
- c++ - 发送到不存在的目标时提升 asio UDP 套接字阻塞
- openapi - 在 Swagger OpenAPI 注解中定义数组
- java - 添加 'ndk { abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64' }' 后,Android 应用程序不兼容 64 位
- python - 通过动态键名对字典进行分组并在 Python 中聚合嵌套字典的一些键
- docker - docker新手,没有看到现场进行的本地更改
- php - 将页面从一个域重定向到另一个域(两个域都属于一个网站)
- magento - 变量 @theme__color__primary-alt 未定义
- .net - 当我得到一件物品时,$Expand 不起作用