我正在开发一个屏幕录制应用程序,它允许用户录制他们的屏幕,我使用 websocket 将他们的字节数据实时发送到我的 FastAPI Python 服务器。字节每 2 秒发送一次,我使用 FFmpeg 将字节保存在输出 MP4 视频文件中。
问题: 用户停止录制后,我有一个 ffmpeg 进程,它将录制的视频作为输入,并在其上添加一些过滤器并返回编辑后的视频。大多数时候它工作正常,但是有时用户会遇到这个 ffmpeg 错误:-
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x60f50ba488c0] moov atom not found
/tmp/recording_91427bc6-3e69-4fef-9aa9-17093d41a136.mp4: Invalid data found when processing input
当我在本地打开视频时,似乎没有任何问题,视频也没有损坏
这是我的代码:-
前端
const recorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=H264',
videoBitsPerSecond: 8000000
});
recorder.ondataavailable = (e: BlobEvent) => {
socketRef.socket.send(e.data)
}
这是我的Python代码:-
@router.websocket("/stream")
async def websocket_endpoint(websocket: WebSocket, token: str = Query(...), videoId: str = Query(...), authorize: AuthJWT = Depends()):
await manager.connect(websocket)
print(f"Chrome Extension = {token} and the key = {videoId}")
print(f" Client connected: {websocket.client.host}")
dataNumber = 1
recordingFile = os.path.join(temp_dir, f"recording_{videoId}.mp4")
command = [
'ffmpeg',
'-y',
'-i',
'-',
'-codec:v',
'copy',
'-c:a', 'aac',
'-y',
'-f', 'mp4',
recordingFile,
# "-"
# f'output{queueNumber}.mp4',
]
async with await anyio.open_process(command, stdin=subprocess.PIPE) as process:
try:
while True:
try:
# async with video_lock:
data = await websocket.receive_bytes()
if not data:
break
await process.stdin.send(data)
await websocket.send_json({"chunkNumber": dataNumber, "status": 200})
dataNumber = dataNumber + 1
except RuntimeError:
break
except WebSocketDisconnect:
print(f"Client disconnected: {websocket.client.host}")
finally:
manager.disconnect(websocket)
await process.stdin.aclose()
await process.wait()
“用户停止录制后,我有一个 ffmpeg 进程将录制的视频作为输入......”
mimeType: video/webm
,那么您不能在文件名中使用文件类型 .mp4
。video/webm
意味着保存 filename.webm
(不是 filename.mp4
)。FFmpeg 正在寻找 moov 原子,因为文件名是
.mp4
。解决方案:
将录音文件扩展名从
.mp4
重命名为 .webm
。filename.webm
.