我知道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停止工作。然后它闲置了几分钟,我不得不杀死这个过程。
事实证明这就是我处理这个过程的方式。
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
!!