One NGINX RTMP server can forward two incoming streams to different YouTube channels, provided each input has a clearly defined route and destination. The important work is not merely adding two push lines: you must prove that each incoming feed reaches only its intended YouTube preview before either stream goes public.
The nginx-rtmp-module supports application-level push, but actual routing depends on the configuration and module build you deploy. Treat the example below as a pattern to adapt, not a tested drop-in configuration or a guarantee of isolation.
Map each input to its intended channel
Start with the people, content and destinations rather than with NGINX syntax. Write down which encoder or publishing process will provide each input, what it will show, which YouTube channel owns the destination, and who is responsible for checking it. For a devotional channel and a local news loop, for example, “morning bhajans” belongs to the devotional channel and “town notices” belongs to the news channel. This simple mapping helps prevent a technically valid but editorially wrong broadcast.
Give each path a stable, understandable name. The input for the devotional stream might publish to channel_one; the news stream might publish to channel_two. These names are examples only. Pick names that your operators can recognise, then use them consistently in the encoder URL, NGINX application or routing rules, and your setup notes.
Keep an inventory of four things for each route: the source that publishes to it, the local RTMP application or route, the YouTube channel, and the matching YouTube stream key. Do not put the key in a shared spreadsheet or an operator note that does not need it. The inventory can identify the key by a private label or last characters, while the full value stays in the secured configuration or credential store.
This is also the point to decide what “separate” means operationally. Two channels can be run by one person, but each still needs its own destination, preview check and go-live decision. If one channel should continue while the other is stopped, make sure your operating procedure and configuration let you identify and stop the correct route without affecting its neighbour.
Choose distinct applications or unambiguous routes
The clearest pattern for a first setup is usually one RTMP application per channel. The application component of a publish URL maps to an application {} block, and the module documents push within an RTMP application. A conceptual configuration looks like this:
rtmp {
server {
listen 1935;
chunk_size 4096;
application channel_one {
live on;
push rtmp://<youtube-ingest-host>/<app>/<channel-one-key>;
}
application channel_two {
live on;
push rtmp://<youtube-ingest-host>/<app>/<channel-two-key>;
}
}
}
This illustrates the intended relationship: an input is published into one application, and that application has its own configured push destination. It does not prove that a particular server build will map every incoming stream name as you expect. Confirm the destination URL format and stream-name behaviour for your deployed module and for the values YouTube currently supplies. The nginx-rtmp-module README documents application-level push and relay directives; use it alongside the configuration and module version actually in use.
For example, an encoder might publish the first input to rtmp://<your-server>:1935/channel_one/<input-name> and the second to rtmp://<your-server>:1935/channel_two/<input-name>. The angle-bracket values are placeholders, not literal credentials or a complete configuration. Check that the application names match the blocks, and verify how the module interprets the final name and constructs the outbound path.
A second approach is one application with distinct stream names and conditional routing. That can suit an existing setup, but the name-based rules must be explicit and must be confirmed against the exact module build. A route that looks distinct to a person is not necessarily distinct to the software if the rule matches only part of the name or if an output is shared. Do not assume the mapping is automatic.
| Routing pattern | What is easier to reason about | What you must verify |
|---|---|---|
| Separate applications | Each input URL visibly names its intended application; keys can be associated with separate blocks | That the input reaches the intended application and that its push target is constructed as intended |
| One application with distinct names | May fit a configuration already organised around one application | That name matching is precise, each name maps to one target, and no rule forwards an input to both destinations |
Prefer separate applications unless you have a clear reason not to use them. Even then, isolation is a property you establish through configuration review and testing, not a property to infer from labels. A private test before making a 24/7 radio stream public is a useful discipline here: keep the first test private or otherwise not public until the correct preview is confirmed.
Configure a destination and stream key per route
In YouTube Live Control Room, create or select the live stream for each channel. For each one, copy the server URL and stream key displayed by YouTube, and enter that pair only in the NGINX route intended for that channel. YouTube’s encoder setup guidance explains that an encoder needs the server URL and stream key to send a feed.
Do not reuse one destination key for both routes as a shortcut. A key identifies the destination YouTube accepts, so reusing it defeats the clear one-input, one-channel mapping you are trying to establish. Equally, do not copy a key from one channel into the other application because the route names look similar. Label the two pairs before pasting them, then have a second person or a deliberate read-back check confirm the channel association if the consequences of a mistake are material.
Use the exact server URL and key shown for each stream rather than relying on an older note or a guessed ingest hostname. YouTube can offer ingest settings and modes that may not be identical across setups. The RTMP destination shown in a generic configuration pattern is not a substitute for the current values in Live Control Room. The YouTube encoder settings page describes supported ingest options and recommends RTMPS; check its current instructions when setting up the actual destination.
The module’s push directive and the YouTube-provided destination are separate pieces of the chain. The first determines what your NGINX RTMP application attempts to forward; the second identifies where YouTube should accept it. A typo in either can mean no picture, a feed going to an unintended destination, or a stream that appears to work locally but is absent from the expected preview. There is no reason to make the configuration look compact at the expense of being able to inspect each pairing.
If you are adapting an existing server, keep the old working route intact while you add the second route, where practical. Review the whole effective configuration, including included files, for duplicate application names, broad name-based rules and repeated push directives. A configuration can be syntactically accepted and still be logically wrong. Do not treat a successful reload as evidence that the correct channel received the correct video.
Understand application-level push
Application-level push means that the RTMP module is configured to relay a published stream from an application to a destination. This makes it possible for one server to receive feeds and forward them to multiple destinations, but the directive alone does not decide which programme belongs on which channel. Your input URL, application or route rules, stream name and destination settings together determine the result.
That distinction matters when you use more than one source. If two encoders publish into the same application and its push rule forwards published inputs, you need to understand exactly what the deployed module does with each name. A route may not behave like a separate physical pipe just because the outgoing destinations are listed separately. Avoid assuming that the first input goes to the first push and the second input goes to the second push unless the specific routing rules establish that behaviour and you have tested it.
An issue reported in the module’s GitHub tracker describes separate applications and a case where both destinations received the first input. It is a useful warning, not proof that all module versions behave that way or that the same failure occurs in every setup. The practical lesson is narrower: intended input-to-output mapping can be surprising, so make the routes explicit and verify the observed result.
Be cautious when copying snippets from a discussion or adapting a configuration written for another fork. The README is primary project documentation for the module’s directives, while a user issue records one reported case. Neither establishes compatibility for every fork, build, path format or current YouTube ingest mode. Record the module version, inspect the configuration you actually reload, and use the test procedure below to resolve uncertainty rather than treating a sample as established fact.
Protect and verify each destination key
Treat each YouTube stream key like a password. YouTube’s stream-key guidance explains that a key tells an encoder where to send a feed and allows YouTube to accept it. Limit access to the configuration and to any place where the key is temporarily handled. Avoid putting full keys in screenshots, public support requests, chat messages or logs that are routinely shared.
Keep the two keys visibly distinguishable without exposing their values. For example, label them “devotional channel — production” and “news channel — production” in your secret-management notes, and keep the full secret available only to the people and processes that need it. When you paste a value into the matching route, check the channel name at the same time. A careful key-handling routine reduces both accidental swaps and the risk that an exposed credential is used to send an unauthorised feed.
If you suspect a key has been exposed, reset or regenerate it in Live Control Room and update only the corresponding route. Then repeat the private test for that route before returning it to normal operation. A key change can interrupt a feed until the configuration and YouTube destination agree again, so plan the change with the person responsible for the channel rather than replacing a value silently during a live broadcast.
For host security, restrict who can reach the publishing endpoint and who can alter the NGINX configuration. These are different controls: a private YouTube key does not stop an unauthorised publisher from reaching an exposed RTMP input, and a restricted input does not protect a key copied into an open file. If this runs on a Linux virtual server, the server security checklist for a YouTube livestream can help you think through access and host maintenance without changing the routing checks described here.
Publish test streams one at a time
Do not test both channels at once at the start. Publish a short representative feed to the first local application while the second input is stopped. Use enough picture and sound to recognise the content, not just a static connection indicator. Then stop that test and repeat the same process for the second application. This isolates the observation: if the wrong preview changes, you know which input was active when it happened.
Before each test, read the route aloud or check it against your inventory: source, local application, YouTube channel and key label. Start the encoder with the intended local publish URL, observe the NGINX and encoder status, and wait for the corresponding YouTube preview. Do not infer success from an encoder’s “connected” message alone; it confirms a connection at one point in the chain, not that YouTube has received the intended programme at the intended channel.
For the first route, confirm that the first channel’s preview shows the test content and that the second channel’s preview does not. Stop the input before moving to the second route. Then confirm the inverse: the second preview shows its test and the first does not. This one-at-a-time approach makes a mapping error easier to notice than testing both routes simultaneously, when two moving previews can obscure which input caused which result.
Use the same video and audio conditions you expect in production. YouTube advises testing with representative content and watching stream health; a file with silence or no motion may not reveal the same problems as a normal devotional programme, study ambience loop or news sequence. If the production feed is a playlist or continuous programme, a relevant guide to alternating episodes and reruns in a live stream can inform what to include in a representative content check.
A preview appearing in the wrong place is a stop condition, not a reason to make the stream public and “fix it later”. Stop publishing, inspect the actual input URL and effective routing rules, and confirm the destination key pairing. Change one thing at a time, then repeat the one-input test. Keep notes about what was changed and what each preview showed, so a second operator can understand the result without having to infer it from a late-night configuration edit.
Confirm each preview in Live Control Room
Live Control Room is the destination-side check. For each test, confirm the correct channel and stream are selected, the preview contains the expected source, and the other channel is not receiving that test. Check stream health before making either stream public. YouTube’s live streaming help provides current setup context; the interface and its available controls may change, so follow the instructions displayed for your account.
Do not treat a thumbnail or a connected indicator as sufficient evidence. Watch enough of the preview to recognise the image and listen for the expected audio. A feed can arrive at YouTube and still be the wrong feed, or have an audio problem that is not apparent from the encoder status. Confirm the channel identity in the Control Room itself before changing visibility or starting a public broadcast.
After each route passes alone, you can test both together if that is how they will operate. Watch both previews and check that the content remains on the intended channel while each input is active. This second-stage test does not replace the isolated tests: it checks simultaneous operation after the one-at-a-time mapping has been established. If one feed disappears or appears at the other destination, stop and revisit route scope, stream-name handling and the actual destination settings.
Also check that the server’s outbound connection can carry both forwarded streams at once, with room for other network use. YouTube’s published ingest bitrate recommendations describe a feed’s settings, not a guarantee about your particular connection; two outgoing feeds require capacity for both. If you transcode separate outputs, account for the added processing work and verify that the server can handle the chosen settings. Keep the encoder format, audio, keyframe interval and ingest protocol aligned with YouTube’s current official guidance, rather than assuming an old preset remains appropriate.
For a 24/7 operation, write down the passing checks and who can stop each route. If a stream drops overnight, an operator should be able to identify the affected input and destination without restarting the other channel blindly. StreamNeo turns an uploaded video into a 24/7 YouTube live stream, which removes the need to keep a personal computer running for that file-based channel; it does not replace the route verification needed when you configure your own NGINX RTMP relay.
When your configuration and test plan are ready, consider the ongoing work of maintaining the server, keys and two independent channel checks before you choose how to operate them.
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 one NGINX RTMP server send two streams to YouTube?
Yes, the nginx-rtmp-module supports relaying through application-level push, so one server can be configured with multiple routes and destinations. You still need to define and test how each input maps to its destination; having two push directives does not by itself prove that two inputs are isolated.
Should I use separate applications or one application with two stream names?
Separate applications are generally easier to inspect because each input URL names its intended application and each application can have its own destination configuration. A single application with name-based rules can work only when those rules are precise and confirmed on the module build you use. In either arrangement, test each input alone and check both YouTube previews.
What if both YouTube previews show the same input?
Stop the tests and keep both streams non-public. Check the effective NGINX configuration, incoming application and stream names, and the key-to-channel pairing; then change one item at a time and repeat the isolated test. A report in the module issue tracker illustrates this kind of surprising mapping, but does not establish how every version behaves.
Can I run both routes continuously after the tests pass?
You can operate both once their individual destinations and simultaneous behaviour have been checked, but tests cannot guarantee uninterrupted service. Monitor each channel’s preview and stream health, keep keys private, and ensure the server’s outbound capacity and any transcoding workload suit both feeds.