To send GStreamer video and audio to YouTube Live, encode the video as H.264 and the audio as AAC, parse the H.264 into AVC format, connect both streams to flvmux, then send the resulting FLV through an RTMP(S)-capable sink. YouTube recommends RTMPS, constant bitrate (CBR), and keyframes about every two seconds; the exact elements and caps you can use depend on your local GStreamer installation.
The muxer does not encode either branch: it packages compatible encoded streams into FLV. Treat the pipeline below as a shape to adapt and test, not a universal command. Check that your sources negotiate the intended formats, that the required plugins are installed, and that the sink accepts the ingest address and key shown in YouTube Live Control Room.
Check YouTube’s ingest requirements first
Start with YouTube’s current encoder settings and bitrate guidance. It lists H.264 video and AAC audio for this workflow, recommends RTMPS, and specifies CBR for RTMP/RTMPS encoder settings. Choose a resolution and frame rate your source and encoder can sustain, then use the corresponding bitrate guidance rather than treating one bitrate as suitable for every stream.
For example, YouTube’s current table recommends 14 Mbps for H.264 at 1080p30, 17 Mbps at 1080p60, and 8 Mbps at 720p30. These are YouTube recommendations, not promises about picture quality or minimums that make a stream work. Consult the full table for other combinations, and leave bandwidth headroom for audio and network overhead.
For audio, YouTube recommends 44.1 kHz for stereo and 48 kHz for 5.1 surround sound. Its settings guidance lists 128 Kbps for stereo and 384 Kbps for 5.1; it also says that 5.1 over RTMP/RTMPS is supported only with AAC. Match the channel layout to your actual programme. A stereo bhajan or lofi channel should not be configured as 5.1 simply because an encoder offers that option.
YouTube’s guidance states: “Keyframe frequency: Recommended 2 seconds Do not exceed 4 seconds”. Keep that target in mind when setting the video encoder, but do not confuse the encoder’s frame-count property with a number of seconds. We will convert between them below.
Build the video source and H.264 branch
The video side starts with a source that produces usable raw video. That might be a camera, a test source, a capture device, or a decoded file; the source element and its output caps are specific to your machine and content. A common branch shape is:
video source . videoconvert . x264enc ... . h264parse . video/x-h264,stream-format=avc . queue . mux.
videoconvert can adapt raw pixel formats between the source and encoder. x264enc encodes raw video as H.264; it does not create the FLV container. GStreamer’s x264enc reference describes its supported properties and output. If you use a hardware encoder instead, check that it produces compatible H.264 caps and offers the rate-control and keyframe controls you need.
The ellipsis is deliberate. Source name, frame rate, dimensions, bitrate, and encoder properties cannot safely be copied from a generic template. Inspect available elements and their properties with the GStreamer tools installed on your system, and check the actual negotiated caps in a test run. The GStreamer element catalogue can help identify which plugin collection documents a given element, but a catalogue entry does not prove that your particular build includes it.
Choose output dimensions and frame rate to match your source and the YouTube bitrate row you intend to follow. A pipeline that asks a modest camera for a higher frame rate cannot create genuine additional captured motion; likewise, setting a high bitrate does not repair a source that is already soft or unstable. For a file loop, confirm that the decoder emits the expected raw format and that a repeat or playlist mechanism handles end-of-file as intended.
Build the audio source and AAC branch
The audio path needs raw audio from a source or decoded file, conversion and resampling where needed, an AAC encoder, then a queue before the muxer. Its shape is:
audio source . audioconvert . audioresample . AAC encoder . queue . mux.
audioconvert handles compatible sample-format and channel-layout conversion. audioresample can adapt the sample rate to the rate selected for the programme. The AAC encoder turns raw audio into AAC; flvmux only receives the encoded branch. If you are following a stereo YouTube configuration, check that the negotiated output is actually stereo at the intended rate, rather than assuming the source and encoder agree.
For one documented GStreamer example, voaacenc is an AAC encoder in the Bad Plug-ins package. Its element reference lists input caps including common rates such as 44.1 kHz and 48 kHz. That makes it a possible local choice, not a guarantee that it is installed or that every platform exposes the same encoder. Check its properties and the resulting encoded caps before connecting it to the muxer.
If the audio is silent, investigate the source and branch before changing the muxer. Check that the source is live or decoding, that conversion and resampling negotiate, and that the AAC encoder emits data. A useful diagnostic is to test the branch independently with an appropriate local sink or inspect negotiated caps and bus messages. For other common delivery symptoms, the YouTube RTMP audio troubleshooting guide may help you separate an audio problem from an ingest problem.
Parse H.264 for muxing
The h264parse element sits after the video encoder and before flvmux. Its job is to parse and, where requested, format the H.264 stream; it is not an encoder. GStreamer documents that the parser can output AVC stream format. That matters because the H.264 sink template documented for flvmux expects AVC, so a valid H.264 stream in a different format can still fail caps negotiation at this point.
The video tail can make that requirement explicit:
x264enc ... . h264parse . video/x-h264,stream-format=avc . queue . mux.
The caps filter asks negotiation for AVC-formatted H.264. It does not transform an incompatible encoder output on its own; the parser must be present and able to provide the requested format. See the h264parse documentation for its output formats and properties, and the flvmux pad templates for the muxer’s accepted caps.
If flvmux rejects the video branch, inspect the caps immediately before the muxer rather than changing unrelated settings at random. Confirm that the parser is installed, that it is linked after the H.264 encoder, and that its negotiated output says stream-format=avc. Also inspect timestamps and stream presence: caps alone do not establish that buffers arrive with useful timing.
The parser has a config-interval property that controls insertion of SPS/PPS parameter sets. In particular, -1 means insertion with every IDR frame. That is a behaviour control, not a universal fix for rejected caps or failed ingest. Set it only when your stream’s needs and tests justify it; first establish a working baseline with correct format negotiation.
Link both branches to flvmux
Once both branches produce encoded data with suitable caps, link their queues to named request pads on one flvmux element. A schematic pipeline is:
video source . videoconvert . x264enc ... . h264parse . video/x-h264,stream-format=avc . queue . mux.
audio source . audioconvert . audioresample . AAC encoder . queue . mux.
flvmux name=mux streamable=true . RTMP(S)-capable sink
The dot after mux denotes a reference to the named element. The actual command-line syntax for requesting and linking pads depends on how you construct the pipeline. The key point is that each branch reaches the muxer on a pad whose caps the muxer accepts. Consult the flvmux element reference for its pad templates and properties.
flvmux packages the encoded H.264 and AAC as FLV output. Its streamable=true property omits indexes and duration for streaming-friendly output. It does not resize video, set the encoder bitrate, make audio AAC, convert H.264 to AVC by itself, or send anything to YouTube. Those jobs belong to the upstream elements, parser and downstream sink respectively.
The queues separate branch scheduling so that a slower branch does not immediately block the other. They are particularly worth testing when the video encoder buffers frames. GStreamer notes that encoder latency can exceed simple queue defaults, which can cause one branch to stall when a queue fills. If that occurs, consider adjusting non-video queue limits or using multiqueue; do so deliberately and observe memory use and latency. GStreamer’s basic tools tutorial gives context for inspecting and debugging pipelines.
Do not assume that adding queues cures every stall. Verify that both sources continue producing, that the encoder is not overloaded, and that timestamps advance sensibly. flvmux also documents timestamp-related controls such as enforce-increasing-timestamps and skip-backwards-streams, but those are not substitutes for correcting bad timestamps upstream.
Send FLV to the RTMP(S) endpoint
The muxer output must reach a sink capable of RTMP or RTMPS. The exact sink element and URI syntax depend on your GStreamer installation; the research for this guide does not establish one universal sink command. Inspect the locally installed elements and their documentation, then configure the sink with the ingest address and stream key shown in YouTube Live Control Room.
YouTube recommends RTMPS. Its RTMPS setup guidance explains the secure ingest option and directs you to use the stream key from Live Control Room. Copy the current server address and key from that interface rather than relying on a value copied from an old tutorial. Treat the key as a credential: avoid putting it in a public script, screenshot, or shared command history.
Before starting the pipeline, verify the sink accepts the endpoint format and authentication method you are using. A pipeline can create valid FLV locally while failing to connect because of an incorrect address, key, firewall, or unsupported transport. Conversely, a successful connection does not prove that YouTube is receiving the intended audio and video. Watch the stream health and messages in Live Control Room while the test is running.
A stable local pipeline also depends on what the machine can sustain. If you are comparing a local process with another way to keep an always-on channel running, decide first whether you want to maintain GStreamer, the host and its reconnect behaviour yourself. StreamNeo can remove the specific burden of keeping your own computer switched on for a file-based broadcast: it takes an uploaded video and runs it as a YouTube live stream, but this GStreamer pipeline remains the appropriate path when you need to construct and control the stream yourself. For context on a different tool and workflow, see how OBS handles encoder overload during a YouTube loop.
Set keyframes, bitrate and rate mode
Set rate control and keyframe behaviour in the video encoder, not in flvmux. YouTube specifies CBR for RTMP/RTMPS encoder settings. Select the recommended bitrate for your chosen resolution and frame rate from YouTube’s current table, then configure the encoder that is actually in use to target that rate. Some encoders expose different property names or control modes, so check that encoder’s local documentation and verify the output rather than copying an x264enc property onto another element.
For x264, key-int-max is a maximum interval expressed as frames. If your output is 30 frames per second, a two-second interval is approximately 60 frames; at 60 frames per second it is approximately 120. The calculation is frame rate multiplied by the target interval in seconds. This does not mean that a value of 2 requests two seconds. Check the actual output frame rate and keyframe cadence, and keep the interval within YouTube’s recommendation not to exceed four seconds.
Rate-control settings can interact with latency and quality. GStreamer’s x264enc documentation describes tune=zerolatency as a possible aid in some live scenarios, while noting that it trades away quality. Do not enable it as a reflex: first measure whether encoder buffering is the cause of a real delay or queue problem, then compare the resulting picture in a realistic test. If quality matters more than minimum latency, that trade-off may not suit your channel.
Run a preflight with movement and audio similar to the planned broadcast. YouTube recommends testing under representative conditions, monitoring stream health during the event and reviewing messages. A static logo and silence do not exercise the same paths as a moving devotional video with continuous music. Check that reconnects behave as expected, the key is valid, both audio and video appear, and the pipeline remains stable long enough to expose buffering or source-end issues.
For readers building a continuous file-based channel rather than capturing live sources, the broader OBS podcast playlist workflow covers a different way to keep material moving. For GStreamer, make the loop or source behaviour explicit and test what happens when a file ends; neither the muxer nor the RTMP sink creates a playlist.
If you have confirmed your sources, plugins and caps and want a file-based channel to run without leaving your own computer on, compare the operating options on the pricing page. When the file and channel are ready, start free — 24-hour trial, no card.
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
Does flvmux encode H.264 or AAC?
No. flvmux muxes compatible encoded branches into FLV. Encode raw video as H.264 and raw audio as AAC upstream, and check the caps accepted by the muxer.
Why does flvmux reject my H.264 caps?
A common issue is that the parser output is not negotiating AVC stream format, which the muxer’s H.264 sink expects. Check that h264parse follows the encoder and inspect the negotiated caps immediately before flvmux; also confirm the parser plugin is installed.
Can I paste this pipeline and expect it to work on any machine?
No. The source elements, encoder, AAC plugin, RTMP(S) sink, URI syntax and negotiated caps vary by installation. Use the schematic branches as a guide, inspect your local plugins and properties, then test the complete pipeline with the actual endpoint details from Live Control Room.
How do I set a two-second keyframe interval?
Set the video encoder’s keyframe interval, not a muxer property. With a frame-count property such as x264enc key-int-max, multiply the output frame rate by two seconds, then verify actual cadence and keep the interval no longer than YouTube’s four-second maximum.