{"id":13643665,"url":"https://github.com/livekit/ingress","last_synced_at":"2025-07-29T12:17:29.720Z","repository":{"id":64298466,"uuid":"458046043","full_name":"livekit/ingress","owner":"livekit","description":"Ingest streams (RTMP/WHIP) or files (HLS, MP4) to LiveKit WebRTC","archived":false,"fork":false,"pushed_at":"2025-07-26T21:06:28.000Z","size":1747,"stargazers_count":123,"open_issues_count":35,"forks_count":50,"subscribers_count":18,"default_branch":"main","last_synced_at":"2025-07-27T01:09:42.887Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/livekit.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-02-11T04:31:28.000Z","updated_at":"2025-07-25T10:53:28.000Z","dependencies_parsed_at":"2023-10-14T20:47:45.929Z","dependency_job_id":"3d240bed-747b-419d-8ec5-474502dd51db","html_url":"https://github.com/livekit/ingress","commit_stats":{"total_commits":88,"total_committers":8,"mean_commits":11.0,"dds":0.3522727272727273,"last_synced_commit":"60a3987b31ba38e799ef450a68a1c45454eb89b7"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/livekit/ingress","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fingress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fingress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fingress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fingress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/livekit","download_url":"https://codeload.github.com/livekit/ingress/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livekit%2Fingress/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267303318,"owners_count":24066524,"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","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"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":"2024-08-02T01:01:51.003Z","updated_at":"2025-07-29T12:17:29.712Z","avatar_url":"https://github.com/livekit.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"\u003c!--BEGIN_BANNER_IMAGE--\u003e\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"/.github/banner_dark.png\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"/.github/banner_light.png\"\u003e\n  \u003cimg style=\"width:100%;\" alt=\"The LiveKit icon, the name of the repository and some sample code in the background.\" src=\"https://raw.githubusercontent.com/livekit/ingress/main/.github/banner_light.png\"\u003e\n\u003c/picture\u003e\n\n\u003c!--END_BANNER_IMAGE--\u003e\n\n# LiveKit Ingress\n\n\u003c!--BEGIN_DESCRIPTION--\u003e\nWebRTC is proving to be a versatile and scalable transport protocol both for media ingestion and delivery. However, some applications may require integrating with existing workflows or equipment that do not support WebRTC. Universal Ingress provides a way to send media that was generated using such workflows to a LiveKit room.\n\u003c!--END_DESCRIPTION--\u003e\n\n## Capabilities\n\nUniversal Ingress is meant to be a versatile service supporting a variety of protocols, both using a push and pull model. Currently, the following protcols are supported:\n- RTMP\n- WHIP (https://datatracker.ietf.org/doc/draft-ietf-wish-whip/)\n\n## Supported Output\n\nThe Ingress service will automatically transcode the source media to ensure compatibility with WebRTC. It can publish multiple layers with [Simulcast](https://blog.livekit.io/an-introduction-to-webrtc-simulcast-6c5f1f6402eb/). The parameters of the different video layers can be defined at ingress creation time. \n\n## Documentation\n\n### Push workflow\n\nTo push media to the Ingress, the workflow goes like this:\n\n* create an Ingress with `CreateIngress` API (to livekit-server)\n* `CreateIngress` returns a URL that can be used to push media to\n* copy and paste the URL into your streaming workflow\n* start the stream\n* Ingress starts receiving data\n* Ingress joins the LiveKit room and publishes transcoded media\n\n### Service Architecture\n\nThe Ingress service and the LiveKit server communicate over Redis. Redis is also used as storage for the Ingress session state. The Ingress service must also expose a public IP address for the publishing endpoint streamers will connect to. In a typical cluster setup, this IP address would be assigned to a load balancer that would forward incoming connection to an available Ingress service instance. The targeted Ingress instance will then validate the incoming request with the LiveKit server using Redis as RPC transport. \n\n### Config\n\nThe Ingress service takes a YAML config file:\n\n```yaml\n# required fields\napi_key: livekit server api key. LIVEKIT_API_KEY env can be used instead\napi_secret: livekit server api secret. LIVEKIT_API_SECRET env can be used instead\nws_url: livekit server websocket url. LIVEKIT_WS_URL env can be used instead\nredis:\n  address: must be the same redis address used by your livekit server\n  username: redis username\n  password: redis password\n  db: redis db\n\n# optional fields\nhealth_port: if used, will open an http port for health checks\nprometheus_port: port used to collect prometheus metrics. Used for autoscaling\nlog_level: debug, info, warn, or error (default info)\nrtmp_port: port to listen to incoming RTMP connection on (default 1935)\nwhip_port: port to listen to incoming WHIP calls on (default 8080)\nhttp_relay_port: port used to relay data from the main service process to the per ingress handler process (default 9090)\nrtc_config: configuration for ICE and other RTC related settings, same settings livekit-server RTC configuration. Used for WHIP.\n\n# cpu costs for various Ingress types with their default values\ncpu_cost:\n  rtmp_cpu_cost: 2.0\n  whip_cpu_cost: 2.0\n```\n\nThe config file can be added to a mounted volume with its location passed in the INGRESS_CONFIG_FILE env var, or its body can be passed in the INGRESS_CONFIG_BODY env var.\n\nIn order for the LiveKit server to be able to create Ingress sessions, an `ingress` section must also be added to the livekit-server configuration:\n\n```yaml\ningress:\n  rtmp_base_url: RTMP url prefix pointing to the Ingress external IP address or load balancer\n  whip_base_url: WHIP url prefix pointing to the Ingress external IP address or load balancer\n```\n\nFor instance:\n```yaml\ningress:\n  rtmp_base_url: rtmp://my.domain.com/x\n  whip_base_url: http://my.domain.com/w\n```\n\nA stream key will be appended to this prefix to generate the ingress session specific RTMP or WHIP publishing endpoint.\n\n### Using the Ingress service\n\n#### RTMP and WHIP\n\nThe first step in order to use the Ingress service is to create an ingress session and associate it with a room. This can be done with any of the server SDKs or with the [livekit-cli](https://github.com/livekit/livekit-cli). The syntax with the livekit-cli is as follow:\n\n```shell\nlivekit-cli create-ingress \\\n  --request \u003cpath to Ingress creation request JSON file\u003e\n```\n\nThe request creation JSON file uses the following syntax:\n\n```json\n{\n    \"input_type\": 0 for RTMP, 1 for WHIP\n    \"name\": Name of the Ingress,\n    \"room_name\": Name of the room to connect to,\n    \"participant_identity\": Unique identity for the room participant the Ingress service will connect as,\n    \"participant_name\": Name displayed in the room for the participant\n}\n```\n\nOn success, `livekit-cli` will return the unique id for the Ingress. \n\nIt is possible to get details on all created Ingress with the `list-ingress` command:\n\n```shell\nlivekit-cli list-ingress\n```\n\nIn particular, this will return the RTMP url WHIP endpoint to use to setup the encoder. \n\n### Running locally\n\n#### Running natively\n\nThe Ingress service can be run natively on any platform supported by GStreamer.\n\n##### Prerequisites\n\nThe Ingress service is built in Go. Go \u003e= 1.18 is needed. The following [GStreamer](https://gstreamer.freedesktop.org/) libraries and headers must be installed:\n- gstreamer\n- gst-plugins-base\n- gst-plugins-good\n- gst-plugins-bad\n- gst-plugins-ugly\n- gst-libav\n\nOn MacOS, these can be installed using [Homebrew](https://brew.sh/) by running `mage bootstrap`. \n\n##### Building\n\nBuild the Ingress service by running:\n\n```shell\nmage build\n````\n\n##### Running the service\n\nTo run against a local LiveKit server, a redis server must be running locally. All servers must be configured to communicate over localhost. Create a file named `config.yaml` with the following content:\n\n```yaml\nlog_level: debug\napi_key: \u003cyour-api-key\u003e\napi_secret: \u003cyour-api-secret\u003e\nws_url: ws://localhost:7880\nredis:\n  address: localhost:6379\n```\n\nOn MacOS, if GStreamer was installed using Homebrew, the following environment must be set in order to ensure that GStreamer can load all its plugins:\n\n```shell\nexport DYLD_LIBRARY_PATH=/opt/homebrew/lib\n```\n\nThen to run the service:\n\n```shell\ningress --config=config.yaml\n```\n\nIf starting an Ingress fails with a GStreamer error such as `Failed to load libsoup library` or `no such element factory \"souphttpsrc`, try deleting your GStreamer plugin registry with:\n\n```shell \nrm -rf ~/.cache/gstreamer-1.0/\n```\n\n#### Running with Docker\n\nTo run against a local LiveKit server, a Redis server must be running locally. The Ingress service must be instructed to connect to LiveKit server and Redis on the host. The host network is accessible from within the container on IP:\n- host.docker.internal on MacOS and Windows\n- 172.17.0.1 on linux\n\nCreate a file named `config.yaml` with the following content:\n\n```yaml\nlog_level: debug\napi_key: \u003cyour-api-key\u003e\napi_secret: \u003cyour-api-secret\u003e\nws_url: ws://host.docker.internal:7880 (or ws://172.17.0.1:7880 on linux)\nredis:\n  address: host.docker.internal:6379 (or 172.17.0.1:6379 on linux)\n```\n\nIn order to be able to use establish WHIP sessions over UDP, the container must be run with host networking enabled. \n\nThen to run the service:\n\n```shell\ndocker run --rm \\\n    -e INGRESS_CONFIG_BODY=\"`cat config.yaml`\" \\\n    -p 1935:1935 \\\n    -p 8080:8080 \\\n    --network host \\\n    livekit/ingress\n```\n\n\u003c!--BEGIN_REPO_NAV--\u003e\n\u003cbr/\u003e\u003ctable\u003e\n\u003cthead\u003e\u003ctr\u003e\u003cth colspan=\"2\"\u003eLiveKit Ecosystem\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\u003ctd\u003eLiveKit SDKs\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/client-sdk-js\"\u003eBrowser\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-swift\"\u003eiOS/macOS/visionOS\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-android\"\u003eAndroid\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-flutter\"\u003eFlutter\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-react-native\"\u003eReact Native\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/rust-sdks\"\u003eRust\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/node-sdks\"\u003eNode.js\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/python-sdks\"\u003ePython\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-unity\"\u003eUnity\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-unity-web\"\u003eUnity (WebGL)\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/client-sdk-esp32\"\u003eESP32\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eServer APIs\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/node-sdks\"\u003eNode.js\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/server-sdk-go\"\u003eGolang\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/server-sdk-ruby\"\u003eRuby\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/server-sdk-kotlin\"\u003eJava/Kotlin\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/python-sdks\"\u003ePython\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/rust-sdks\"\u003eRust\u003c/a\u003e · \u003ca href=\"https://github.com/agence104/livekit-server-sdk-php\"\u003ePHP (community)\u003c/a\u003e · \u003ca href=\"https://github.com/pabloFuente/livekit-server-sdk-dotnet\"\u003e.NET (community)\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eUI Components\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/components-js\"\u003eReact\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/components-android\"\u003eAndroid Compose\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/components-swift\"\u003eSwiftUI\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/components-flutter\"\u003eFlutter\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eAgents Frameworks\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/agents\"\u003ePython\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/agents-js\"\u003eNode.js\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/agent-playground\"\u003ePlayground\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eServices\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://github.com/livekit/livekit\"\u003eLiveKit server\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/egress\"\u003eEgress\u003c/a\u003e · \u003cb\u003eIngress\u003c/b\u003e · \u003ca href=\"https://github.com/livekit/sip\"\u003eSIP\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003c/tr\u003e\n\u003ctr\u003e\u003ctd\u003eResources\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://docs.livekit.io\"\u003eDocs\u003c/a\u003e · \u003ca href=\"https://github.com/livekit-examples\"\u003eExample apps\u003c/a\u003e · \u003ca href=\"https://livekit.io/cloud\"\u003eCloud\u003c/a\u003e · \u003ca href=\"https://docs.livekit.io/home/self-hosting/deployment\"\u003eSelf-hosting\u003c/a\u003e · \u003ca href=\"https://github.com/livekit/livekit-cli\"\u003eCLI\u003c/a\u003e\u003c/td\u003e\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c!--END_REPO_NAV--\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flivekit%2Fingress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flivekit%2Fingress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flivekit%2Fingress/lists"}