我试图将网络摄像头的视频实时播放给其他客户,但当观众开始在中间观看时我遇到了一些问题。
为此,我使用getUserMedia(及其所有兄弟姐妹)获取网络摄像头流。
然后,点击一下按钮,我就开始录制流,并将每个段/块/任何你称之为的内容发送到广播公司的后台后台:
var mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(1000);
mediaRecorder.ondataavailable = function (event) {
uploadVideoSegment(event); //wrap with a blob and call socket.send(...)
}
在服务器端(Web API,使用Microsoft.Web.WebSockets), 我完全得到了字节[]。
然后我将byte []发送到当前连接到Broadcaster的Viewers,使用FileReader在socket的onmessage事件上读取它,并将Uint8Array附加到MediaSource的sourceBuffer,这是HTML5的src视频元素。
当观察者从头开始获取byte []时,具体地说,前面的126个字节以EBMLHeader(0x1A45DFA3)开头并以Cluster的开头(0x1F43B675)结束,然后是整个媒体 - 它被播放得很好。
当新查看器加入中间并获取第二个块以及之后时,会出现问题。
我一直试图通过各种方式进行研究并弄脏手。我知道标题是必不可少的(http://www.slideshare.net/mganeko/media-recorder-and-webm),有关于关键帧和所有这些内容的一些东西,但我很快就感到困惑。
到目前为止,我尝试在c#中编写自己的简单webm解析器(来自github中的node.js项目的引用 - https://github.com/mganeko/wmls)。因此,我从第一个块中分割出标头,缓存它并尝试稍后将其与每个块一起发送。当然它没有用。
我认为也许MediaRecorder正在将群集分成中间,因为ondataavailable事件被触发(因为我已经注意到第二个块的开始并不是从群集的标题)。
此时我不知道如何使用解析器来解决问题而陷入困境。
然后我读到了使用ffmpeg转换webm流s.t每帧也是一个关键帧 - Encoding FFMPEG to MPEG-DASH – or WebM with Keyframe Clusters – for MediaSource API(在Chris Nolet的回答中)。
我尝试使用FFMpegConverter(for .Net):
var conv = new FFMpegConverter();
var outputStream = new MemoryStream();
var liveMedia = conv.ConvertLiveMedia("webm", outputStream, "webm", new ConvertSettings { VideoCodec = "vp8", CustomOutputArgs = "-g 1" });
liveMedia.Start();
liveMedia.Write(vs.RawByteArr, 0, vs.RawByteArr.Length); //vs.RawByteArr is the byte[] I got from the MediaRecorder
liveMedia.Stop();
byte[] buf = new byte[outputStream.Length];
outputStream.Position = 0;
outputStream.Read(buf, 0, (int)outputStream.Length);
我对FFMPEG并不熟悉,所以我可能没有正确参与参数,尽管答案是我所看到的,但他们很快就在那里写了。
当然我遇到了很多问题: 使用websockets时,FFMpegConverter的运行只是强制关闭websockets通道。 (如果有人能解释原因,我会很高兴。)
我没有放弃,我使用HttpGet(用于从服务器获取片段)和HttpPost(具有多部分blob和所有用于发布记录块的派对)方法并尝试使用上面提到的FFMpegConverter。
对于第一个段它工作但是输出了一个字节[],其长度是原始段的一半(如果有人能够解释那个,我会很高兴),而对于其他块,它会抛出异常(每个时间不只是一次)说管道已经结束。
我迷路了。
请帮助我,任何人。主要的4个问题是:
如何播放MediaRecorder第一块后面的块? (同时,我只是触发了sourcebuffer close / end事件,并且sourceBuffer与其父MediaSource对象分离(导致像#34; sourceBuffer已从其父&#34中删除的异常;),因为传递给它的byte []并不好 - 也许我没有使用我以正确的方式编写的webm解析器来检测第二个块中的重要部分(顺便说一句,它不是从集群开始的 - 这就是为什么我写道,似乎MediaRecorder正在削减中间的集群))
为什么FFMpeg会导致WebSockets关闭?
我是否使用带有正确参数的FFMpegConverter.ConvertLiveMedia来获取一个新的webm段,其中包含所需的所有信息,以便将其作为一个独立的块,而不依赖于以前的块(作为Chris Nolet在上面的SO链接中的答案中说道?
为什么FFMpegConverter抛出"管道结束"例外
任何帮助都将受到高度赞赏。