I'm writing a tutorial involving ffmpeg - could you please fact-check?
Hi! I'm writing an article detailing streaming to Twitch from a web camera, using ffmpeg. I tried to explain the ffmpeg command-line I'm using, however, as I don't know ffmpeg that well, my understanding of the command-line itself is limited. Could you please see if there's anything obviously (or non-obviously) wrong with the following text?
First, let's cover a simple streaming case - no sound involved, just video. We have a USB camera (available as /dev/video0), and we have a Twitch RTMP URL, which we should send our stream to. A basic ffmpeg command-line that does the job of is as follows:
ffmpeg -f v4l2 -s "$INRES" -r "$FPS" -i /dev/video0 -vcodec h264_omx -g $GOP -keyint_min $FPS -b:v $CBR -minrate "100k" -maxrate $CBR -pix_fmt yuv420p -bufsize "500k" -preset "veryfast" -f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"
That's a lot of parameters for a single command! Let's go through it so that you understand what's going on. First, here's the breakdown of all parts this command-line consists of:
ffmpeg {global options} -f {input type} {input options} -i {input} {codec} {codec options} -f {output type} {output}
We're only using one global option - "-hide-banner", which tells ffmpeg not to print its version information on start. Our webcam is /dev/video0 - in your case, it might end with another number (say, you're using a laptop with a webcam). To capture video from the webcam, we're using the Video4Linux system and the corresponding ffmpeg plugin called "v4l2", and we tell it the resolution to use and FPS (frames per second) that we want. Twitch requires that we compress our video as H.264 - this would usually be a CPU-intensive task, but Raspberry Pi has hardware H264 encoding support. We can get that support if we use the h264_omx ffmpeg plugin.
Even though compression means we don't send full frames all the time, we still need to send a full frame once in a while - packets can get lost and glitches can happen. A frame sent for the image synchronization purpose is called a keyframe - the "-g" parameter tells how often keyframes will be made (say, $GOP is double the $FPS, then a keyframe will be formed each 2 seconds), and the "-keyint_min" parameter allows additional keyframes to appear if necessary (say, the video changes rapidly) This explains the "-g $GOP -keyint_min $FPS" part. Now, what about "-b:v $CBR -minrate "100k" -maxrate $CBR"? These are the h264_omx codec parameters, and they restrict the bitrate of the resulting stream - bitrate is, in our case, how much data we're sending per second.
... [a long not-ffmpeg-related explanation of what bitrates mean and why we need a constant bitrate for Twitch]
After all the bitrate-related parameters, we have parameters defining the color encoding scheme (Twitch requires the YUV420 scheme) and buffer size - the buffer in question is the one ffmpeg uses to check whether bitrate is constant enough; setting your "bufsize" to the same value as your bitrate is a good starting point. The last parameter is the compression quality - as in, how much time should be spent on compression. The "fast"-er the preset, the less time is spent compressing and the more bandwidth will be taken by your video - you have options like "veryslow", "slow", "medium", "fast" and "veryfast", and some more in between.
I'm sorry if this request is taken as asking for too big of a favour (full disclosure: I'm getting paid to write this). I just really, really would hate to explain things in a wrong way and push it onto the readers, and I hope you can help make a ffmpeg streaming tutorial that explains things well (which, in my experience, is a rare occurence). Cheers! Arsenijs
On 2018-02-26 22:53, Pičugins Arsenijs wrote:
Hi! I'm writing an article detailing streaming to Twitch from a web camera, using ffmpeg. I tried to explain the ffmpeg command-line I'm using, however, as I don't know ffmpeg that well, my understanding of the command-line itself is limited. Could you please see if there's anything obviously (or non-obviously) wrong with the following text?
First, let's cover a simple streaming case - no sound involved, just video. We have a USB camera (available as /dev/video0), and we have a Twitch RTMP URL, which we should send our stream to. A basic ffmpeg command-line that does the job of is as follows:
ffmpeg -f v4l2 -s "$INRES" -r "$FPS" -i /dev/video0 -vcodec h264_omx -g $GOP -keyint_min $FPS -b:v $CBR -minrate "100k" -maxrate $CBR -pix_fmt yuv420p -bufsize "500k" -preset "veryfast" -f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"
That's a lot of parameters for a single command! Let's go through it so that you understand what's going on. First, here's the breakdown of all parts this command-line consists of:
ffmpeg {global options} -f {input type} {input options} -i {input} {codec} {codec options} -f {output type} {output}
We're only using one global option - "-hide-banner", which tells ffmpeg not to print its version information on start. Our webcam is /dev/video0 - in your case, it might end with another number (say, you're using a laptop with a webcam). To capture video from the webcam, we're using the Video4Linux system and the corresponding ffmpeg plugin called "v4l2", and we tell it the resolution to use and FPS (frames per second) that we want. Twitch requires that we compress our video as H.264 - this would usually be a CPU-intensive task, but Raspberry Pi has hardware H264 encoding support. We can get that support if we use the h264_omx ffmpeg plugin.
Even though compression means we don't send full frames all the time, we still need to send a full frame once in a while - packets can get lost and glitches can happen. A frame sent for the image synchronization purpose is called a keyframe - the "-g" parameter tells how often keyframes will be made (say, $GOP is double the $FPS, then a keyframe will be formed each 2 seconds), and the "-keyint_min" parameter allows additional keyframes to appear if necessary (say, the video changes rapidly) This explains the "-g $GOP -keyint_min $FPS" part. Now, what about "-b:v $CBR -minrate "100k" -maxrate $CBR"? These are the h264_omx codec parameters, and they restrict the bitrate of the resulting stream - bitrate is, in our case, how much data we're sending per second.
... [a long not-ffmpeg-related explanation of what bitrates mean and why we need a constant bitrate for Twitch]
After all the bitrate-related parameters, we have parameters defining the color encoding scheme (Twitch requires the YUV420 scheme) and buffer size - the buffer in question is the one ffmpeg uses to check whether bitrate is constant enough; setting your "bufsize" to the same value as your bitrate is a good starting point. The last parameter is the compression quality - as in, how much time should be spent on compression. The "fast"-er the preset, the less time is spent compressing and the more bandwidth will be taken by your video - you have options like "veryslow", "slow", "medium", "fast" and "veryfast", and some more in between. I'm sorry if this request is taken as asking for too big of a favour (full disclosure: I'm getting paid to write this). I just really, really would hate to explain things in a wrong way and push it onto the readers, and I hope you can help make a ffmpeg streaming tutorial that explains things well (which, in my experience, is a rare occurence).
Cheers! Arsenijs _______________________________________________ ffmpeg-user mailing list ffmpeg-user@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-user
To unsubscribe, visit link above, or email ffmpeg-user-request@ffmpeg.org with subject "unsubscribe".
I have never used ffmpeg for that purpose, so I can't comment much about the technical correctness. However, I can give some comments about more general topics. 1. Have you used this command, and does it in fact work? I assume that you have, but you didn't say so in your introduction. 2. You use environment variables like $INRES, $FPS, $CBR, but I don't see any text that explains they are variables, not literal parameters to the command. Nor do I see an explanation of what values they should be set to. Nor do I see an explanation of why these values, but not others, are provided as environment variables instead of literally. I imagine it's a good idea to make them variables, but it would help the article to explain why. I hope this helps. Good luck with the article! -- --Jim DeLaHunt, jdlh@jdlh.com http://blog.jdlh.com/ (http://jdlh.com/) multilingual websites consultant 355-1027 Davie St, Vancouver BC V6E 4L2, Canada Canada mobile +1-604-376-8953
2018-02-27 7:53 GMT+01:00 Pičugins Arsenijs <crimier@yandex.ru>:
ffmpeg -f v4l2 -s "$INRES" -r "$FPS" -i /dev/video0 -vcodec h264_omx -g $GOP -keyint_min $FPS -b:v $CBR -minrate "100k" -maxrate $CBR -pix_fmt yuv420p -bufsize "500k" -preset "veryfast" -f flv "rtmp://$SERVER.twitch.tv/app/$STREAM_KEY"
"-r" looks wrong to me. Carl Eugen
participants (3)
-
Carl Eugen Hoyos -
Jim DeLaHunt -
Pičugins Arsenijs