How to generate an RTMP test stream using ffmpeg command? - ffmpeg

I would like to test my streaming infrastructure by generating an RTMP test video with a timestamp. This could look like that screen. The image doesn't matter. I'm after the working stream generated on-the-fly and timestamp only. I intend to use the ffmpeg tool for that purpose. The command could look something like
$ ffmpeg -i image.png \
-vf drawtext="fontfile=/Library/Fonts/Arial.ttf: \
timecode='00\:00\:00\:00': r=1: fontcolor=white: \
fontsize=24: box=1: boxcolor=black#0.5: \
boxborderw=5: x=(w-text_w)/2: y=(h-text_h)/2" \
-f flv rtmp://localhost/live/test
I do run locally a streaming server based on NGINX and its RTMP module.
However, the above command gives me the following error:
Input #0, png_pipe, from 'image.png':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: png, rgb24(pc), 768x576 [SAR 7874:7874 DAR 4:3], 25 tbr, 25 tbn, 25 tbc
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> flv1 (flv))
Press [q] to stop, [?] for help
[Parsed_drawtext_0 # 0x7fb78450ece0] Using non-standard frame rate 1/1
Output #0, flv, to 'rtmp://localhost/live/test':
Metadata:
encoder : Lavf57.71.100
Stream #0:0: Video: flv1 (flv) ([2][0][0][0] / 0x0002), yuv420p, 768x576 [SAR 1:1 DAR 4:3], q=2-31, 200 kb/s, 25 fps, 1k tbn, 25 tbc
Metadata:
encoder : Lavc57.89.100 flv
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
[flv # 0x7fb785812a00] Failed to update header with correct duration.
[flv # 0x7fb785812a00] Failed to update header with correct filesize.
frame= 1 fps=0.0 q=8.6 Lsize= 50kB time=00:00:00.00 bitrate=406016.0kbits/s speed=0.019x
video:49kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.451271%
The streaming server operates as expected. The problem is with the command. Would anyone be able to help me?

ffmpeg has testsrc you can use as a test source input stream:
ffmpeg -r 30 -f lavfi -i testsrc -vf scale=1280:960 -vcodec libx264 -profile:v baseline -pix_fmt yuv420p -f flv rtmp://localhost/live/test
-r, scaling, profile, etc are just an example and can be ommited/played with. The point is using -i testsrc

Related

ffmpeg convert rtmp audio/video stream to icecast2 audio/video stream

I've been using this command to convert my public rtmp audio/video stream to a local mp3 audio icecast2 stream, but I have been unable to do the same for both video and audio.
[Audio Only] (This works fine)
ffmpeg -re -i rtmp://162.142.xx.xxx:xxx/stream -vn -codec:a libmp3lame -b:a 128k -f mp3 -content_type audio/mpeg icecast://source:password#192.168.1.xxx:80/live
I've tried to re-write in order to support video, but I keep hitting dead ends
[Audio & Video Attempt] (this does not work)
ffmpeg -re -i rtmp://162.142.xx.xxx:xxx/stream -codec:v -f mpeg4 -b:v -f mpeg4 -content_type video/mpeg4 icecast://source:password#192.168.1.xxx:80/live
When I run this command, it gives me the error below asking for a suitable format.
$ ffmpeg -re -i rtmp://162.142.xx.xxx:xxx/stream -codec:v -f mpeg4 -b:v -f mpeg4 -content_type video/mpeg4 icecast://source:password#192.168.1.xxx:80/live
[h264 # 0x5598ffbb8980] co located POCs unavailable
[h264 # 0x5598ffbb8980] mmco: unref short failure
Input #0, flv, from 'rtmp://162.142.xx.xxx:xxx/stream':
Metadata:
|RtmpSampleAccess: true
Server : NGINX RTMP (github.com/sergey-dryabzhinsky/nginx-rtmp-module)
displayWidth : 1280
displayHeight : 720
fps : 48
videokeyframe_frequency: 0
profile :
level :
Duration: 00:00:00.00, start: 28117.779000, bitrate: N/A
Stream #0:0: Audio: aac (LC), 48000 Hz, stereo, fltp, 327 kb/s
Stream #0:1: Video: h264 (High), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 2560 kb/s, 48 fps, 48 tbr, 1k tbn
[NULL # 0x5598ffb8bec0] Unable to find a suitable output format for 'mpeg4'
mpeg4: Invalid argument
I am positive that icecast2 can support video streams, however on the few occasions that I was able to actively stream successfully to it, it only showed an empty video embed.
I've re-written the command for AV multiple times while referencing ffmpeg documentation, however my above attempt seems to be the closest (concept-wise) that I have gotten.
What flags/formatting might I be missing which are causing the stream not to work?

Can I test funcion of nvidia decoder (nvdec/cuvid) on generated ffmpeg video?

goal: In my script I try to check if nvdec on my graphics card is available/functional.
I don't have any source video (H.264 / H.265) to use as input at this time intentionally, so I want to generate it.
It is also not necessary to use an encoder, because I do not need the output file.
I'm testing the exit code of command ffmpeg ($?).
I use nvidia-smi for check dec/enc load.
My attempt:
ffmpeg -y -hwaccel cuda -hwaccel_output_format cuda -c:v h264_cuvid -f lavfi -i testsrc="duration=5:size=1920x1080:rate=25" -c:v copy test.ts
output of my commands:
Input #0, lavfi, from 'testsrc=duration=5:size=1920x1080:rate=25':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264, rgb24, 1920x1080 [SAR 1:1 DAR 16:9], 25 tbn
Stream mapping:
Stream #0:0 -> #0:0 (h264 (h264_cuvid) -> wrapped_avframe (native))
Press [q] to stop, [?] for help
No information about the input framerate is available. Falling back to a default value of 25fps for output stream #0:0. Use the -r option if you want a different framerate.
Output #0, null, to 'pipe:':
Metadata:
encoder : Lavf58.65.101
Stream #0:0: Video: wrapped_avframe, rgb24, 1920x1080 [SAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 fps, 25 tbn
Metadata:
encoder : Lavc58.119.100 wrapped_avframe
frame= 0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed= 0x
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
I triead add -t 5 before test.ts but nothing changed.
Output ts file has zero size.
If I debug the command, I expect to add it to the end "-f null - 2>/dev/null". Output file is only for debug purposes.
Thank you.
You need to first generate the video with a H.264 encoder and then try decoding it separately afterwards.
ffmpeg -y -f lavfi -i "testsrc2=duration=5:size=1920x1080:rate=25" -c:v h264 test.ts
ffmpeg -c:v h264_cuvid -i test.ts -f null -

ffmpeg can't find codec to cut 10 seconds movie

I tried to cut 10 seconds from movie and convert to MP4. But sometimes I have a error like below:
Duration: 00:08:52.40, start: 0.000000, bitrate: 1126 kb/s
Stream #0:0: Audio: wmav2 (a[1][0][0] / 0x0161), 44100 Hz, stereo, fltp, 96 kb/s
Stream #0:1: Video: wmv3 (Main) (WMV3 / 0x33564D57), yuv420p, 640x480, 1000 kb/s, SAR 1:1 DAR 4:3, 29.97 tbr, 1k tbn, 1k tbc
[mp4 # 0x5614bbea1300] Could not find tag for codec wmv3 in stream #0, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argumentStream mapping:
What does this error mean? Should I install some extra codec?
My exec line looks like:
ffmpeg -i input.wmv -ss 00:00:00 -to 0 -c copy 0:00:10 output.mp4
Could not find tag for codec wmv3 in stream #0, codec not currently supported in container
You're trmiing the file without recompressing, and ffmpeg does not write Windows Media 9 streams into MP4, so either recompress:
ffmpeg -i input.wmv -ss 00:00:00 -to 00:00:10 output.mp4
or output to a different container, like Matroska:
ffmpeg -i input.wmv -ss 00:00:00 -to 00:00:10 -c copy output.mkv

FFMPEG: how to wrap h264 stream into FLV container?

What I want is straightforward: wrap H.264 video stream into a FLV container. However, ffmpeg just decode the input stream and pack raw video stream into FLV. The details are described below:
The input stream is captured from a hardware-encoder video camera, and the FLV will be sent to some video server. Firstly I used following command:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -f flv "rtmp://some.website.com/receive/path"
However, the resultant stream is suspicious. The watching side don't get any H.264 thing. Then I made a test by writing output to local files.
1: Read raw stream, encode by h264_omx, write to FLV file:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video0 -codec h264_omx -f flv raw_input_h264_omx.flv
......
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 194017.870905, bitrate: 18432 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 320x240, 18432 kb/s, 15 fps, 15 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (h264_omx))
......
2: Read H264 stream, write to FLV file:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -f flv h264_input.flv
......
Input #0, video4linux2,v4l2, from '/dev/video1':
Duration: N/A, start: 194610.307096, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 320x240, 15 fps, 15 tbr, 1000k tbn, 2000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> flv1 (flv))
......
Then read the two files correspondingly:
$ ffmpeg -i raw_input_h264_omx.flv
......
Stream #0:0: Video: h264 (High), yuv420p(progressive), 320x240, 200 kb/s, 15 fps, 15 tbr, 1k tbn
$ ffmpeg -i h264_input.flv
......
Stream #0:0: Video: flv1, yuv420p, 320x240, 200 kb/s, 15 fps, 15 tbr, 1k tbn
It is clear when I give a H.264 stream, ffmpeg firstly decodes it, then pack the raw video into FLV. How to avoid that happen, and have the H.264 stream packed directly?
Supplement: I will eventually pushing multiple video streams, so don't ask me to allow ffmpeg's silent decoding, and encode the stream again.
Unless told otherwise, ffmpeg will transcode streams.
Use
ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -c copy -f flv "rtmp://website/receive/path"

What does the fps mean in the ffmpeg output?

I am streaming a static png file with ffmpeg and it uses basically all my CPU. It seems a bit greedy to me, and even though I limited the fps on the input and output size, I am seeing a huge fps printed out.
w:\ffmpeg\bin>ffmpeg.exe -loop 1 -framerate 1 -i w:\colorbar2.png -r 10 -vcodec libx264 -pix_fmt yuv420p -r 10 -f mpegts udp://127.0.0.1:10001?pkt_size=1316
ffmpeg version N-68778-g5c7227b Copyright (c) 2000-2014 the FFmpeg developers
built on Dec 29 2014 22:12:54 with gcc 4.9.2 (GCC)
Input #0, png_pipe, from 'w:\colorbar2.png':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: png, pal8, 320x240 [SAR 3779:3779 DAR 4:3], 1 fps, 1 tbr, 1 tbn, 1 tbc
[libx264 # 00000000002fb320] using SAR=1/1
[libx264 # 00000000002fb320] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
[libx264 # 00000000002fb320] profile High, level 1.2
Output #0, mpegts, to 'udp://127.0.0.1:10001?pkt_size=1316':
Metadata:
encoder : Lavf56.16.102
Stream #0:0: Video: h264 (libx264), yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=-1--1, 10 fps, 90k tbn, 10 tbc
Metadata:
encoder : Lavc56.19.100 libx264
Stream mapping:
Stream #0:0 -> #0:0 (png (native) -> h264 (libx264))
Press [q] to stop, [?] for help
frame=561310 fps=579 q=25.0 size= 144960kB time=15:35:25.80 bitrate= 21.2kbits/s dup=505179 drop=0
As you can see the frame counter goes up quickly and fps=579 is reported on the last line. I am confused now, what does that fps mean, if above the low frame per secs are also mentioned (output 10fps, input 1 fps)
What am I doing wrong and how could I reduce CPU load more given that it's a static file that is being streamed.
Thanks!
ffmpeg attempts to decode and encode as fast as it can. Just because you set the output to be 10 frames per second does not mean that it will (de|en)code realtime at 10 frames per second.
Try the -re input option. From the ffmpeg cli-tool documentation:
Read input at native frame rate. Mainly used to simulate a grab device
or live input stream (e.g. when reading from a file). Should not be
used with actual grab devices or live input streams (where it can
cause packet loss). By default ffmpeg attempts to read the input(s)
as fast as possible. This option will slow down the reading of the
input(s) to the native frame rate of the input(s). It is useful for
real-time output (e.g. live streaming).
Example:
ffmpeg.exe -re -loop 1 -framerate 10 -i w:\colorbar2.png -c:v libx264 \
-tune stillimage -pix_fmt yuv420p -f mpegts udp://127.0.0.1:10001?pkt_size=1316

Resources