[我正在尝试通过WS向我的Phoenix后端发出webm
Blob
(由MediaRecorder
编码并生成的Base64编码),在这里我对它们进行Base64解码并将它们附加到文件中。我最终得到的是一个有缺陷的webm视频,当我在播放器中打开它时,我可以看到第一帧,但是有些像素化,颜色不正确等。视频长度不存在,并且当我尝试诊断ffmpeg
的错误,它表示:
[h264 @ 0x7fcbd3804200] decode_slice_header error
[h264 @ 0x7fcbd3804200] no frame!
[h264 @ 0x7fcbd3804200] non-existing PPS 0 referenced
(repeated many times)
我不确定我在哪里出错(或者如果我在出错),这是我的简短客户端代码:
const mediaStream = await navigator.mediaDevices.getUserMedia({ audio:true, video: true });
const options = {
audioBitsPerSecond: 128000,
videoBitsPerSecond: 2500000,
mimeType: 'video/webm'
}
const mediaRecorder = new MediaRecorder(mediaStream,options);
mediaRecorder.ondataavailable = ((e) => {
var reader = new window.FileReader();
reader.readAsDataURL(e.data);
reader.onloadend = (() => {
base64data = reader.result;
topic.push('video_feed', {data: base64data});
})
})
mediaRecorder.start(1500);
我负责文件IO和Base64解码的后端Elixir代码:
{:ok, io} = File.open("some_file.webm", [:binary, :append]) # This part is triggered once
# Everything below is triggered upon receiving a blob (feed is the base64data object from
# clientside code above)
"data:video/x-matroska;codecs=avc1,opus;base64," <> base64_bit = feed
decode_res = Base.decode64(base64_bit)
case decode_res do
:error -> some_error_handling_code
{:ok, data} -> io |> IO.binwrite(data)
end
{:noreply, state}
我是否以某种方式弄乱了文件IO?我怀疑我以某种方式缺少媒体播放器所需的某些标头或文件元数据。
[好吧,经过2天的挖掘和调试webm
文件,我意识到这是一个客户端问题(与代码有关)。
[存在竞争情况,在我调用mediaRecorder.stop()
后立即从客户端关闭了套接字。这是一个错误,因为我忘记了在这种情况下,总是发出最后的事件,并剩下其余的数据(最后一次发射时间和停止记录器时间之间的时间段)。该事件从未发送,因为我立即以编程方式关闭了标签页(据我所知),因此我的视频格式不正确。我还有其他一些与代码相关的问题,但没有那么大。
请确保您收到了最终事件,类似以下内容:
topic.push('feed', {data: base64data})
.receive('ok', () => {
// MR state will become inactive as soon as you call .stop() method
if (mediaRecorder.state === 'inactive') {
x.push('that_was_the_final_chunk_go_wild', {}).receive('ok' => {
nowWeCanSurelySafelyTerminate();
})
}
})
}