{"id":51532923,"url":"https://github.com/robocup-ssl/ssl-streaming-package","last_synced_at":"2026-07-09T05:01:07.725Z","repository":{"id":365766175,"uuid":"1273369463","full_name":"RoboCup-SSL/ssl-streaming-package","owner":"RoboCup-SSL","description":"Everything regarding streaming a proper Small Size League match to YouTube","archived":false,"fork":false,"pushed_at":"2026-06-28T15:13:35.000Z","size":7563,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T16:10:24.812Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RoboCup-SSL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-18T13:05:33.000Z","updated_at":"2026-06-28T15:13:38.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/RoboCup-SSL/ssl-streaming-package","commit_stats":null,"previous_names":["robocup-ssl/ssl-streaming-package"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RoboCup-SSL/ssl-streaming-package","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoboCup-SSL%2Fssl-streaming-package","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoboCup-SSL%2Fssl-streaming-package/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoboCup-SSL%2Fssl-streaming-package/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoboCup-SSL%2Fssl-streaming-package/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RoboCup-SSL","download_url":"https://codeload.github.com/RoboCup-SSL/ssl-streaming-package/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoboCup-SSL%2Fssl-streaming-package/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35287403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-07-09T05:01:06.726Z","updated_at":"2026-07-09T05:01:07.709Z","avatar_url":"https://github.com/RoboCup-SSL.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SSL Streaming Package\n\nAn out-of-the-box streaming setup for the [RoboCup Small Size League](https://ssl.robocup.org/).\nThe RoboCup Small Size League (SSL) is an autonomous robot soccer competition where teams\nof miniature robots (each fitting within an 18 cm diameter circle) play fast-paced,\n11-vs-11 or 6-vs-6 matches.\n\nThe goal of this package is to make SSL livestreams **professional by default** — so that a\nvolunteer operator at any event (international, regional, or a spontaneous match anywhere in\nthe world), who knows Linux and programming but not OBS or video production, can produce a\nclean, watchable, shareable stream with minimal setup and little room to get things wrong.\n\n## Quickstart (deploy a field)\n\n```bash\ngit clone \u003crepo\u003e \u0026\u0026 cd ssl-streaming-package\n./setup.sh                            # installs uv + Python deps + the MediaMTX binary\ncp field.toml.example field.toml      # edit: [cameras], OBS url/password, source names\n./run.sh                              # validates config, starts MediaMTX + live-data\n# then: import the OBS scene collection, launch OBS, go live\n```\n\n`field.toml` (repo root) is the **only** file you edit per field. To bring up another field,\ncopy the repo and change its `[cameras]` block. `Ctrl-C` on `run.sh` stops everything it\nstarted (MediaMTX + the ffmpeg camera feeds). Target OS: Ubuntu 24+ (the MediaMTX download is\ncross-platform; Windows is untested).\n\n## Status \u0026 roadmap\n\nEarly scaffolding. The project ships in incremental MVPs, each delivering standalone value.\nSee [`MVP.md`](MVP.md) for the full rationale.\n\n| Milestone | Theme | Scope |\n|---|---|---|\n| **MVP1** | *Looks pro, manual* | Pre-built OBS template (1.1, 1.2, 1.3, 1.5) + Game-Controller text push (2.2) + Python controller skeleton (2.0) + operator handbook. Operator drives streams/scenes/commentary manually inside a polished template. |\n| **MVP2** | *Runs itself* | Per-match auto streaming (2.1, first in line) + automatic scene switching (2.3). Unattended fallback when no operator is available. |\n| **Later** | *Enhancements* | Digital ball-zoom (2.4), commentator replay (1.4), AR overlays + calibration (3.x), MediaMTX manager (4.x), Windows support. |\n\n**Operating model:** thin-first. The professional look lives in a shared OBS template. By\ndefault the operator does everything manually (with a beginner handbook); the Python\ncontroller starts as a live-data feeder and grows into a full unattended mode.\n\n---\n\n## Field infrastructure — Hardware\n\nAt the RoboCup, all the matches will be streamed. Each soccer field will have multiple\ncameras around it, and one streaming pc. The cameras are all somehow connected to this\nstreaming pc (via ethernet rtsp, hdmi capture cards, spi capture cards, etc). The streaming\nPC will run an OBS instance, which will take all these cameras, use them to create multiple\nscenes, and it will livestream to youtube. The streaming PC will also have a microphone for\na commentator, as well as a commentator-facing webcam.\n\n## Field infrastructure — Software\n\nA second computer, owned and controlled by the league committee, will run the small size\nleague software. This includes:\n\n- **The game controller.** The game controller is responsible from deciding and announcing\n  the current state of the game. This includes match phase such as first half, half time,\n  second half, penalty shootout, match over, etc. It also includes match state such as free\n  kick, penalty, normal play, yellow card, foul, etc.\n\n- **The AutoRef.** The autoref does many things, but only relevant now is that it broadcasts\n  the location of the 12 (divb) or 22 (diva) robots + the ball on the soccer field.\n\n- **Vision software** (either legacy SSL-Vision, or the newer Vision-Processor). The vision\n  software is responsible for using multiple field overhead cameras to find where the robots\n  + ball are, and send this raw data to the autoref. The autoref then uses filters to create\n  a coherent world view, which it then broadcasts. Additionally, the vision software\n  broadcasts the geometry of the field such as width, height, line thickness, etc.\n\nThe three software packages mentioned above all communicate via protobuf.\n\nThe livestream will ideally support multiple features.\n\n## 1. OBS basics\n\n- **1.1.** When switching cameras, the scenes should fade into eachother.\n- **1.2.** The commentator-facing webcam feed should be embedded / overlayed on top of the\n  field-facing camera feeds, so that viewers will see mainly the field, and the commentators\n  on the side of the video (\"field-with-commentator feed\").\n- **1.3.** When switching from field-with-commentator feed to \"commentator feed\" (meaning\n  fullscreen commentator, no field), or vice versa, OBS should play a custom stinger.\n- **1.4.** The commentator should be able to replay the last few seconds of his feed, where\n  only the video is replayed, but the audio is not. This will allow the commentator to replay\n  for example goals, fouls, while commentating on these. A second custom stinger should be\n  played when going into the \"replay feed\".\n- **1.5.** All the feeds should support custom banners / logo overlays.\n\n## 2. Autonomous OBS control\n\n**Preface:** A python script will control OBS via the websocket interface. This python\nscript will run next to OBS localhost on the same machine. It's able to listen to all the\nprotobuf messages from the game controller, autoref, and vision software mentioned above.\nAdditionally, it will have a file with the schedule.\n\n- **2.1.** It might occur that there are no commentators available to start or stop the\n  livestreams. The python script should be able to automatically start and stop the\n  livestream based on the schedule + time of day and the messages from the Game Controller\n  (such as NORMAL_FIRST_HALF_PRE and POST_GAME and team names). Every match will have its own\n  livestream url, meaning a different YouTube key. Python should also be able to handle this.\n  The matches will be manually pre-scheduled on YouTube.\n- **2.2.** The python script should be able to push text (such as team names / scores / next\n  up matches) towards OBS, so that OBS can render this text dynamically.\n- **2.3.** The python script should be able to switch to scenes / banners automatically (live\n  match, half time, post match with score etc. Scenes + banners are to be determined).\n- **2.4.** The python script should be able to zoom in a camera feed on the location of the\n  ball. This is a simply digital zoom. In no way is the actual camera controlled, only its\n  feed is transformed within OBS.\n\n## 3. Dynamic overlays / Augmented reality\n\n**Preface:** The robots are small and the ball is even smaller. The robots move fast and all\nlook alike. This makes it difficult for spectators to see what's going on. video feed\noverlays could provide a solution. Clear colors could be rendered under / around the robots,\nand the location of the ball could be indicated with a big circle around it. This does come\nwith some challenges:\n\n- **Challenge 1:** Each camera has to be calibrated towards the field. A transformation\n  matrix will need to be determined to map field x-y coordinates to pixels.\n- **Challenge 2:** The overlay rendering has to be fast. Ideally, given a 30fps, the\n  rendering shouldn't take more that 1/30s of a second.\n\n- **3.1.** The overlay should be sent as a separate stream to OBS, using an alpha background.\n  This allows OBS to optionally render it on top of the corresponding camera feed.\n- **3.2.** The overlay should be able to indicate the position of the ball.\n- **3.3.** The overlay should be able to indicate the team to which robots belong (either\n  yellow or blue).\n- **3.4.** A \"calibration program\" should allow the users to open a webcam stream, and click\n  on certain points in the field. Using these points, a calibration matrix is generated.\n- **3.5.** An \"overlay program\" should be able to open both a video feed and a corresponding\n  calibration matrix, and push out an overlay video feed with an alpha background.\n\n## 4. MediaMTX manager\n\n**Preface:** Multiple programs have been detected which need access to the video feeds. OBS,\n\"calibration program\", \"overlay program\". To faciliate this access, a MediaMTX instance will\nbe placed in the middle of it all. It will be the hub through which all video streams +\noverlay streams flow. Webcam / camera streams will be registered at MediaMTX, which will be\npulled by the aforementioned programs. The \"overlay program\" will also push its overlay\ntowards MediaMTX, which will be pulled by OBS. MediaMTX however doesn't seem to have a\nconvenient interface, or even an command line interface.\n\n- **4.1.** Users can register video feeds within MediaMTX, meaning ip address / usb port +\n  endpoint.\n- **4.2.** Users can remove video feeds within MediaMTX, given an endpoint.\n\n## 5. Package deployment\n\n**Preface:** This is a meta feature regarding the management of this entire project. What I\nwant is a single monorepo containing all of these separate projects. Each project should\nstand on its own, meaning all communication between programs will go via TCP / UDP /\nWebSockets etc. The entire project should be able to be bundled up easily for deployment on a\ncomputer. The project will target ubuntu 24+ computers, but windows compability would be a\nnice to have (but not required).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobocup-ssl%2Fssl-streaming-package","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobocup-ssl%2Fssl-streaming-package","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobocup-ssl%2Fssl-streaming-package/lists"}