implement wildcard streams + playback configuration webhook
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 88
- Forks
- 37
- PR merge metrics
- No merged PRs in 30d
Description
Part 1: Wildcard streams
Currently, UGC platforms building on top of the Livepeer API would have to create a new Stream object for each user. That's not ideal; if I want to update my bitrate ladder site-wide, I'd have to iterate through every single stream definition! So, let's allow one stream to be used multiple times.
Streams get a new field: {"wildcard": true/false}.
If false, current behavior:
Ingest URL: rmtp://${ server }/live/${ streamKey }
Playback URL: https://${ cdn }/hls/${ playbackKey }/index.m3u8 All is well.
If true, each streaming endpoint can be used multiple times. (And probably streaming to the root endpoint is not allowed.)
Ingest URL: rtmp://${ server }/live/${ streamKey }+${ anything }
Playback URL: https://${ cdn }/hls/${ playbackKey }%2B${ anything }/index.m3u8
To implement this part, all we need to do is add the field on the server then tweak the logic on mist-api-connector to handle URLs in such a form.
Part 2: Playback configuration webhook
That alone will be sufficient for lots of use cases, but there's also a problem for the primary UGC use case... there's only one secret streamKey. if they use ingest URLs of the form rtmp://example.com/live/streamKey+userName, that means anyone can stream to any user by using rtmp://example.com/live/streamKey+otherUserName!
The solution here is to allow for UGC platforms to provide internal stream keys to their users and then provide the playbackId to Livepeer during the resolution of the streamStarted webhook. In this example, imagine I'm implementing a service called Stream.Town. The workflow will look like this:
- Before anyone streams, I create a Stream ` object with my desired renditions. It has:
POST /api/stream
{
...rendition configuration omitted
"wildcard": true
}
201 Created
{
"id": "livepeer-id",
"streamKey": "livepeer-stream-key",
"playbackId": "livepeer-playback-id"
}
- I also create a webhook for the streamStarted event of that stream:
POST /api/webhook
{
eventType: "streamStarted",
streamId: "livepeer-id",
url: "https://stream.town/api/handle-webhook"
}
- A user signs up on Stream.Town. When they sign up, I provide them with a stream key and save it in their user record in the Stream.Town database:
{
"username": "iameli",
"streamKey": "streamtown-stream-key"
}
- On the StreamTown frontend, I geolocate (
GET /api/ingest) then provide them with their RTMP ingest URL:rtmp://some-origin.livepeer.com/live/livepeer-stream-key+streamtown-stream-key. - The user streams in. A series of webhooks fire, and stream.town returns the playbackId during the streamStarted event.
POST https://stream.town/api/handle-webhook
{
"stream": {
"id": "livepeer-id",
"playbackId": "livepeer-playback-id"
...
}
"streamKey": "streamtown-stream-key"
}
I proceed to check my database for streamtown-stream-key, and find that it corresponds to the user iameli. So I send that back from the webhook:
200 OK
{
"playbackId": "iameli"
}
- That playbackId gets inserted into the newly-created Stream Session as
livepeer-playback-id+iameliand used for playback athttps://example-cdn.livepeer.com/hls/livepeer-playback-id%2Biameli/index.m3u8.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing Stream creation, stream-session handling, and webhook resolution, then inspect the mist-api-connector URL logic. Verify wildcard ingest and encoded playback URLs, the wildcard field, and the streamStarted playbackId response. Done means both workflows are supported without changing existing non-wildcard behavior, with coverage for the API and webhook paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, audio-video-rtc, backend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100