我正在尝试执行以下操作:
在服务器上,我将h264数据包编码为Webm(MKV)容器结构,这样每个集群都会得到一个单帧数据包。只有第一个数据块不同,因为它包含一个名为Initialization Segment的内容。Here it is explained quite well。 然后我通过WebSocket将二维流中的这些集群逐个流式传输到一个浏览器,即Chrome浏览器。 我使用h264编解码器而不是VP8或VP9(这是Webm视频格式的本机编解码器)可能听起来很奇怪。但似乎html video tag没有问题来播放这种视频容器。如果我只是将整个流写入文件并将其传递给video.src,它就可以正常播放。但是我想实时传输它。这就是为什么我将视频分成块并通过websocket发送它们的原因。 在客户端,我正在使用MediaSource API。我对Web技术的经验很少,但我发现这可能是我的唯一方法。
它没有用。我没有错误,流运行正常,视频对象没有发出警告或错误(通过开发者控制台检查)。 客户端代码如下所示:
<script>
$(document).ready(function () {
var sourceBuffer;
var player = document.getElementById("video1");
var mediaSource = new MediaSource();
player.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
//array with incoming segments:
var mediaSegments = [];
var ws = new WebSocket("ws://localhost:8080/echo");
ws.binaryType = "arraybuffer";
player.addEventListener("error", function (err) {
$("#id1").append("video error "+ err.error + "\n");
}, false);
player.addEventListener("playing", function () {
$("#id1").append("playing\n");
}, false);
player.addEventListener("progress",onProgress);
ws.onopen = function () {
$("#id1").append("Socket opened\n");
};
function sourceOpen()
{
sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.64001E"');
}
function onUpdateEnd()
{
if (!mediaSegments.length)
{
return;
}
sourceBuffer.appendBuffer(mediaSegments.shift());
}
var initSegment = true;
ws.onmessage = function (evt) {
if (evt.data instanceof ArrayBuffer) {
var buffer = evt.data;
//the first segment is always 'initSegment'
//it must be appended to the buffer first
if(initSegment == true)
{
sourceBuffer.appendBuffer(buffer);
sourceBuffer.addEventListener('updateend', onUpdateEnd);
initSegment = false;
}
else
{
mediaSegments.push(buffer);
}
}
};
});
我也为MIME类型尝试了不同的配置文件代码,即使我知道我的编解码器是&#34;高配置文件。我尝试了以下配置文件:
avc1.42E01E基线
avc1.58A01E扩展资料
avc1.4D401E主要资料
avc1.64001E高调
在我从2 - 3年前发现的一些例子中,我看到开发人员使用type =&#34; video / x-matroska&#34;,但从那以后可能有很多变化,因为现在甚至video.src都没有&# 39; t处理这种MIME。
此外,为了确保我通过流发送的块没有损坏,我在VLC播放器中打开了一个本地流媒体会话,它逐步播放,没有任何问题。 我唯一怀疑MediaCodec不知道如何处理这种混合容器。我想知道为什么视频对象播放这样的视频ok.Am我在客户端代码中遗漏了什么?或者MediacCodec API确实不支持这种类型的媒体?
PS:对于那些好奇为什么我使用MKV容器而不是MPEG DASH,例如。答案是 - 容器简单,数据写入速度和大小。 EBML结构非常紧凑,易于实时编写。