nodejs ffmpeg 在特定时间播放视频并将其流式传输到客户端

Posted

技术标签:

【中文标题】nodejs ffmpeg 在特定时间播放视频并将其流式传输到客户端【英文标题】:nodejs ffmpeg play video at specific time and stream it to client 【发布时间】:2020-06-23 23:44:57 【问题描述】:

我正在尝试使用 nodeJS 和 ffmpeg 制作一个基本的在线视频编辑器。

为此,我需要 2 个步骤:

    设置客户端视频的进出时间,需要客户端在特定的时间观看视频,并切换视频的位置。这意味着,如果将单个视频用作输入并将其拆分为更小的部分,则需要从下一个编辑片段的开始时间重播,如果这有意义的话。

    将输入输出数据发送到 nodejs 并使用 ffmpeg 将其导出为完成的视频。

一开始我想做1.纯粹在客户端,然后将源视频上传到nodeJS,并用ffmpeg生成相同的结果,并将结果发回。

但是目前在客户端用 html 处理视频可能有问题,所以现在我有一个改变计划:在 nodeJS 服务器上做所有的处理,包括视频播放。

这是我现在陷入困境的部分。我知道 ffmpeg 可以以与 nodeJS 不同的方式使用,但是 我还没有找到一种方法来使用 ffmpeg 在特定时间戳实时播放 .mp4 webm 视频并发送流式视频(再次,在某个时间戳)发送给客户端。

我从 ffmpeg 看到了 pipe:1 属性,但我找不到任何教程来让它与 mp4 webm 视频一起工作,并以某种方式使用 nodejs 解析标准输出数据并将其发送到客户端。即使我可以让这部分工作,我仍然不知道在某个时间戳实时播放视频。

我也看过ffplay,但据我所知,那只是为了测试;我还没有看到任何使用 nodejs 实时获取视频数据的方法。

所以:

如何在特定时间(最好使用 ffmpeg)在 nodeJS 中播放视频,并将其实时发送回客户端?

我已经看到的:

Best approach to real time http streaming to HTML5 video client

Live streaming using FFMPEG to web audio api

Ffmpeg - How to force MJPEG output of whole frames?

ffmpeg: Render webm from stdin using NodeJS

No data written to stdin or stderr from ffmpeg

node.js live streaming ffmpeg stdout to res

Realtime video conversion using nodejs and ffmpeg

Pipe output of ffmpeg using nodejs stdout

can't re-stream using FFMPEG to MP4 HTML5 video

FFmpeg live streaming webm video to multiple http clients over Nodejs

http://www.mobiuso.com/blog/2018/04/18/video-processing-with-node-ffmpeg-and-gearman/

stream mp4 video with node fluent-ffmpeg

How to get specific start & end time in ffmpeg by Node JS?

Live streaming: node-media-server + Dash.js configured for real-time low latency

Low Latency (50ms) Video Streaming with NODE.JS and html5

Server node.js for livestreaming

HLS Streaming using node JS

Stream part of the video to the client

Video streaming with HTML 5 via node.js

Streaming a video file to an html5 video player with Node.js so that the video controls continue to work?

How to (pseudo) stream H.264 video - in a cross browser and html5 way?

Pseudo Streaming an MP4 file

How to stream video data to a video element?

How do I convert an h.264 stream to MP4 using ffmpeg and pipe the result to the client?

https://medium.com/@brianshaler/on-the-fly-video-rendering-with-node-js-and-ffmpeg-165590314f2

node.js live streaming ffmpeg stdout to res

Can Node.js edit video files?

【问题讨论】:

【参考方案1】:

这个问题有点宽泛,但我已经构建了类似的东西,并会尝试为你回答这个问题:

    设置客户端视频的进出时间,需要客户端在特定时间观看视频,并切换视频的位置。这意味着,如果将单个视频用作输入并将其拆分为更小的部分,则需要从下一个编辑片段的开始时间重播,如果这有意义的话。

客户端,当你回放时,你可以简单地使用多个引用相同 URL 的 HTMLVideoElement 实例。

对于时间安排,您可以使用.currentTime 属性自行管理。但是,您会发现您的 javascript 计时不会是完美的。如果您知道实例化时的起点/终点,则可以使用Media Fragment URIs:

video.src = 'https://example.com/video.webm#t=5.5,30';

在本例中,视频从 5.5 秒开始,到 30 秒停止。您可以使用ended event 了解何时开始播放下一个剪辑。这不能保证完全精确到帧,但对于实时预览之类的东西来说非常好。

但是目前HTML客户端的视频处理可能存在问题,所以现在我有一个改变计划:在nodeJS服务器上完成所有处理,...

如果一致性很重要,这不是一个糟糕的计划。

...包括正在播放的视频。

就控制该视频的延迟和预览质量而言,您在此做出了重大权衡。我建议采用一种混合方法,其中编辑在客户端完成,但您的最终反弹/合成/无论在服务器端完成。

这与桌面视频编辑软件的工作方式没有什么不同。

这是我现在陷入困境的部分。我知道 ffmpeg 可以以与 nodeJS 不同的方式使用,但我还没有找到一种方法来使用 ffmpeg 在特定时间戳实时播放 .mp4 webm 视频,并发送流式视频(再次,在特定时间戳)发送给客户端。

是 MP4 还是 WebM?这是两种不同的容器格式。 WebM 很容易流式传输,直接从 FFmpeg 输出。 MP4 需要使用 MOOV atom (-movflags faststart),这可能有点麻烦。

无论如何,听起来您只需要在输入上设置时间戳:

ffmpeg -ss 00:01:23 -i video.mp4 -to 00:04:56 -f webm -

我已经看到了 ffmpeg 的 pipe:1 属性,但是我找不到任何教程来让它与 mp4 webm 视频一起使用,并以某种方式使用 nodejs 解析标准输出数据并将其发送到客户端。

只需使用连字符- 作为输出文件名,FFmpeg 将输出到 STDOUT。然后,您无需在 Node.js 应用程序中执行任何其他操作……将输出直接传送到客户端。未经测试,但您正在寻找类似的东西,假设是典型的 Express 应用:

app.get('/stream', (req, res, next) => 
  const ffmpeg = child_process.spawn('ffmpeg', [
    '-i', 'video.mp4',
    '-f', 'webm',
    '-'
  ]);

  res.set('Content-Type', 'video/webm'); // TODO: Might want to set your codecs here also

  ffmpeg.stdout.pipe(res);
);

即使我可以让这部分工作,我仍然不知道在某个时间戳实时播放视频。

好吧,为此,你只是在播放一个流,所以你可以这样做:

<video src="https://your-nodejs-server.example.com/stream" preload="none" />

preload="none" 部分很重要,要让它保持“活跃”。

所有这些的替代方法是设置GStreamer 管道,并可能利用其内置的 WebRTC 堆栈。这不是微不足道的,但具有潜在的较低延迟和自动处理“赶上”来自服务器的实时视频的优势。如果您使用普通视频标签,则必须通过监控缓冲数据和管理播放速度来自行处理。

我也看过ffplay...

FFplay 与您的项目无关。

希望这堆笔记能给你一些思考和观察的东西。

【讨论】:

感谢所有提示,非常有帮助!我将尝试在此处实现这些方法,如果我还有任何问题,请告诉您 @bluejayke 是的,没问题,祝你的项目好运!此外,如果您对 Stack Overflow 问题范围之外的任何直接咨询感兴趣,请随时给我发送电子邮件至 brad@audiopump.co。

以上是关于nodejs ffmpeg 在特定时间播放视频并将其流式传输到客户端的主要内容,如果未能解决你的问题,请参考以下文章

如何配置ffmpeg只是为了播放RTSP视频

NodeJS 视频流动态转码

FFmpeg 如何使用 bash 生成视频序列

如何用 FFmpeg 编写一个简单播放器详

通过ffmpeg反向播放视频

使用 JavaCV 和 FFmpeg 播放视频