Resource icon

OBS Studio: Stream to multiple platforms or channels at once

UPD 17 Mar 2021: Now that the amazing SoraYuki published their obs-multi-rtmp plugin, you probably don't need this guide anymore, as the plugin is a lot easier to use. Like, a lot easier. But if you need FFmpeg filters, or you need to output at different frame rates, keep reading.

Before you read, please note that this is only useful if a third party service like https://restream.io doesn't suit your needs. Also, some of the more complicated setups might require a good understanding of command-line FFmpeg. If you need help for your specific setup, ping Nakajima Megumi#7432 in the obsproject support Discord.

The general idea is as follows: host a RTMP server on your PC, stream to that server, then use FFmpeg to copy the stream to as many streaming platforms as you need to, with or without reencoding.



Step 1. Host a RTMP server


There are multiple solutions for this. The one I recommend personally for Windows is MonaServer, as it's relatively painless to set up - just extract and run.
Get it here: http://sourceforge.net/projects/monaserver/files/MonaServer_Win32.zip/download
Extract it, then launch MonaServer.exe from the command line. Example command:
Code:
cd /D C:\Apps\mona
monaserver.exe
1_mona_running.png

Feel free to ignore error messages not relevant to the RTMP server running on port 1935.
This will host a RTMP server on your Windows PC; by default, only you should be able to stream to it unless you forward port 1935. If you're using Linux, or you'd like to set up a more feature-rich server, you can use the guide from dodgepong, here https://obsproject.com/forum/resources/how-to-set-up-your-own-private-rtmp-server-using-nginx.50/


Step 2. Configure OBS Studio to stream to your server and start streaming


In OBS Studio, copy your current live-streaming profile by clicking Profiles > Duplicate. This will let you easily undo all changes, if you need to.
2_obs_copy_profile.png

After that, go to Settings > Stream, change streaming service to "Custom" and paste the following:
In the Server field:
rtmp://localhost:1935/live
In the Stream Key field:
stream
3_settings-stream.png

Press OK to apply changes and Start streaming to start your local stream. MonaServer will recognize a new client now:
4_mona_rtmp.png

You should see "1 clients". That's us.

Step 3. Set up FFmpeg and test


If you don't have FFmpeg installed yet, to go https://ffmpeg.zeranoe.com/ and download the 64-bit static build. Extract ffmpeg.exe, ffprobe.exe and ffplay.exe to the same folder where you have MonaServer.exe.
Now, let's verify that the stream is live. To do that, create a new CMD or Powershell window and use ffplay from your download of ffmpeg:
Code:
cd /D C:\Apps\mona
ffplay -i rtmp://localhost:1935/live/stream
5_droste.png
Since I'm watching my own stream, I see a video feedback effect. Don't worry about the high stream delay, most of it came from ffplay's buffering, RTMP should introduce about 800 ms of extra latency at worst, 100-200 ms on average.
Quit ffplay by hitting q in its window or Ctrl+C in the command line window where you spawned it.


Step 4. Get your stream keys


Now you need your stream keys and the exact full path for each broadcast you intend to run.
For example, Twitch's ingest server in France is available at rtmp://live-fra.twitch.tv/app/ and Youtube's primary ingest server is rtmp://a.rtmp.youtube.com/live2 . What this means is that your full play path for broadcasting on Twitch would be rtmp://live-fra.twitch.tv/app/my-stream-key, where my-stream-key is your full stream key.
To see the full list of ingest servers OBS Studio exposes, read https://github.com/obsproject/obs-studio/blob/master/plugins/rtmp-services/data/services.json .


Step 5. Start streaming

Note that I could be using line breaks for more convenient reading in example commands; you will need to remove them.

Option 1. Start and stop streams independently of each other per-service, no reencoding

For this, you need to launch a separate FFmpeg instance for each service. This increases the total RAM and CPU footprint slightly. Here's an example command to start streaming to a single platform:
ffmpeg -i rtmp://localhost:1935/live/stream -c:v copy -c:a copy -f flv rtmp://live-fra.twitch.tv/app/my-stream-key
You can stop the stream by either closing the CMD/PowerShell window, or by pressing Ctrl+C. FFmpeg will try to exit cleanly, which may be slow; if you need to force-quit FFmpeg, sending Ctrl+C four or more times will cause a force-quit.

Option 2. Start and stop multiple livestreams simultaneously, all services/channels will receive the same video quality, no reencoding

To broadcast to multiple platforms or channels at once, we can use the "tee" protocol and separate play paths with the | character.
Let's test it first by remuxing the local stream and re-streaming it to our own server:
Code:
ffmpeg -i rtmp://localhost:1935/live/stream -c:v copy -c:a copy -map 0 -f tee "[f=flv]rtmp://localhost:1935/live/stream2|[f=flv]rtmp://localhost:1935/live/stream3|[f=flv]rtmp://localhost:1935/live/stream4"
If MonaServer is reporting 5 clients (that's 4 broadcasters and 1 viewer), it's working.
Here's an example with three Twitch channels:
Code:
ffmpeg -i rtmp://localhost:1935/live/stream -c:v copy -c:a copy -map 0 -f tee "[f=flv]rtmp://live-fra.twitch.tv/app/my-stream-key|[f=flv]rtmp://live-fra.twitch.tv/app/my-second-stream-key|[f=flv]rtmp://live-fra.twitch.tv/app/my-third-stream-key"
Each URL will receive a copy of the stream, without reencoding.

Option 3. Two (or more) services, each receives its own reencode

Let's say you want to stream to Twitch in 720p 60fps 6 mbps, and to Youtube in 1080p 60fps 20 mbps. There are two ways to approach this - either stream locally in high quality (target 100-230 mbps, or use CQP) and do two reencodes, slightly increasing the performance footprint, or stream in a bit rate high enough for Youtube and reencode it for Twitch, hurting the quality of Twitch's stream.

If we have a high-quality local stream and want to do two x264 reencodes, keeping our 160kbps audio for both streams, we'd be specifying outputs one after another, like this:
Code:
ffmpeg -hide_banner -i rtmp://localhost:1935/live/stream -c:v libx264 -b:v 20000k -preset veryfast -c:a copy -f flv rtmp://a.rtmp.youtube.com/live2/my-youtube-stream-key -c:v libx264 -b:v 6000k -preset veryfast -c:a copy -vf "scale=1280:720" -f flv rtmp://live-fra.twitch.tv/app/my-stream-key
Note the addition of -vf "scale=1280:720" - this adds a video filter to downscale the stream to 720p for Twitch. I'm assuming the input will be 1080p 60fps, and that is what Youtube will receive.

Here's another example using NVENC for Youtube's reencode and x264 for Twitch:
Code:
ffmpeg -hide_banner -i rtmp://localhost:1935/live/stream
-c:v nvenc_h264 -b:v 20000k -preset slow -c:a copy -f flv  rtmp://a.rtmp.youtube.com/live2/my-youtube-stream-key
-c:v libx264 -b:v 6000k -preset veryfast -c:a copy -vf "scale=1280:720" -f flv  rtmp://live-fra.twitch.tv/app/my-stream-key


Or, let's say you're streaming from OBS Studio at 20 mbps 1080p 60fps and want to copy the stream as-is to Youtube, and reencode to 4 mbps 720p 30 fps for Twitch:
Code:
ffmpeg -hide_banner -i rtmp://localhost:1935/live/stream
-c:v copy -c:a copy rtmp://a.rtmp.youtube.com/live2/my-youtube-stream-key
-c:v libx264 -preset veryfast -b:v 6000k -c:a copy -r 30 -vf "scale=1280:720" -f flv rtmp://live-fra.twitch.tv/app/my-stream-key
Note the addition of -r 30 to drop from 60 fps to 30 fps. If your input is 59.94fps (60000/1001), you can drop to 29.97 by using -r 30000/1001.

Note on FFmpeg options and preset selection:
-preset veryfast selects the x264 preset, "veryfast".
FFmpeg can also use NVENC with -c:v h264_nvenc- in that case, I'd recommend using -preset slow (2-pass high quality) on all cards except Turing cards; on Turing cards I'd recommend -preset hq (single pass high quality). Note that due to NVIDIA's marketing limitations you can only use 2 concurrent NVENC sessions on GeForce cards; trying to start a 3rd one will throw an "out of memory" error (even if you have enough spare VRAM).
FFmpeg can also use AMD AMF with -c:v h264_amf, please refer to this documentation for using AMF:
ffmpeg -hide_banner -h encoder=h264_amf

Option 4. Re-encode some or all of the streams

This option requires a good understanding of the command line interface and FFmpeg. I'll try to describe it and provide examples, but if that doesn't help, you might still have to dig through FFmpeg's documentation.


Let's say we take a high quality input, save it as-is to file, then reencode to 2 mbps and send to 2 services:
Grab the stream
ffmpeg -hide_banner -i rtmp://localhost:1935/live/stream
Save locally
-c:v copy -c:a copy -f mp4 source.mp4
Reencode with two outputs
-c:v libx264 -b:v 2000k -c:a copy -map 0 -f tee "[f=flv]rtmp://live-fra.twitch.tv/app/my-stream-key|[f=flv]rtmp://live-fra.twitch.tv/app/my-second-stream-key"


If you need help for your specific setup, or some parts of the guide are unclear, ping Nakajima Megumi#7432 in the obsproject Discord with your questions.

You can learn more about the tee muxer for more advanced use cases here: https://trac.ffmpeg.org/wiki/Creating multiple outputs

Latest reviews

Very well done and detailed.
Thank you so much for such a clearly detailed step-by-step tutorial. I actually signed up on here just to give you this rating and feedback. Thanks again.
megpoid0 is ON FiRE! Gros Merci! wow, great step by step
Absolute Titanium* Much Health! gracie millé
Just GREAT. It was such a beautiful article and I was able to do it so easilu that it's unbelieveable. Thank you so much to whoever wrote this article. Deserves a 10 star rating.
Very good article,
Top