diff --git a/content/streaming/index.md b/content/streaming/index.md index 0b95bfd..dc8accb 100644 --- a/content/streaming/index.md +++ b/content/streaming/index.md @@ -1,12 +1,12 @@ +++ -title = "Streaming setup" -date = 2026-10-01 +title = "Streaming for Teamspeak3" +date = 2026-10-10 description = "Custom streaming setup to complement teamspeak" draft = true [taxonomies] categories = ["Homelab"] -tags = ["Homelab"] +tags = ["Homelab", "Teamspeak3"] [extra] toc = true @@ -26,18 +26,72 @@ But as anyone that has used teamspeak before might know, Teamspeak3 does not sup But given that teamspeak allows for creating your own plugins and makes it relatively easy to distribute them, I thought it might be interesting to try and basically add this functionality myself using a plugin. # The Plan -TODO +So the plan is to have a teamspeak plugin, which we use to authenticate, automate the streaming setup and allow for easily watching streams. +In practice that means you are required to log into my self-hosted auth server, which both ensures that you are actually allowed to stream and allows me to send dynamic information about the streaming setup to the client (like some secret key to use for further auth). +If someone wants to start streaming it both provides you the URL and stream-key for manual use, but can also start OBS itself and properly configure the streaming details, if the OBS websocket server has been enabled before. +As a viewer you can just click on someone in teamspeak and click on "watch", which opens up a new window containing the stream. -# OvenMediaEngine + OBS -Luckily I found OvenMediaEngine, which is an entire software setup to basically host your own streaming -platform. This is obviously overkill for our goal, but works better than I would have expected at first. +# OvenMediaEngine +OvenMediaEngine is a project I found, that allows you to basically setup your own streaming platform with all kinds of features. +However for this use-case the setup will be limited to the most basic configuration of just directly rebroadcasting the incoming streams. + +So it accepts streams over rtmp from streaming sources, like OBS, and then listens for any "consumer" and forwards the stream using WebRTC over UDP to them. +This allows for low-latency streaming, which is very important as you are likely talking to the person streaming and any large delays in the stream would greatly reduce the overall enjoyability of this plugin. + +# OBS +OBS in this case is just the default choice for streaming, as it is open-source and relatively easy to use by everyone. +The main requirement is that it needs to be able to stream over rtmp, but a benefit of using OBS is that you can (once enabled) interact with OBS programmatically over a websocket server. +This means that users do not have to manually enter the stream credentials every time they want to start the stream, but instead the plugin can actually configure these settings for the user. # Teamspeak3 Plugin -To make the setup for my friends easier and to add some form of security/authentication, I wrote a small -teamspeak plugin, which generates the credentials and urls needed to both stream yourself and watch streams. +The plugin itself is relatively simple, as all it has to do is authenticate the user and give them two new buttons for starting a stream and watching streams. +Teamspeak plugins in general are relatively straight forward to build, as they are just dynamically linked library, exposing a specific set of functions, which are loaded at runtime by teamspeak. -# Custom Website -TODO +The authentication works very roughly, by starting a local webserver and providing a link to my auth server. +This is a simple OAuth flow, where the user gets redirected to the local webserver of the plugin, allowing it to get all the information it needs. +This information includes both the endpoint to stream to and a secret key, which gets used together with the users ID to generate the stream-key, which authenticates them against OvenMediaEngine. + +Starting to stream is relatively simple, the plugin uses the secret key and the users current teamspeak ID and generates the stream-key to use in OBS or other programs. +For manual usage, the plugin outputs the streaming endpoint and the stream-key in message to the user itself. +For automatic usage, the plugin tries to launch OBS and connect to it over the websocket server, if that fails it will just ignore the failure, but if it can connect it will automatically update the streaming settings to the correct information. + +Actually watching is the easiest part, as plugin just launches the bundled custom viewer, with the teamspeak ID of the person they want to watch and the secret-key. +The custom viewer will then take care of the authentication for watching the stream and actually begin the video player. + +## Custom Viewer +The custom viewer, is based on a react site statically bundled into an electron app. +I chose this approach, as OvenMediaEngine provides a library for embedding a stream in a website, which handles all the player and related logic making it very easy to use. + +One detail is that it requires some extra information provided as command line arguments, like the ID of the stream to watch and a secret key to authenticate against OvenMediaEngine. + +# Limitations +Although the current system works, there are still quite a bit of short comings. + +## IPv6 only +Because OvenMediaEngine uses direct UDP streams between the server and the viewers, the server requires a publicly reachable address. +However in my homelab setup, where this is hosted, I only have public IPv6 address and no public IPv4, meaning that only people with IPv6 can use the current setup. + +This could be solved by either getting ahold of some public IPv4 addresses for my servers (very unlikely) or I could maybe use some of the more advanced features of OvenMediaEngine, which includes streaming to "satelite" servers, which then serve the viewers. +Basically instead of the source server streaming to the viewers directly, it forwards the stream to these other servers, which then forward it to the viewers. +This would allow me to have an external server with both IPv4 and IPv6, which can basically proxy all the streams, but it is unlikely that I will do this as it would incur more costs and maintenance for limited benefits. + +## OBS not bundled +Basically everything required for the plugin to work properly and as good as possible, is bundled together so there is just one install. +However I have not found a good way to achieve this with OBS and especially certain OBS settings. +Like I mentioned before, the websocket server that the plugin is using to configure OBS, has to be enabled before the plugin can actually use it, all parameters about the websocket server can be configured via the cli apart from actually enabling it. + +This just creates some really unexpected pain-points in my experience. + +## Stream IDs can become mismatched +Currently the plugin is just using the teamspeak ID of a user as its stream ID, as that makes it very easy to determine the stream ID of anyone I want to watch. +However the teamspeak ID changes whenever a user disconnects from the teamspeak, so if someone: +1. starts a stream +2. disconnects +3. reconnects + +Then noone will be able to view their currently running stream, as it was started under their old teamspeak ID which has now changed. # Conclusion -TODO +Overall I am pretty happy with this setup and plugin now. +Obviously there are things to improve and its kind of hard to explain to someone for the first time, but once everything has been setup once, it actually works suprisingly well. +The main issue currently is the limitation to IPv6, as I have friends whose internet provider does not give them an IPv6 address for some reason.