即时更改 ffmpeg 输入 [英] Change ffmpeg input on the fly

查看:48
本文介绍了即时更改 ffmpeg 输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在不事先知道 Linux 主机上接下来会播放哪个视频文件的情况下不间断地播放视频.这应该在本地工作,没有任何网络.我打算用ffplay播放视频.一个视频播放完后,下一个应该可以无缝播放,没有任何延迟.我试图附加到一个文件,然后像这样用 ffplay 播放它:

I want to show videos non-stop without knowing beforehand which videofile would go next on a Linux host. This should work locally, without any networking. I'm going to playback videos with ffplay. When one video is finished, the next one should be played seamlessly, without any delay. I tried to append to a file and just play it with ffplay like this:

ffmpeg -re -i source.mp4 -f mpegts - >> video.ts
# In another console
ffplay video.ts

但这不起作用 - 一旦 ffmpeg 处理完文件,ffplay 就会停止播放.如果我再次运行相同的 ffmpeg 命令,ffplay 从一开始就播放带有丑陋工件的视频.

But that didn't work - once ffmpeg is done with the file, ffplay stops playing. If I run the same ffmpeg command again, ffplay plays the video from the start with ugly artifacts.

我想要实现的是:

  1. 运行 ffplay 并忘记它
  2. 对视频文件运行 ffmpeg.ffplay 应该会自动开始播放
  3. 对视频文件运行 ffmpeg.ffplay 应该自动无缝地开始播放它,但只有在它完成第一个文件后
  4. 在另一个文件上运行 ffmpeg...我希望你能明白

我对 ffmpeg 真的很陌生,所以如果我要求一些明显或不可能的东西,我很抱歉.我希望你能让我找到正确的方向.

I'm really new to ffmpeg, so I'm sorry if I'm asking for something obvious or impossible. I hope you'll be able to get me into the right direction.

推荐答案

我已经设法通过以下命令获得了我想要的东西(通过遵循 Ryan Williams 使用 HLS 的提示):

I've managed to get what I want with the following command (by following Ryan Williams's tip to use HLS):

ffmpeg -i source.mp4 -s 640x360 -hls_list_size 30 -hls_flags delete_segments+append_list+omit_endlist -f hls out.m3u8

这就是它起作用的原因:

Here's why it works:

HTTP 直播是苹果公司实现的协议.简而言之,它非常简单——它只是在文本文件中列出视频块及其持续时间,以便播放器知道接下来播放哪个块.玩家不需要事先知道有多少块以及接下来会是什么——这正是我的要求.

HTTP Live Streaming is a protocol implemented by Apple. In a nutshell, it's pretty simple - it just lists chunks of video and their duration in a text file, so that player knew which chunk to play next. The player does not need to know beforehand how many chunks there are and which will be next - these were exactly my requirements.

为了完成这项工作,我在 ffmpeg 命令中添加了 -f hls 标志.它使 ffmpeg 获取输入视频,将其分成块,保存并为 HLS 消费者生成播放列表(在我的情况下为 ffplay).

To make this work, I added -f hls flag to the ffmpeg command. It makes ffmpeg take the input video, split it in chunks, save them and generate a playlist for HLS consumer (ffplay in my case).

但我想确保播放列表是无限的.默认情况下,ffmpeg 会在 m3u8 文件中添加终止命令.为了防止这种情况,并确保 ffmpeg 清理并且不会覆盖现有的播放列表,我添加了以下标志:-hls_flags delete_segments+append_list+omit_endlist.

But I want to make sure that the playlist is infinite. By default, ffmpeg adds a terminating command to the m3u8 file. To prevent that, and also to make sure that ffmpeg cleanups and does not override the existing playlist, I added these flags: -hls_flags delete_segments+append_list+omit_endlist.

我还使用 -hls_list_size 30 标志将播放列表中的默认块数更改为 30.

I also changed the default number of chunks in the playlist to 30 with -hls_list_size 30 flag.

结果是我可以使用 ffplay out.m3u8 播放的无限视频.当 ffmpeg 命令完成后,我只需要重新运行它和我接下来要播放的视频.玩家会自动捡起所有东西.

The result is the infinite video that I can play with ffplay out.m3u8. When ffmpeg command finishes, I just have to re-run it with the video I want to go next. The player picks everything up automatically.

当然,我仍然必须确保在当前视频播放结束时我已经准备好下一个视频.此外,我怀疑如果我快速连续运行 ffmpeg 命令,它可能会导致正在播放的视频卡顿 - 因为 ffmpeg 可以清理尚未播放的块,但 ffmpeg 认为它们很旧.

Of course, I still have to make sure that I have the next video ready when the current video playback comes to an end. Also, I suspect that if I ran ffmpeg commands in quick succession it could lead to stuttering the video being played - because ffmpeg could clean up chunks that were not played back yet, but ffmpeg considered them old.

这篇关于即时更改 ffmpeg 输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆