{"id":19798572,"url":"https://github.com/seb0xff/custom-audio-broadcaster","last_synced_at":"2026-05-19T15:01:50.896Z","repository":{"id":218619062,"uuid":"746860788","full_name":"seb0xff/custom-audio-broadcaster","owner":"seb0xff","description":"A simple C++ broadcasting library fro audio coming from custom sources (e.g. generated by a program).","archived":false,"fork":false,"pushed_at":"2024-12-22T13:09:12.000Z","size":204,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-28T16:43:26.599Z","etag":null,"topics":["audio-streaming","broadcast","cpp","custom-audio","gstreamer","hls","rtmp","rtsp","srt","webrtc"],"latest_commit_sha":null,"homepage":"","language":"C++","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/seb0xff.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}},"created_at":"2024-01-22T20:18:16.000Z","updated_at":"2024-12-22T13:09:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"6f8e5e8e-4909-48d3-9221-66f652170237","html_url":"https://github.com/seb0xff/custom-audio-broadcaster","commit_stats":null,"previous_names":["sebastianpilarz/custom-audio-broadcaster","seb0xff/custom-audio-broadcaster"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/seb0xff/custom-audio-broadcaster","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seb0xff%2Fcustom-audio-broadcaster","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seb0xff%2Fcustom-audio-broadcaster/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seb0xff%2Fcustom-audio-broadcaster/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seb0xff%2Fcustom-audio-broadcaster/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seb0xff","download_url":"https://codeload.github.com/seb0xff/custom-audio-broadcaster/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seb0xff%2Fcustom-audio-broadcaster/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264232304,"owners_count":23576814,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["audio-streaming","broadcast","cpp","custom-audio","gstreamer","hls","rtmp","rtsp","srt","webrtc"],"created_at":"2024-11-12T07:30:20.888Z","updated_at":"2026-05-19T15:01:50.801Z","avatar_url":"https://github.com/seb0xff.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# custom-audio-broadcaster\n\nA simple C++ broadcasting library for audio coming from custom sources (e.g. generated by a program).\n\nThe library interface allows to:\n\n- create and delete rooms\n- get information about rooms\n- kick clients from rooms\n- publish/unpublish audio streams\n- publish/unpublish custom text data\n\n**Note:** This library is still under development and doesn't provide any security mechanism like authentication or encryption.\nThe library is currently only tested on macOs.\n\n## Installation\n\nThe library depends on [gstreamer](https://gstreamer.freedesktop.org/) and [mediamtx](https://github.com/bluenviron/mediamtx).\n\nOn macOs we can install them using homebrew:\n\n```bash\nbrew install gstreamer\nbrew install mediamtx\n```\n\nClone the repo to your project for example into `external` subdirectory\n\n**Note:** You need to enable http api of mediamtx in its configuration file (api: yes).\n\n## Usage\n\nThe following example shows how to broadcast audio from a custom wave generator.\n\n#### Server\n\n```bash\nmediamtx # start media server\n```\n\n```cpp\n#include \u003ciostream\u003e\n#include \"broadcaster.hpp\"\n#include \"json.hpp\"\n\nusing json = nlohmann::json;\n\nint main()\n{\n\n  //  a broadcaster object that will be used to create and delete rooms and publish audio.\n  Broadcaster broadcaster;\n  // we create a new room with path \"/test\", title \"Test room\", description \"This is a test room\" and max number of clients 10 (by default there's no limit).\n  broadcaster.create_new_room(\"test\", \"Test room\", \"This is a test room\", 10);\n\n  // we can get all available rooms\n  const auto rooms = broadcaster.get_rooms();\n  for (const auto \u0026room : rooms)\n  {\n    std::cout \u003c\u003c room.to_json().dump(2) \u003c\u003c std::endl;\n  }\n\n  // This is our custom audio generator.\n  const auto data_provider = [](uint8_t *buffer, int chunk_size, int sample_rate)\n  {\n    static float a = 0, b = 1, c = 0, d = 1;\n    int num_samples = chunk_size / 2; /* Because each sample is 16 bits */\n    int16_t *raw = (int16_t *)buffer;\n    c += d;\n    d -= c / 1000;\n    float freq = 1100 + 1000 * d;\n    for (int i = 0; i \u003c num_samples; i++)\n    {\n      a += b;\n      b -= a / freq;\n      raw[i] = (int16_t)(500 * a);\n    }\n    return num_samples;\n  };\n\n  // We Add custom text data to the room that can be queried by clients using GET /rooms/\u003croom_path\u003e/data\n  broadcaster.publish_text_data(\"test\", [](json \u0026data)\n                                { data[\"greeting\"] = \"Hello from /test room!\";\n                                data[\"goodbye\"] = \"Goodbye from /test\"; });\n  broadcaster.publish_audio(\"test\", data_provider, GST_AUDIO_FORMAT_S16);\n  int i = 0;\n  while (i++ \u003c 100)\n  {\n    std::this_thread::sleep_for(std::chrono::seconds(1));\n    std::cout \u003c\u003c \"running...\" \u003c\u003c std::endl;\n  }\n\n  // This is how we can unpublish\n  // These two will be called automatically when broadcaster is destroyed or when we delete the room.\n  broadcaster.unpublish_audio(\"test\");\n  broadcaster.unpublish_text_data(\"test\");\n  return 0;\n}\n```\n\nAs you can see audio publisher function gets buffer that can be filled with raw data. The generator function needs to return the number of samples it generated (it's needed for timestamping). We can cast the buffer to many different types, but we need to specify appropriate format in the `publish_audio` function. Possible formats resides in `gstreamer/1.22.8_2/include/gstreamer-1.0/gst/audio/audio-format.h`.\nfor example:\n`GST_AUDIO_FORMAT_U16` - unsigned 16 bit\n`GST_AUDIO_FORMAT_F32BE` - float 32 bit big endian\n\nSimilarly we can publish custom text data that can be queried by clients using GET /rooms/\u003croom_path\u003e/data. The publisher function gets json object that can be filled with data.\n\n###### Build\n\n**Note:** it assumes that the library is cloned into `external` subdir of your project.\n\n```cmake\ncmake_minimum_required(VERSION 3.15.3)\nproject(example)\n\nset(CMAKE_CXX_STANDARD 20)\n\nadd_executable(example example.cpp)\n\nadd_subdirectory(external/custom-audio-broadcaster)\ntarget_link_libraries(example PRIVATE broadcaster)\n```\n\n#### Client\n\nTo test it out can use my example [client](https://github.com/seb0xff/custom-audio-broadcaster-client).\n\nBasically there's one endpoint you want to use: /v1/rooms, to list all available rooms and their urls and metadata.\n\nLet's query the server for all available rooms:\n\n```bash\ncurl -X GET http://localhost:3000/v1/rooms\n```\n\n**Note:** Ip and port are the ones that we specified when creating the broadcaster object earlier.\n\nThis is our response:\n\n```javascript\n{\n  \"rooms\": [\n    {\n      \"audioUrls\": {\n        \"hls\": \"http://localhost:8888/test/index.m3u8\",\n        \"rtmp\": \"rtmp://localhost:1935/test\",\n        \"rtsp\": \"rtsp://localhost:8554/test\",\n        \"srt\": \"srt://localhost:8890?streamid=read:test\",\n        \"webrtc\": \"http://localhost:8889/test\"\n      },\n      \"currentClientsNumber\": 0,\n      \"description\": \"This is a test room\",\n      \"maxClientsNumber\": 10,\n      \"path\": \"/test\",\n      \"dataUrl\": \"localhost:3000/v1/rooms/test/data\",\n      \"title\": \"Test room\"\n    }\n  ]\n}\n```\n\nNow we can use the `audioUrls` to listen to the audio stream.\nTo test it without developing client, we can just open it\nin the web browser by using the `webrtc` url. We can also use tools like `ffmpeg`, `gstreamer` or any other player that supports above protocols.\n\n```bash\nffplay rtsp://localhost:8554/test # ffmpeg (rtsp)\ngst-play-1.0 srt://localhost:8890?streamid=read:test # gstreamer (srt)\n```\n\nTo get the custom text data we can use the `textDataUrl`:\n\n```bash\ncurl -X GET http://localhost:3000/v1/rooms/test/data\n```\n\nThis is our response:\n\n```javascript\n{\n\t\"goodbye\": \"Goodbye from /test\",\n\t\"greeting\": \"Hello from /test room!\"\n}\n```\n\nIt may be empty string if no text data is published.\n\nIf the given room doesn't exist, the response will be:\n\n```javascript\n{\n  \"errorMessage\": \"Room does not exist\"\n}\n```\n\nwith response code 404.\n\n**Note** Comression used for the audio stream is currently fixed to `opus`.\n\n## License\n\nMIT license (© 2023 seb0xff)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseb0xff%2Fcustom-audio-broadcaster","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseb0xff%2Fcustom-audio-broadcaster","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseb0xff%2Fcustom-audio-broadcaster/lists"}