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

Javascript nodejs ffmpeg在特定时间播放视频并将其流式传输到客户端,javascript,node.js,ffmpeg,mp4,webm,Javascript,Node.js,Ffmpeg,Mp4,Webm,我正在尝试用nodeJS和ffmpeg制作一个基本的在线视频编辑器 为此,我需要两个步骤: 设置客户端视频的输入和输出时间,这要求客户端在特定时间查看视频,并切换视频的位置。也就是说,如果使用单个视频作为输入,并将其分割为较小的部分,则需要从下一个编辑片段的开始时间开始重播(如果有意义的话) 将输入输出数据发送到nodejs,并使用ffmpeg将其导出为完成的视频 起初我想做1。纯在客户端上,然后将源视频上载到nodeJS,并使用ffmpeg生成相同的结果,然后将结果发回 但是目前HTML客户端

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

为此,我需要两个步骤:

  • 设置客户端视频的输入和输出时间,这要求客户端在特定时间查看视频,并切换视频的位置。也就是说,如果使用单个视频作为输入,并将其分割为较小的部分,则需要从下一个编辑片段的开始时间开始重播(如果有意义的话)

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

  • 起初我想做1。纯在客户端上,然后将源视频上载到nodeJS,并使用ffmpeg生成相同的结果,然后将结果发回

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

    这就是我现在被卡住的部分。我知道ffmpeg可以以许多不同于NodeJ的方式使用,但是我还没有找到一种方法来使用ffmpeg在特定时间戳实时播放.mp4 webm视频,并将流式视频(同样,在特定时间戳)发送到客户端。

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

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

    因此:

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

    我已经看到:


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

  • 设置客户端视频的输入和输出时间,这要求客户端在特定时间查看视频,并切换视频的位置。也就是说,如果使用单个视频作为输入,并将其分割为较小的部分,则需要从下一个编辑片段的开始时间开始重播(如果有意义的话)
  • 客户端,当您回放时,您可以简单地使用多个引用相同URL的HTMLVideoElement实例

    对于计时,您可以使用
    .currentTime
    属性自行管理。然而,您会发现您的JavaScript计时并不完美。如果在实例化时知道起点/终点,可以使用:

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

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

    如果一致性很重要的话,这是一个不错的计划

    。。。包括视频播放

    这里有一个严重的折衷,即控制视频的延迟和预览的质量。我建议使用一种混合方法,即编辑是在客户端完成的,但最终的反弹/合成/任何操作都是在服务器端完成的

    这和桌面视频编辑软件的工作原理没有什么不同

    这就是我现在被卡住的部分。我知道ffmpeg可以以许多不同于NodeJ的方式使用,但我还没有找到一种方法,可以使用ffmpeg在特定时间戳实时播放.mp4 webm视频,并将流式视频(同样,在特定时间戳)发送到客户端

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

    在任何情况下,听起来您只需要在输入上设置时间戳:

    ffmpeg -ss 00:01:23 -i video.mp4 -to 00:04:56 -f webm -
    
    我已经看过ffmpeg中的pipe:1属性,但是我找不到任何教程来让它与mp4 webm视频一起工作,以及用nodejs解析stdout数据并将其发送到客户端

    只需使用连字符
    -
    作为输出文件名,FFmpeg将输出到标准输出。那么,在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”
    部件很重要,可以使其保持“活动”

    所有这一切的替代方法是建立一个管道,并可能利用其内置的WebRTC堆栈。这并非微不足道,但具有潜在的较低延迟和自动处理来自服务器的实时视频的优势。如果你使用普通的视频标签,你必须通过监控缓冲数据和管理播放速度来自己处理

    我也看过ffplay

    FFplay与您的项目无关


    希望这堆笔记会给你一些需要考虑的事情,看一下。

    谢谢所有的提示,非常有用!我将尝试在这里实现这些方法,如果还有其他方法,请告诉您questions@blueja
    <video src="https://your-nodejs-server.example.com/stream" preload="none" />