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

时间:2020-03-11 22:47:45

标签: javascript node.js ffmpeg mp4 webm

我正在尝试使用nodeJS和ffmpeg创建基本的在线视频编辑器。

为此,我需要2个步骤:

  1. 设置来自客户端的视频的出入时间,这要求客户端在特定时间观看视频,并切换视频的位置。这意味着,如果将单个视频用作输入,并将其分割成较小的部分,则需要从下一个已编辑片段的开始时间开始重放。

  2. 将输入输出数据发送到nodejs并使用ffmpeg将其导出为最终视频。

首先,我想只在客户端上做1.然后将源视频上传到nodeJS,并使用ffmpeg生成相同的结果,然后将结果发送回去。

但是目前在客户端使用HTML进行视频处理可能会出现问题,所以现在我有一个计划变更:在nodeJS服务器上进行所有处理,包括视频播放。

这是我现在停留的部分。我知道ffmpeg与nodeJS可以以多种不同的方式使用,但是我还没有找到在特定时间戳下使用ffmpeg实时播放.mp4 webm视频并发送流视频的方法(再次,在特定的时间戳记下)。

我已经从ffmpeg看到了pipe:1属性,但是我找不到任何教程来使它与mp4 webm视频一起使用,以及使用nodejs解析stdout数据并将其发送到客户端。即使我可以发挥作用,我仍然不知道要在某个时间戳实时播放视频。

我也看过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 个答案:

答案 0 :(得分:2)

这个问题有点广泛,但是我已经建立了类似的东西,并将尝试为您分块回答:

  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原子(-movflags faststart)来监视,并且可能会有些麻烦。

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

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

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

只需使用连字符-作为输出文件名,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与您的项目无关。

希望这堆笔记能给您一些思考和研究的东西。