但在Firefox中运行良好。
Google Chrome版本:61.0.3163.100(官方版本)(64位)
Mozilla Firefox版本:56.0.2(64位)
我的视频片段化MP4通过WebSocket流式传输到客户端html页面,然后将其提取到MSE中。视频编解码器是H264 Main Profile。已在FFPROBE和其他检查员中检查视频信息,以确保数据完整性正常。在复用FMP4时使用以下标志:
"empty_moov+default_base_moof+frag_keyframe"
我还仔细检查了第一个碎片是所谓的“初始化段”,大小为24字节。 正如我所说,Firefox播放很好。
这是客户端代码(主要是从here借来的):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MSE Demo</title>
</head>
<body>
<h1>MSE Demo</h1>
<div>
<video id="video1" controls width="80%" autoplay="true"> </video>
</div>
<script type="text/javascript">
(function () {
var mime = 'video/mp4; codecs="avc1.4D401E"';
if (!MediaSource.isTypeSupported(mime)) {
document.querySelector('h1').append(' - Unsuported mime type :(');
return;
}
var buffer;
var websocket;
var buffer_size = 4 * 1024 * 1024;
var buffer_index = 0;
var frag_mp4_buffer = new Uint8Array(buffer_size);
var video = document.querySelector('video');
var mediaSource = new MediaSource();
mediaSource.addEventListener('sourceended', function (e) { console.log('sourceended: ' + mediaSource.readyState); });
mediaSource.addEventListener('sourceclose', function (e) { console.log('sourceclose: ' + mediaSource.readyState); });
mediaSource.addEventListener('error', function (e) { console.log('error: ' + mediaSource.readyState); });
video.src = window.URL.createObjectURL(mediaSource);
video.crossOrigin = 'anonymous';
mediaSource.addEventListener('sourceopen', function (e) {
console.log('sourceopen: ' + mediaSource.readyState);
//doesn't help:
// var playPromise = video.play();
// In browsers that don’t yet support this functionality,
// playPromise won’t be defined.
/*
if (playPromise !== undefined) {
playPromise.then(function () {
// Automatic playback started!
}).catch(function (error) {
// Automatic playback failed.
// Show a UI element to let the user manually start playback.
});
}
*/
buffer = mediaSource.addSourceBuffer(mime);
buffer.addEventListener('updateend', function (e) {
if (video.duration && !video.currentTime) {
video.currentTime = video.duration;
}
});
var websocket = new WebSocket('ws://' + document.location.hostname + ':8080');
websocket.binaryType = 'arraybuffer';
websocket.addEventListener('message', function (e) {
var data = new Uint8Array(e.data);
console.log("got packet! size:" + data.length);
if (data.length) {
if ((buffer_index + data.length) <= buffer_size) {
frag_mp4_buffer.set(data, buffer_index);
buffer_index = buffer_index + data.length;
if (!buffer.updating && mediaSource.readyState == 'open')
{
var appended = frag_mp4_buffer.slice(0, buffer_index);
buffer.appendBuffer(appended);
frag_mp4_buffer.fill(0);
buffer_index = 0;
}
}
}
}, false);
}, false);
})();
</script>
</body>
另一个重要信息,你可以看到我注释了video.play()
电话。这实际上是应用程序启动时抛出错误的唯一地方:
未捕获(承诺)DOMException:无法加载,因为没有 找到支持的来源
我尝试了here的以下解决方案:
var playPromise = video.play();
if (playPromise !== undefined) {
playPromise.then(function () {
// Automatic playback started!
}).catch(function (error) {
// Automatic playback failed.
$(document).on('click', '#video1', function (e) {
var video = $(this).get(0);
if (video.paused === false) {
video.pause();
} else {
video.play();
}
return false;
});
});
}
但它没有改变。视频区域始终为白色。
答案 0 :(得分:1)
我遇到了一个类似的问题,我只能使用这个mse example在Firefox上播放我的碎片mp4,但不能在chrome上播放。我试图首先提供一个完整的文件,而不是通过websocket发送它,因为我想确保我的碎片mp4格式正确。我发现的问题是,在我的ffmpeg命令中,如果我包含-an
删除音频,那么我的文件将无法在chrome中播放,但仍然可以在firefox中使用。不使用音频标志或专门使用-c:a libfdk_aac
允许我的mp4在chrome和firefox上播放。此外,您应该只需要-movflags +dash
而不是所有其他movflags。有关我下面的代码片段的参考,我正在使用来自ip摄像机的rtsp源,该摄像机使用h264视频编码,因此-c:v copy
。
在mac上测试过,在firefox和safari上工作但不是chrome:
ffmpeg -i input_source -an -c:v copy -f mp4 -movflags +dash dash.mp4
在mac上测试过,在firefox和safari上进行了操作和chrome
ffmpeg -i input_source -c:v copy -f mp4 -movflags +dash dash.mp4
ffmpeg -i input_source -c:a libfdk_aac -c:v copy -f mp4 -movflags +dash dash.mp4
*编辑我刚刚找到了有关音频编码与Chrome播放相关的更多信息。我的mimetype / codec错了,chrome并不像firefox和safari那样宽容。
var mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
我将其更改为var mimeCodec = 'video/mp4; codecs="avc1.42E01E"';
,我的mp4编码无音频以chrome格式播放,以及其他浏览器。也许你有音频但不包括编解码器的音频部分?或者您的视频编解码器可能不适合您的视频?如果没有看到用于创建文件的完整ffmpeg命令,很难说。*第二次编辑。我使用ffmpeg,nodejs,express和socket.io在媒体源扩展上测试了实时流式传输mp4 little project。 它的边缘有点粗糙,但它大部分都有效。
答案 1 :(得分:0)
这在Firefox和Chrome上对我有效:
ffmpeg -i input.any \
-f mp4 \
-movflags faststart+separate_moof+empty_moov+default_base_moof \
-acodec aac -b:a 256000 \
-frag_duration 500K \
output.mp4
还可与Meadia Source Extension API中的SourceBuffer一起使用。您在这里寻找的Mime-Type是audio/mp4; codecs="mp4a.40.2"
。
但是在这一点上,我不确定如何在该文件中进行查找(如果可能的话),例如如果您不想将整个文件发送到客户端,而是从特定的时间戳开始,然后直接跳至[moof][mdata]
对以开始加载。
答案 2 :(得分:0)
Chrome 不喜欢视频没有音频。
如果您使用 m4s 片段(本质上是碎片化 mp4 的块)生成 HLS 播放列表,那么您还需要确保有音频,否则它根本不会播放。
这个应该适用于所有浏览器:
ffmpeg -y -i SOURCE.mp4 -f lavfi -i aevalsrc=0 -af apad -shortest -c:v copy -movflags empty_moov+default_base_moof+frag_keyframe+omit_tfhd_offset -write_tmcd off FRAGMENTED_WITH_PADDED.mp4