URL.createObjectURL(mediaSource) - 播放来自 URL 的视频 - MOOV atom - Elastic Transcoder
URL.createObjectURL(mediaSource) - play back video from URL - MOOV atom - Elastic Transcoder
我正在尝试通过创建 blob URL.
来播放视频(目前托管在 S3 上,具有 public 访问权限)
我使用 Elastic Transcoder 对视频进行编码,因为它应该将 MOOV atom 设置到顶部(开始)。
我无法让代码工作,但也找到了一个工作示例:link here
这是我的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
mediaSource.endOfStream();
video.play();
//console.log(mediaSource.readyState); // ended
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
我做错了什么?我查看了工具 ie.e MP4Box 或 QT-FastStart,但它们似乎有点老套。我也愿意从 MP4 更改为 M3U8 播放列表,但我不知道要使用什么 MIME 类型。
当天晚上,我正在尝试回放 video/stream 并隐藏可能使用 blob 的 URL(来源)。
谢谢大家!
所以,首先,尽管这段代码似乎取自 mozilla documentation site, there are a few issues - you are not checking the readyState
before calling endOfStream
thus the error you get is valid, secondly, the play()
call is blocked by the autoplay policy changes。如果添加错误处理程序,您实际上会看到 appendBuffer
失败。这是更新后的代码段:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
// console.log(mediaSource.readyState); // ended
if (mediaSource.readyState === "open") {
mediaSource.endOfStream();
video.play();
}
});
sourceBuffer.addEventListener('error', function (event) {
console.log('an error encountered while trying to append buffer');
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
所以让我们前进到下一期 - 实际错误。因此,使用 chrome://media-internals/
我们可以看到视频实际上加载失败是因为与 ISOBMFF 格式不兼容:
我对Elastic Transcoder 不熟悉,但好像它没有生成适合直播的mp4 文件。此外,如果使用 mse,将 moov 放在开头是不够的,视频实际上必须满足所有 ISOBMFF requirements - 请参阅第 3 章和第 4 章
您提到的工作样本不是有效的比较,因为它使用 src
的 blob,其中 ISOBMFF 规则不适用。如果您可以这样做,请不要使用 MSE 并将 blob 直接放在 src
中。如果你需要 MSE,你必须正确地复用它。
好的,所以我通过使用 ffmpeg 编码我的 MP4 视频得到了原始代码示例:
ffmpeg -i input.mp4 -vf scale=1920:1080,setsar=1:1 -c:v libx264 -preset medium -c:a aac -movflags empty_moov+default_base_moof+frag_keyframe output.mp4 -hide_banner
重要的是:-movflags empty_moov+default_base_moof+frag_keyframe
此设置还将视频缩放到 1920x1080(忽略输入视频的任何纵横比)
但是,根据原 post 的评论,我相信可能有更有效的方法来生成 blob url 并摄取到视频标签中。此示例直接从 https://developer.mozilla.org 复制而来。
如果有人提出更好的脚本(不是过度设计),请在此处 post。
感谢@Rudolfs Bundulis 的所有帮助!
我正在尝试通过创建 blob URL.
来播放视频(目前托管在 S3 上,具有 public 访问权限)我使用 Elastic Transcoder 对视频进行编码,因为它应该将 MOOV atom 设置到顶部(开始)。
我无法让代码工作,但也找到了一个工作示例:link here
这是我的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
mediaSource.endOfStream();
video.play();
//console.log(mediaSource.readyState); // ended
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
我做错了什么?我查看了工具 ie.e MP4Box 或 QT-FastStart,但它们似乎有点老套。我也愿意从 MP4 更改为 M3U8 播放列表,但我不知道要使用什么 MIME 类型。
当天晚上,我正在尝试回放 video/stream 并隐藏可能使用 blob 的 URL(来源)。
谢谢大家!
所以,首先,尽管这段代码似乎取自 mozilla documentation site, there are a few issues - you are not checking the readyState
before calling endOfStream
thus the error you get is valid, secondly, the play()
call is blocked by the autoplay policy changes。如果添加错误处理程序,您实际上会看到 appendBuffer
失败。这是更新后的代码段:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
</head>
<body>
<video controls></video>
<script>
var video = document.querySelector('video');
var assetURL = 'https://ovation-blob-url-test.s3.amazonaws.com/AdobeStock_116640093_Video_WM_NEW.mp4';
// Need to be specific for Blink regarding codecs
// ./mp4info frag_bunny.mp4 | grep Codec
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if ('MediaSource' in window && MediaSource.isTypeSupported(mimeCodec)) {
var mediaSource = new MediaSource;
//console.log(mediaSource.readyState); // closed
video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.error('Unsupported MIME type or codec: ', mimeCodec);
}
function sourceOpen (_) {
//console.log(this.readyState); // open
var mediaSource = this;
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
fetchAB(assetURL, function (buf) {
sourceBuffer.addEventListener('updateend', function (_) {
// console.log(mediaSource.readyState); // ended
if (mediaSource.readyState === "open") {
mediaSource.endOfStream();
video.play();
}
});
sourceBuffer.addEventListener('error', function (event) {
console.log('an error encountered while trying to append buffer');
});
sourceBuffer.appendBuffer(buf);
});
};
function fetchAB (url, cb) {
console.log(url);
var xhr = new XMLHttpRequest;
xhr.open('get', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
cb(xhr.response);
};
xhr.send();
};
</script>
</body>
</html>
所以让我们前进到下一期 - 实际错误。因此,使用 chrome://media-internals/
我们可以看到视频实际上加载失败是因为与 ISOBMFF 格式不兼容:
我对Elastic Transcoder 不熟悉,但好像它没有生成适合直播的mp4 文件。此外,如果使用 mse,将 moov 放在开头是不够的,视频实际上必须满足所有 ISOBMFF requirements - 请参阅第 3 章和第 4 章
您提到的工作样本不是有效的比较,因为它使用 src
的 blob,其中 ISOBMFF 规则不适用。如果您可以这样做,请不要使用 MSE 并将 blob 直接放在 src
中。如果你需要 MSE,你必须正确地复用它。
好的,所以我通过使用 ffmpeg 编码我的 MP4 视频得到了原始代码示例:
ffmpeg -i input.mp4 -vf scale=1920:1080,setsar=1:1 -c:v libx264 -preset medium -c:a aac -movflags empty_moov+default_base_moof+frag_keyframe output.mp4 -hide_banner
重要的是:-movflags empty_moov+default_base_moof+frag_keyframe
此设置还将视频缩放到 1920x1080(忽略输入视频的任何纵横比)
但是,根据原 post 的评论,我相信可能有更有效的方法来生成 blob url 并摄取到视频标签中。此示例直接从 https://developer.mozilla.org 复制而来。 如果有人提出更好的脚本(不是过度设计),请在此处 post。 感谢@Rudolfs Bundulis 的所有帮助!