To stream a video file to YouTube Live at a constant frame rate, have FFmpeg read the file at real-time speed, convert it to the output cadence you choose, encode it, and send it to the live ingest address from YouTube Studio. The output frame rate, resolution, bitrate and keyframe interval need to suit both the source and your upstream connection; a 30 fps example is only a starting point.
This is a live-ingest workflow, not a recipe for making an ordinary YouTube upload. YouTube’s live encoder guidance describes settings for a broadcast, while its upload guidance says to encode at the frame rate at which the video was recorded. Choose the instructions for the destination you are actually preparing.
What constant frame rate means for a live feed
A constant-frame-rate (CFR) output has frames spaced at a regular cadence over time. At 30 fps, for example, the encoder aims to produce 30 frames for each second of output. A file with variable frame rate (VFR) may instead have uneven spacing between frames, even if a media player reports an average near 30 fps.
That difference matters when a prerecorded file is sent through a live ingest path. YouTube receives a continuing encoded feed rather than a file it can inspect and process at its own pace. A stable output cadence makes the timing explicit, but it does not repair every source problem: judder, duplicate frames, missing source frames or uneven audio can still be visible or audible after conversion.
FFmpeg can create a new cadence while re-encoding. Its fps video filter selects frames for the requested output rate, dropping or duplicating as needed. Merely copying a source video stream with -c:v copy does not create a new cadence, because the frames are not decoded and encoded again. If CFR is a requirement, use an encoding path and verify the result rather than relying on a file’s displayed average frame rate.
The live feed also has other timing constraints. In particular, the GOP (group of pictures) size controls how many encoded pictures sit between keyframes. A keyframe interval is a period of time, so the FPS and GOP length must be considered together. A GOP of 60 frames lasts two seconds at 30 fps, but not at every output rate.
Choose an output frame rate
Start with the material and the way it will be watched. If the source is a 25 fps recording, a 25 fps live output may preserve its motion more naturally than converting it to 30 fps. If your source is 60 fps and the channel needs to retain smoother motion, an output of 60 fps may be appropriate, provided the encoder, resolution, bitrate and stable upstream bandwidth can support it. You are choosing a live output cadence, not declaring one rate best for every channel.
Conversion can alter motion. Moving from 25 to 30 fps means FFmpeg must add frames or otherwise map the source timing to the new cadence; moving from 30 to 25 means some frames may be dropped. The result may be technically constant-rate without looking better. For a fixed devotional visual, a simple animation, or a still-heavy ambience loop, fewer frames may be sufficient. For a camera pan, dance performance or gameplay, motion detail can be more noticeable, so inspect representative movement before settling on a setting.
YouTube’s live encoder settings list frame rates up to 60 fps. That is a platform capability, not a reason to convert every file to 60 fps. YouTube’s separate upload page lists common upload rates and tells creators to use the recording rate; that upload instruction should not be substituted for a live-output choice. Compare the live and file workflows in the table below, then use the matching official guidance: YouTube’s live encoder settings and YouTube’s upload encoding recommendations.
| Decision | Prerecorded file sent as a live feed | Ordinary video upload |
|---|---|---|
| Destination | YouTube Live ingest | YouTube upload processing |
| Timing | Read and transmit at real-time speed | Create a file offline, then upload it |
| Frame-rate policy | Pick the live output cadence and convert if needed | YouTube advises matching the recording frame rate |
| Relevant controls | Stream address and key, encoder, GOP interval, sustained bitrate | File/container encoding and upload recommendations |
If you are building a long-running channel around an existing file, this distinction also helps when choosing a broader workflow. A 24/7 ambience stream built around a looping visual has different motion demands from a classroom lesson or a high-motion recording. The subject does not change YouTube’s ingest requirements, but it can change what frame rate and image quality are sensible for your viewers.
Use FFmpeg to target a fixed cadence
For a live file playout, -re tells FFmpeg to read the input at its native playback speed rather than consuming it as quickly as the computer can process it. To repeat a file indefinitely, -stream_loop -1 loops the input. Omit that option if you want the feed to end when the file ends. Before using either option, decide how a loop should behave at the join: if the end and beginning do not meet cleanly, viewers will see or hear the transition on every repeat.
The following is an adaptable example that targets 30 fps. It is illustrative, not a tested command for every build, source or channel. Replace the ingest placeholder with the URL and stream key supplied in YouTube Studio; do not share or publish the key.
ffmpeg -re -stream_loop -1 -i input.mp4 \\
-vf "fps=30" \\
-c:v libx264 -preset veryfast -pix_fmt yuv420p \\
-b:v 10M -maxrate 10M -bufsize 20M \\
-g 60 -keyint_min 60 -sc_threshold 0 \\
-c:a aac -b:a 128k -ar 44100 \\
-f flv "rtmp://SERVER/STREAM_KEY"
The filter -vf "fps=30" requests a 30 fps output cadence. To target another rate, change the filter and recalculate the GOP length for the intended interval. FFmpeg also has an output -r option that can duplicate or drop frames before encoding. The -fps_mode option may be useful when choosing how output timestamps are handled, but it does not make stream copy a frame-rate conversion. Consult the FFmpeg documentation for the options available in your installed version and how they behave in context.
Avoid casually adding -r before a normal input filename as though it were a general VFR repair. Input -r has a different purpose: it ignores stored timestamps and generates timestamps at the specified rate, a use intended for raw formats. For a typical video file, use a deliberate output conversion and retain sensible source timestamps. If you need a file for upload rather than a live feed, remove real-time reading, choose a file container such as MP4 and use the upload guidance instead. A file workflow may also use -movflags +faststart for progressive download, but that is not a live-ingest setting.
Check the FFmpeg build before relying on the command. The example names libx264; that encoder is not present in every FFmpeg build. If FFmpeg reports that the encoder is unavailable, use a build that includes it or select an encoder supported by your setup and accepted by YouTube’s current live guidance. Do not swap an encoder option without checking the codec and rate-control settings it supports.
For practical notes on running FFmpeg for long periods, the guide to logging FFmpeg output on a VPS explains why keeping error output matters when a stream runs unattended. Logs do not prove that viewers are receiving a healthy picture, but they can help distinguish a failed input, an unavailable encoder or a broken ingest connection.
Set the H.264 output for YouTube Live
The example uses H.264 video and AAC audio in an FLV container sent over RTMP. YouTube’s current live guidance also lists RTMPS and other video codecs, but H.264 is a straightforward example profile. Confirm the ingest protocol and accepted settings in the YouTube Studio workflow you are using. The stream URL and key are credentials for the broadcast; keep them private and regenerate a key through YouTube’s controls if it is exposed.
YouTube recommends a two-second keyframe frequency for live encoding and says not to exceed four seconds. At 30 fps, -g 60 sets a 60-picture GOP, which spans two seconds. If you choose 25 fps, 50 frames span two seconds; at 60 fps, 120 frames do. These relationships explain why copying the example’s -g 60 unchanged while changing the output to 25 or 60 fps changes the interval. -keyint_min and -sc_threshold 0 are included to keep GOP behaviour predictable in this example; check encoder documentation and actual output if you alter them.
The command uses a bitrate target and maximum rate, plus a buffer-size value. These are encoder controls; they do not guarantee a perfectly constant instantaneous bitrate. YouTube’s live guidance calls for CBR for RTMP/RTMPS, so configure a suitable constant-bitrate rate-control mode in the encoder you use and test the stream. The particular way to request CBR can depend on the selected encoder and FFmpeg build. -b:v, -maxrate and -bufsize alone should not be treated as proof that your output is CBR.
For H.264, YouTube’s listed recommended bitrate depends on both resolution and frame rate. Its current page lists 10 Mbps for 1080p30 and 17 Mbps for 1080p60, and 8 Mbps for 720p30. These are YouTube recommendations for live ingest, not guarantees that your connection can sustain those rates or that they are the right choice for every source. Check the current live bitrate and encoder table before a broadcast, since settings can change.
Adapt resolution and bitrate to the source
Do not upscale a small or soft source simply to match a larger output number. Choose an output resolution that fits the detail in the file and the quality you want to deliver. If a file is 720p, encoding it at 1080p cannot restore detail that was never recorded; it can, however, require more bitrate and processing. Conversely, scaling a high-resolution source down may make a lower-bitrate live stream more manageable, at the cost of fine detail.
The sample command does not set a scaling filter, so it keeps the input dimensions. If you need a specific output size, choose a scale filter deliberately, preserve the aspect ratio, and decide how to handle padding or cropping rather than stretching the picture. Check both the source’s dimensions and its orientation. A portrait clip pushed into a landscape output without a plan can look cramped or distorted.
Bitrate is a trade-off among resolution, frame rate, codec, scene complexity and available upstream capacity. A static image with gentle motion may compress more easily than leaves moving in wind or a camera moving across a detailed crowd. The same target rate can therefore produce different visible results. YouTube’s listed recommendations are useful starting points for an ingest profile, but do not treat them as a measurement of your own file or connection.
In the example, -b:v 10M is tied to the illustrative 1080p30 H.264 live setting from YouTube’s guidance; change it when your chosen resolution or frame rate differs. The audio options request AAC at 128 kbps and 44.1 kHz. They are example values, not a promise that every input’s audio will be suitable. Listen for clipping, silence and loop discontinuities, and make sure the audio is present and correctly mapped. If the file has no audio stream, or has multiple tracks, the command may need adjustment.
A fireplace or candle channel with a black background illustrates why resolution should follow the actual picture rather than a default. A mostly dark frame with a small flame has different detail from a full-screen landscape, but still needs a clean, correctly sized output and a bitrate test. Base the choice on a preview of the encoded result, not on the assumption that a lower-detail image removes every quality concern.
Check bandwidth and stream output
Treat the target video bitrate as part of the sustained upstream load, not as a short speed-test result. Audio, protocol overhead and normal variation in the connection add to what must be carried. If your upstream capacity regularly falls near the configured stream rate, the feed may buffer, drop frames or lose connection when conditions change. A stable connection with margin is more useful than a brief peak reading, particularly for a channel intended to run overnight.
Before the broadcast, test with a representative section of the file: include the fastest motion, the busiest image, any fades, and the point where the file loops. YouTube recommends testing before going live with similar audio and movement, then watching stream health during the event. Check that the preview starts, that movement looks even, that audio stays in sync, and that the stream health indicators remain acceptable. For troubleshooting symptoms around timing and keyframes, consult YouTube’s live streaming error messages.
FFmpeg’s own output is another useful signal. Read the console or retain a log so that you can see whether frames are being encoded, the output rate is near the target over time, and errors appear at the input or output. A running process is not enough to prove a successful live broadcast: confirm the picture at YouTube’s preview and, where practical, on a separate viewer connection. If the stream health deteriorates, check the ingest settings and connection before changing several encoding options at once.
For a channel that must continue while your own computer is off, the repeated work of keeping a file playing and responding to a dropped feed is a specific operational burden. StreamNeo lets you upload a video once, add your YouTube stream key and have the broadcast run without your computer, with monitoring and automatic restarts if it drops. It is YouTube-only, so this does not replace choosing an appropriate source, output frame rate or ingest profile.
If the command is part of a more technical self-managed workflow, compare it with a GStreamer setup on an Ubuntu VPS; the relevant choice depends on whether you want to manage a live encoding process yourself. Whichever route you use, keep the key private, test the exact file and settings, and keep a way to check stream health after the channel starts.
Before committing, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.
FAQ
How do I stream a video file to YouTube Live with FFmpeg?
Use -re to read the file at real-time speed, encode to a live-compatible format and send the output to the URL and key from YouTube Studio. Add -stream_loop -1 only if you want the file to repeat, and test the resulting feed before relying on it.
How do I make an FFmpeg video constant frame rate?
Use a frame-rate conversion during encoding, such as -vf "fps=30" for a 30 fps target, or an appropriate output frame-rate option. FFmpeg may drop or duplicate frames to reach the requested cadence; -c:v copy does not perform that conversion.
Why does YouTube complain about frame rate or keyframe interval?
Check that the output cadence is the one you intended and that the GOP length gives the right interval at that cadence. YouTube recommends a two-second keyframe interval and says not to exceed four seconds; for example, 60 frames at 30 fps span two seconds.
Should I use the same FFmpeg settings for an upload?
No. Live ingest settings describe a real-time broadcast, including its protocol, keyframe cadence and sustained bitrate. YouTube’s upload guidance says to encode and upload at the recording frame rate, so use the current upload recommendations when making a normal video file.