I've wanted to learn how to stream video since I started UruTunes back in '07, and now I've finally done it!
Some may be surprised to learn that Icecast can do video, but it does it quite well. Since it's rock-solid stable, free, powerful, small, and ubiquitous across the net, I've built my setup around it. This article is the result of a huge chunk of my life researching all around the web and testing in Firefox, Chrome, VLC and more. I hope it helps you.
Important!
This is about running server software directly from your own computer. It's not recommended for slow PCs, slow internet, or lots of users. Running a server requires Port Forwarding through your router. This setup requires an Internet upstream speed of at least 10 Megabits per second (Mbps), per user — that's 100 Mbps for 10 users.
Port forwarding is done on your internet router/gateway, and is different for every kind, so you'll need to work that out with the manufacturer's documentation. The default port for Icecast is 8000, so that's a place to start.
Of course, this uses Free and Open Source Software (FOSS) because that's how I roll.
Icecast Media Server https://icecast.org/download/ Beta: https://icecast.org/news/icecast-release-2_5-beta1/
Icecast is very popular. I'm using a test version, 2.4.999.1 (aka 2.5.0 RC1) for Windows, which is very solid, but the old 2.4.4 version works great too. It's been confirmed to me that the test version I'm using now has been improved to more easily start playback in various players like Chrome. I learned about it from the kind folks in the #icecast IRC channel on Libera Chat (webchat).
Open Broadcaster Software (OBS) https://obsproject.com/download
OBS is also quite popular and has a large community on Discord and elsewhere.
This is my most commonly used setup, i.e. 1080p at 30 fps with 5.1 surround sound, but sometimes I do other resolutions and fps by tweaking these numbers. For plain stereo audio only, I recommend using BUTT (Broadcast Using This Tool) instead of OBS, because it's simply the best at audio, and OBS isn't meant for that. I've developed several different "Profiles" in OBS and configs in Icecast for doing various types of shows.
I'm trying to collect all the good information I can find out there for this kind of thing. Here's another great guide from a contributor to the Icecast project.
https://epir.at/2018/03/08/obs-icecast-streaming/
Strap in and good luck! You can do this!
Icecast, in the icecast.xml file:
https://icecast.org/docs/icecast-latest/ (Official docs)
In addition to standard stream settings, either in the applicable <limits> or <mount> section, add/replace these 2 lines. Burst size is how much data (Bytes) each player is given at the start — I shoot for 1 second-worth. Queue size is how much data is allocated for each player — it must be larger than burst size and about 3 times that. If a player lags behind more than this, their playback stops, but it eats memory, so go easy.
- <queue-size>2490000</queue-size>
- <burst-size>830000</burst-size>
Take your total bitrate (video + audio, from OBS or whatever), divide it by 8 to get the Bytes, then use that as the burst-size for 1 second of playback. Then, multiply that burst value by 3 for queue-size to give about 3 seconds-worth. That seems to work very well until I get up to ultra high-rate streams like 2160p@60-fps which call for some 7,580,000 Bytes per second. At that rate, Icecast gets a little twitchy - it works but users might need to refresh a couple times. I've beat my head against this far too long and can't seem to do any better.
These metadata values go inside a <mount> block; they're optional; and can be set here in Icecast, or below in OBS. Setting metadata here in Icecast supersedes the same values in OBS (or any other source).
- <stream-name>Show Name</stream-name>
- <stream-description>Show Description</stream-description>
- <stream-url>Show URL</stream-url>
- <genre>Show Genre</genre>
Settings >
> Audio > General:
- Sample Rate: 48kHz (Required by some codecs.)
- Channels: 5.1 (Fewer == less overhead.)
- Base (Canvas) Resolution: 1920x1080 (Lower == less overhead.)
- Output (Scaled) Resolution: 1920x1080 (Better done here than in the Output > Recording below.)
- Common FPS Values: 30 (Lower == less overhead.)
- Type: Custom Output (FFmpeg)
- FFmpeg Output: Output to URL
- File or URL: icecast://username:password@host:port/mount (From icecast.xml.)
- Container: webm
- Muxer settings (Space separated prop='val', single quotes only. Only content_type is required, the others are optional and can be set here or in Icecast above.) Here's the full string entry:
content_type='video/webm' ice_name='Show Title' ice_description='Show Description' ice_genre='Show Genre' ice_url=www.UruTunes.com ice_public=1 - Video bitrate: 6000 Kb/s (Lower == less overhead.)
- Rescale: [ ] (No; better done in Settings > Video above.)
- Keyframe interval (frames): 60 (Double the FPS number for 2 seconds; higher == fewer keyframes and less overhead but more latency.)
- Show all codecs: [x] (Yes.)
- Video Encoder: av1_nvenc - NVIDIA NVENC av1 (This is NVIDIA'S hardware encoder; if you have an AMD GPU you should try: av1_amf - AMD AMF AV1. If neither of those work, a good software encoder is the default: libvpx-vp9 - libvpx VP9.)
- Audio bitrate: 640 Kb/s (Lower == less overhead; 500 is good for 5.1 but 96 will do for stereo.)
- Audio Encoder: Disable encoder (Yep, none. Using a hardware video encoder above seems to handle the audio as well, but the audio bitrate above still matters, so set that first then disable this — strange thing. If your hardware's video encoder doesn't provide audio, choose libvorbis - libvorbis here.)
NOTE: I discovered that libopus doesn't work in VLC for playback, so I changed to libvorbis which seems to work across all playback cases. However, as of this writing, Firefox has had a bug in their libvorbis decoder that mixes up audio channel assignments — I've reported it and they're working on it. UPDATE: This bug may have been squashed - the last time I tried it seemed correct.
As always, if you have any questions or input, please let me know.