使用FFMPEG创建无限MP4(不循环)

时间:2017-12-26 18:33:20

标签: ffmpeg raspberry-pi video-streaming html5-video mp4

我知道mp4流是一个禁忌,这个项目只是用于播放视频:)

我有一个由Raspberry Pi相机提供的无限h264流,我想用无限的mp4包装它,所以我可以在浏览器中观看它。

(来源)raspivid -t 0 -w 1640 -h 1232 -fps 20 -b 500000 -vf -hf -o -

(ffmpeg)ffmpeg -r 20 -i - -vcodec copy -movflags "frag_keyframe+empty_moov" -f mp4 pipe:1

我所做的是将管道(源)导入(ffmpeg)然后(ffmpeg)导入我的程序,缓冲,上传到服务器,进行身份验证等。

这很好用,我可以从浏览器中观看流。

问题:问题是(ffmpeg)在6分钟后停止输出数据。

当视频到达6:00时,(ffmpeg)命令停止将数据写入其stdout

我尝试更改帧率,比特率,分辨率等,但没有任何区别,它总是在6点停止。

我检查了(source)命令,它仍在写入自己的stdout

问题:我有什么遗漏的东西吗?为什么在6分钟后停止写stdout?命令缺少一些标志以允许无限的mp4?

编辑:添加了以下-report的输出。

ffmpeg started on 2017-12-26 at 19:59:13
Report written to "ffmpeg-20171226-195913.log"
Command line:
ffmpeg -report -r 20 -i - -vcodec copy -movflags frag_keyframe+empty_moov -f mp4 pipe:1
ffmpeg version git-2017-12-10-eaff5fc Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 6.3.0 (Raspbian 6.3.0-18+rpi1) 20170516
  configuration: --arch=armel --target-os=linux --enable-gpl --enable-nonfree
  libavutil      56.  5.100 / 56.  5.100
  libavcodec     58.  6.103 / 58.  6.103
  libavformat    58.  3.100 / 58.  3.100
  libavdevice    58.  0.100 / 58.  0.100
  libavfilter     7.  7.100 /  7.  7.100
  libswscale      5.  0.101 /  5.  0.101
  libswresample   3.  0.101 /  3.  0.101
  libpostproc    55.  0.100 / 55.  0.100
Splitting the commandline.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Reading option '-r' ... matched as option 'r' (set frame rate (Hz value, fraction or abbreviation)) with argument '20'.
Reading option '-i' ... matched as input url with argument '-'.
Reading option '-vcodec' ... matched as option 'vcodec' (force video codec ('copy' to copy stream)) with argument 'copy'.
Reading option '-movflags' ... matched as AVOption 'movflags' with argument 'frag_keyframe+empty_moov'.
Reading option '-f' ... matched as option 'f' (force format) with argument 'mp4'.
Reading option 'pipe:1' ... matched as output url.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option report (generate a report) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input url -.
Applying option r (set frame rate (Hz value, fraction or abbreviation)) with argument 20.
Successfully parsed a group of options.
Opening an input file: -.
[NULL @ 0x2e7d450] Opening 'pipe:' for reading
[pipe @ 0x2e7db70] Setting default whitelist 'crypto'
[h264 @ 0x2e7d450] Format h264 probed with size=2048 and score=51
[h264 @ 0x2e7d450] Before avformat_find_stream_info() pos: 0 bytes read:4096 seeks:0 nb_streams:1
[AVBSFContext @ 0x2e8f3e0] nal_unit_type: 7, nal_ref_idc: 1
[AVBSFContext @ 0x2e8f3e0] nal_unit_type: 8, nal_ref_idc: 1
[AVBSFContext @ 0x2e8f3e0] nal_unit_type: 5, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 7, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 8, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 5, nal_ref_idc: 1
[h264 @ 0x2e7fa60] Format yuv420p chosen by get_format().
[h264 @ 0x2e7fa60] Reinit context to 1648x1232, pix_fmt: yuv420p
[h264 @ 0x2e7fa60] nal_unit_type: 1, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 1, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 1, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 1, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 1, nal_ref_idc: 1
[h264 @ 0x2e7fa60] nal_unit_type: 1, nal_ref_idc: 1
[h264 @ 0x2e7d450] max_analyze_duration 5000000 reached at 5000000 microseconds st:0
[h264 @ 0x2e7d450] After avformat_find_stream_info() pos: 395264 bytes read:397312 seeks:0 frames:127
Input #0, h264, from 'pipe:':
  Duration: N/A, bitrate: N/A
    Stream #0:0, 127, 1/1200000: Video: h264 (High), yuv420p(progressive), 1640x1232, 25 fps, 25 tbr, 1200k tbn, 50 tbc
Successfully opened the file.
Parsing a group of options: output url pipe:1.
Applying option vcodec (force video codec ('copy' to copy stream)) with argument copy.
Applying option f (force format) with argument mp4.
Successfully parsed a group of options.
Opening an output file: pipe:1.
[pipe @ 0x2e8ef70] Setting default whitelist 'crypto'
Successfully opened the file.
[mp4 @ 0x2e80680] Empty MOOV enabled; disabling automatic bitstream filtering
Output #0, mp4, to 'pipe:1':
  Metadata:
    encoder         : Lavf58.3.100
    Stream #0:0, 0, 1/10240: Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 1640x1232, q=2-31, 25 fps, 25 tbr, 10240 tbn, 20 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (copy)
cur_dts is invalid (this is harmless if it occurs once at the start per stream)
[mp4 @ 0x2e80680] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
frame=  140 fps=0.0 q=-1.0 size=     352kB time=00:00:06.95 bitrate= 415.4kbits/s speed=11.8x    
frame=  152 fps=128 q=-1.0 size=     352kB time=00:00:07.55 bitrate= 382.4kbits/s speed=6.35x    
frame=  164 fps= 94 q=-1.0 size=     352kB time=00:00:08.15 bitrate= 354.3kbits/s speed=4.69x    
frame=  174 fps= 78 q=-1.0 size=     352kB time=00:00:08.65 bitrate= 333.8kbits/s speed=3.86x    
.....
frame= 7342 fps= 20 q=-1.0 size=   22381kB time=00:06:07.05 bitrate= 499.5kbits/s speed=1.02x    
frame= 7354 fps= 20 q=-1.0 size=   22381kB time=00:06:07.65 bitrate= 498.7kbits/s speed=1.02x    
frame= 7366 fps= 20 q=-1.0 size=   22381kB time=00:06:08.25 bitrate= 497.9kbits/s speed=1.02x

正如您所看到的,它在此次运行中于6:08停止工作。然后它闲置了几分钟,我不得不杀死这个过程。

1 个答案:

答案 0 :(得分:1)

事实证明这就是我处理这个过程的方式。

ffmpeg会将与-report类似的内容写入stderr

// This line over and over:
frame= 8237 fps= 20 q=-1.0 Lsize=   25192kB time=00:06:51.80 bitrate= 501.2kbits/s speed=1.02x

我没有考虑到这一点,完全无视stderr,直到它备份了流并且流程卡住了:(

由于对stderr的记录遵循恒定速率(不依赖于比特率,帧速率等),因此在我的情况下大约在6:00左右,进程总是卡在一起。

解决方案:不要忘记阅读或重定向stderr !!