Skip to content
streamneo.
Setup Guides11 min read

How to Stream a GStreamer Pipeline to YouTube with RTMP

Build a GStreamer source-to-sink pipeline for YouTube Live, from encoding and FLV muxing to RTMP delivery and ingest checks.

sn.
StreamNeoPublished 7 October 2026
Worth sharing?

To stream a GStreamer pipeline to YouTube Live, build a path from your audio and video sources through any required conversion, then encode both streams, mux them into FLV, and send the result to an RTMP sink. The exact elements and properties depend on your sources, installed GStreamer plugins, and the ingest details YouTube gives you for the stream.

The important boundary is between encoding and delivery: an RTMP sink is not a general-purpose encoder. It expects data in a suitable streaming format, so use the documented FLV muxing pattern and test the complete path with the actual YouTube URL and key before relying on it.

Map the source-to-sink workflow

Think of the pipeline as a set of branches that meet at a muxer:

video source → convert/scale → video encoder ─┐
                                               ├→ flvmux → RTMP sink
 audio source → convert/resample → audio encoder ┘

A single video-only test can establish that the basic route is connected, but a real programme usually includes audio. GStreamer’s rtmpsink documentation shows a video test source feeding an FLV encoder, flvmux, and the sink. Its rtmp2sink documentation likewise demonstrates video encoding followed by flvmux and the sink. These examples explain the shape of the pipeline; they are not complete YouTube commands and do not establish that a particular source, encoder, or destination will work unchanged.

GStreamer has two documented RTMP sink implementations worth checking: rtmpsink and rtmp2sink. Both accept video/x-flv on their sink pads, which is why the FLV muxer belongs immediately before the delivery element. Which one is appropriate depends on what is installed, what connection behaviour and properties it supports, and whether it connects successfully to your specific YouTube ingest configuration. There is no basis for assuming one is universally better.

Before composing a long command, inspect your installation. gst-inspect-1.0 rtmpsink, gst-inspect-1.0 rtmp2sink, and inspection of the chosen encoder and muxer can show whether the elements are present and which properties this build exposes. A plugin documented for GStreamer may not be included in your operating system’s package selection, and property availability can vary by release. Treat the documentation and your local inspection output as complementary evidence.

If you are new to the distinction between a server URL and a stream key, the guide to RTMP servers, URLs, and stream keys gives the delivery terms more context. Keep the key private: it is a credential, not a public label for the broadcast.

Prepare or convert your sources

Start with the source you actually intend to publish. It might be a camera, a file, a live audio input, or another GStreamer element. Each source exposes particular media caps and timing behaviour. A camera may provide a format the encoder cannot accept directly; a file may end or have a different frame rate from the one you intend to send; an audio device may expose a sample rate or channel layout that needs conversion.

Use conversion elements deliberately rather than assuming every source can connect directly to an encoder. Video conversion and scaling can make pixel format and frame dimensions suitable for the chosen encoder. Audio conversion and resampling can help align the source with the encoder’s supported format and the stream’s intended channel layout. The actual element names and caps depend on the source and installed plugins, so verify them rather than copying a source-specific command from another machine.

A useful first test is to run the source and conversion path locally, before adding the network sink. Confirm that the source produces data continuously, that negotiated caps are what you expect, and that there are no bus errors. Then add encoding and muxing, and only after that configure the network destination. This makes it easier to distinguish a capture problem from an encoder negotiation problem or a failed connection.

For prerecorded material, make sure the source behaviour matches the broadcast you want. A file source normally reaches its end; it does not automatically become an endless programme just because the destination is a live channel. If your real task is a continuing rotation of recorded material, see the guide to streaming prerecorded videos to YouTube continuously. That is a different operational requirement from publishing one finite pipeline session.

Encode audio and video

The muxer combines encoded elementary streams; it does not replace the encoders. Build an audio encoding branch and a video encoding branch that match the codecs supported by your chosen output path and YouTube’s current ingest guidance. The encoder choices in GStreamer depend on installed plugins, platform support, and whether you have hardware or software encoding available. Check the selected element’s documentation and local properties rather than assuming a name or option from another system exists in your build.

YouTube’s live encoder settings guidance lists H.264, H.265/HEVC, and AV1 video for RTMP/RTMPS ingest, and AAC or MP3 audio. It also recommends constant bitrate encoding and a keyframe interval of two seconds, with four seconds as the maximum. These are platform recommendations; an encoder’s property names and behaviour are GStreamer-specific, and not every encoder exposes every control in the same way.

For H.264, YouTube’s current guidance includes the following video bitrate figures. They are guidance for the listed formats, not a promise that your upload connection can sustain them. The table reflects YouTube’s encoder-settings page checked in 2026; check that page again when preparing a real broadcast because recommendations can change.

Video format Minimum video bitrate Recommended video bitrate
720p at 30 fps 3 Mbps 8 Mbps
720p at 60 fps 3 Mbps 8 Mbps
1080p at 30 fps 5 Mbps 14 Mbps
1080p at 60 fps 6 Mbps 17 Mbps

YouTube lists 128 Kbps for stereo audio on the same page. Choose a profile that your source, encoder, and sustained upload can support, then observe the incoming stream’s health rather than treating a table entry as a target that overrides the connection you have. A quiet static visual and a camera scene with motion can behave differently in terms of the amount of data required to preserve the picture.

Keyframes matter because YouTube uses them as reference points in the incoming video. Its recommended two-second interval should be translated into the selected encoder’s actual control, taking frame rate and encoder behaviour into account. GStreamer documents GstForceKeyUnit events as a general mechanism for requesting keyframes, but that does not mean every encoder responds identically or that an event alone guarantees the requested cadence. Read the element documentation or gst-inspect-1.0 output for the encoder you chose.

For an application that embeds GStreamer, also account for live-source state behaviour. GStreamer’s streaming tutorial discusses live sources that can return GST_STATE_CHANGE_NO_PREROLL, alongside buffering and clock-loss handling. That is application-level lifecycle context rather than a YouTube-specific setting, but ignoring it can leave a sender that works in a short command-line test less robust when integrated into a longer-running process.

Mux the encoded streams to FLV

Place flvmux after the encoded streams and before the RTMP sink. In a two-branch pipeline, the encoded audio and video pads both feed the muxer; the muxer packages them into the FLV stream that the RTMP sink sends. That order is the central detail behind the documented source-to-sink architecture. Sending raw camera caps or raw audio straight to the RTMP sink skips the format conversion the sink interface expects.

The official examples are useful as structural references. GStreamer’s rtmpsink page illustrates videotestsrc . ffenc_flv . flvmux . rtmpsink, while its rtmp2sink page shows videotestsrc . x264enc . flvmux . rtmp2sink. In each case, the destination is illustrative, the source is a test pattern, and the encoder may not be installed or appropriate for your situation. Do not copy the localhost or example server destination into a live setup and expect it to reach YouTube.

For a real audio/video pipeline, branch and link the audio and video streams according to the elements you have selected, then confirm the muxer negotiates both streams. Use verbose output during early tests and look for caps negotiation failures, missing pads, or errors reported on the GStreamer bus. A muxer can only package streams that reach it in compatible, supported forms; adding a network sink will not repair an upstream mismatch.

If the pipeline starts but one branch never produces data, inspect that branch independently. A live audio source that is silent, a video source that has not negotiated, or a file that has already reached EOS can all leave you with an incomplete programme even though the sink element itself exists. Test with representative audio and moving video before scheduling a real event.

Send the FLV output with an RTMP sink

After flvmux, choose the sink available in your installation. The rtmpsink element belongs to GStreamer’s RTMP Bad Plug-ins package and uses a location property for its destination URL. The rtmp2sink documentation provides another implementation and also uses a location. Their documented examples establish the pattern, but you still need to verify the precise URL form, authentication handling, and supported properties for the destination and local plugin build.

For a command-line test, think in terms of this schematic rather than a copy-and-run recipe:

<video source and conversion> . <video encoder> ─┐
                                                   ├→ flvmux → <RTMP sink with configured location>
<audio source and conversion> . <audio encoder> ─┘

This is intentionally not a complete command: source syntax, caps, queueing, encoder settings, and the exact sink location vary. Do not put a real stream key in a public article, shell history you share, screenshot, or source-control repository. Restrict access to scripts and logs that could contain it, and replace a key if you believe it has been exposed.

YouTube recommends RTMPS, the secure extension to RTMP. That recommendation does not itself prove that a specific GStreamer sink build can connect to the RTMPS endpoint you plan to use. Check the sink’s current documentation and local properties, then use the server address supplied by YouTube for your stream and a supported transport. If your intended sink does not support the required connection mode, choose a compatible sender path rather than silently substituting a different endpoint.

The sink documentation exposes different diagnostic and configuration options, and some rtmp2sink properties are documented as having been introduced in particular GStreamer releases. Compare the installed plugins by availability, URL and authentication behaviour, useful diagnostics, and a successful test against the exact ingest details. If you need the sender to keep running unattended, recovery from a stopped process or lost connection is also an operational concern, not a guarantee provided by the fact that the pipeline has an RTMP sink. The guide to recovering a YouTube FFmpeg stream after a server restart is relevant to that broader recovery problem, although its sender is different.

Use the current YouTube ingest details

In YouTube Live Control Room, create or select the live stream and copy the stream URL and stream key shown for that configuration. Enter the URL in the sender’s destination field and use the key only in the form expected by that endpoint and sink. The values belong to your channel’s current stream configuration; do not invent a path or assume that another creator’s URL layout is suitable for yours. YouTube’s encoder setup instructions explain the platform workflow.

For a scheduled event, sending packets is not necessarily the same thing as making the event public. Wait for YouTube to show the incoming preview and check stream health; where the event workflow requires it, use the control-room action to go live. YouTube advises testing with representative audio and video and monitoring the health indicators. Treat a successful local GStreamer state transition as only one check: it does not prove the platform has received a valid picture, sound, or stable bitrate.

Before the event, validate the whole chain in order: sources produce data; conversions negotiate the intended formats; both encoders run; the muxer receives the encoded streams; the sink connects to the supplied destination; and the control room shows the incoming preview. Compare actual bitrate and keyframe behaviour with the current encoder guidance. If you change resolution, frame rate, codec, or transport, repeat the test rather than assuming the earlier result still applies.

A pipeline that must remain live through the night also needs an operational plan for the computer or process that owns it. A local command stops being useful if the machine sleeps, loses power, or the process exits. StreamNeo removes that particular always-on computer burden for prerecorded-file broadcasts: you upload the video and provide the YouTube stream key, then the broadcast can continue with your computer off, with monitoring and automatic restarts if it drops. It is for YouTube, so a live capture pipeline whose source must remain connected at your premises is a different use case.

If the content is a scheduled sequence rather than one continuous source, plan the viewer hand-off separately from the encoder. The guide to automating YouTube Live redirects between scheduled streams covers that channel workflow; it does not replace testing the GStreamer ingest path described here.

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

Can I use rtmpsink or rtmp2sink directly with a camera source?

Not as a general rule. The camera’s raw output must be converted if needed, encoded, and muxed into FLV before it reaches an RTMP sink. The camera’s supported formats and your installed encoders determine the actual pipeline.

Is YouTube’s RTMPS recommendation the same as proof that my sink supports it?

No. YouTube recommends RTMPS, but you must confirm that your installed GStreamer sink and its build support the intended secure endpoint and authentication behaviour. Use the current endpoint shown for your stream and test the connection.

Why does the sink connect but YouTube show no usable preview?

A connection alone does not establish that the incoming media is correctly encoded or muxed. Check negotiated caps, whether audio and video reach flvmux, bus errors, the URL/key pair, and the control room’s stream-health information.

Can one example command work unchanged on every machine?

No. Source elements, codecs, properties, and plugin availability vary by operating system and GStreamer build. Use the documented architecture as a guide, inspect the elements installed locally, and test the complete pipeline with your own source and current YouTube ingest details.

YOU’VE REACHED THE END

Keep the ideas coming.

More guides, useful tools and a little help for your next broadcast.

Back to the journal ↗
YOUR NEXT READ

A little more to explore.

More Setup Guides guides ↗ · All topics ↗