Multistream
Multistream allows a source stream and transcoded renditions to be pushed to multiple RTMP(S) or SRT targets, such as Twitch, Facebook Live, and YouTube Live. This guide will provide an understanding and use of multistream with the following:
- Stream Object
- Creating a Stream with Multistream Targets
- Manage Multistream Targets
- In the Livepeer Studio Dashboard
- With the API
- Understanding Multistream Performance
- Through the Livepeer Studio dashboard
- Through the API
The /stream
Object
To use a Multistream Target
, you need to reference it from a Stream
object.
The reference is made in the targets
sub-field of the multistream
field in
the Stream
resource (stream.multistream.targets[]
). It is represented as an
array of target reference objects, each with a profile
that should be
multistreamed and the id
of the corresponding Multistream Target
.
The profile
field must reference an existing transcoding profile on the same
stream, or "source"
to multistream the same original video as ingested. The
same profile can be multistreamed to several Multistream Targets
, but there can
be only 1 multistream to a given URL. You can also set the videoOnly
field to
true
to mute the stream audio and stream only a silent video to the target.
To avoid managing separate Multistream Target
objects, you can also create
targets inlined in the Stream
object on the same mutation request (create or
update). In that case, the target reference object in the multistream.targets
field should have a spec
instead of an id
with the payload for creating a
new Multistream Target
. Notice that spec
is a write-only field, meaning that
Stream
objects returned from reads (GET
) will always have only a profile
and id
in the targets. To get the current state of a Multistream Target
,
fetch from its own read API using that id
.
Creating a Stream with Multistream Targets
You can create a Stream
already with some Multistream Targets
. Either
reference an existing Multistream Target
by id
or create a new
Multistream Target
inline with the spec
field. You can also use both types
of targets on the same payload (reference and inline) as long as they are
separate entries in the multistream.targets
array.
Request by reference
curl -X POST 'https://livepeer.studio/api/stream' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"name": "test_multistream_reference",
"profiles": [
{ "name": "720p", ... },
{ "name": "480p", ... },
{ "name": "360p", ... }
],
"multistream": {
"targets": [
{ "id" :"0bf161f3-95bd-4971-a7b1-4dcb5d39e78a", "profile": "source" },
{ "id" :"95bd0bf1-61f3-a7b1-4971-39e78a4dcb5d", "profile": "720p" }
]
}
}
Response
{
"lastSeen": 0,
"isActive": false,
"record": false,
"suspended": false,
"sourceSegments": 0,
"transcodedSegments": 0,
"sourceSegmentsDuration": 0,
"transcodedSegmentsDuration": 0,
"sourceBytes": 0,
"transcodedBytes": 0,
"profiles": [
{
"name": "720p",
"bitrate": 2000000,
"fps": 30,
"width": 1280,
"height": 720
},
{
"name": "480p",
"bitrate": 1000000,
"fps": 30,
"width": 854,
"height": 480
},
{
"name": "360p",
"bitrate": 500000,
"fps": 30,
"width": 640,
"height": 360
}
],
"name": "test_multistream_reference",
"multistream": {
"targets": [
{
"id": "936aad06-2165-48d7-bec3-41d4af328281",
"profile": "source"
},
{
"id": "36e73bf6-92bb-49cc-838a-2831ef746ecf",
"profile": "720p"
}
]
},
"kind": "stream",
"userId": "eada599f-3d58-499b-ba24-c7f3faf988de",
"renditions": {},
"id": "f9f8de67-f032-4efd-af77-a664538596e7",
"createdAt": 1656436202327,
"streamKey": "f9f8-tesi-a2co-187v",
"playbackId": "f9f8nwl0eou5lxv4",
"createdByTokenName": "Test"
}
Request by inline
curl -X POST 'https://livepeer.studio/api/stream' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"name": "test_multistream_reference",
"profiles": [
{ "name": "720p", ... },
{ "name": "480p", ... },
{ "name": "360p", ... }
],
"multistream": {
"targets": [
{
"profile": "720p",
"videoOnly": true,
"spec": {
"name": "Eli\'s Twitch",
"url": "rtmp://rtmp.twitch.tv/live/SECRET"
}
},
{
"profile": "360p",
"spec": { "url": "rtmp://rtmp.twitter.com/SECRET" }
}
]
}
}
Response by inline
{
"lastSeen": 0,
"isActive": false,
"record": false,
"suspended": false,
"sourceSegments": 0,
"transcodedSegments": 0,
"sourceSegmentsDuration": 0,
"transcodedSegmentsDuration": 0,
"sourceBytes": 0,
"transcodedBytes": 0,
"profiles": [
{
"name": "720p",
"bitrate": 2000000,
"fps": 30,
"width": 1280,
"height": 720
},
{
"name": "480p",
"bitrate": 1000000,
"fps": 30,
"width": 854,
"height": 480
},
{
"name": "360p",
"bitrate": 500000,
"fps": 30,
"width": 640,
"height": 360
}
],
"name": "test_multistream_reference",
"multistream": {
"targets": [
{
"profile": "720p",
"videoOnly": true,
"id": "936aad06-2165-48d7-bec3-41d4af328281"
},
{
"profile": "360p",
"id": "36e73bf6-92bb-49cc-838a-2831ef746ecf"
}
]
},
"kind": "stream",
"userId": "eada599f-3d58-499b-ba24-c7f3faf988de",
"renditions": {},
"id": "",
"createdAt": 1656435768386,
"streamKey": "cf00-nkaf-odbr-dqib",
"playbackId": "cf00sa2snftzfj5p",
"createdByTokenName": "Test"
}
Updating Multistream Targets of a Stream
You can also update an existing Stream
to add or remove Multistream Targets
.
The schema of all fields is the same as the creation API, with the targets being
referenced with an id
or created inline with a spec
. You can also add,
remove or update multiple Multistream Targets
on the same API call.
Note: Changes to an existing
Stream
will only take effect when the next stream session is started.
Adding Multistream Targets
Since you can combine inlined and referenced Multistream Targets
on the same
request, it's really easy to add a target by URL to an existing stream:
Request
1. GET
the current state of the Stream
curl 'https://livepeer.studio/api/stream/{id}' \
-H 'authorization: Bearer {api-key}'
Response
{
"name": "test_multistream_reference",
"profiles": [
{ "name": "720p", ... },
{ "name": "480p", ... },
{ "name": "360p", ... }
],
"multistream": {
"targets": [
{ "id" :"0bf161f3-95bd-4971-a7b1-4dcb5d39e78a", "profile": "source" },
{ "id" :"95bd0bf1-61f3-a7b1-4971-39e78a4dcb5d", "profile": "720p" }
]
}
}
Patch Request
PATCH
the Stream with the new target.
PATCH
can also add new Multistream Targets
by id
instead of inline, just
like on Stream
creation.
curl -X PATCH 'https://livepeer.studio/api/stream/{id}' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"multistream": {
"targets": [
{ "id" :"0bf161f3-95bd-4971-a7b1-4dcb5d39e78a", "profile": "source" },
{ "id" :"95bd0bf1-61f3-a7b1-4971-39e78a4dcb5d", "profile": "720p" },
{ "profile": "720p", "spec": {"url": "rtmp://rtmp.twitter.com/SECRET"} }
]
}
}'
Patch Response
The response should be a 204
Removing Multistream Targets
To remove a Multistream Target
from a Stream
, you can use the same PATCH
request as above to either remove or completely clear the multistream.targets
array.
After removing the reference from the Stream
, you can also delete the
Multistream Target
object completely by calling the separate
Delete Multistream Target
API.
Note: Make sure that no other
Stream
has a reference to thatMultistream Target
before doing so.
Removing a single Multistream Target
To remove a specific target, we need to make a PATCH
request maintaining only
the targets that we want to keep in the stream, after removing the desired one.
For Example:
Request
This request removes only the first target from the example above.
curl -X PATCH 'https://livepeer.studio/api/stream/{id}' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"multistream": {
"targets": [
{ "id" :"95bd0bf1-61f3-a7b1-4971-39e78a4dcb5d", "profile": "720p" }
]
}
}'
Response
The response should be a 204
We kept only the remaining targets in the PATCH
, i.e. the second one.
Note: Additionally, you can use a single API call to change the
profile
that should be multistreamed to a specific target by changing theprofile
field for the given target when building thePATCH
request payload.
Removing all Multistream Targets
Request
curl -X PATCH 'https://livepeer.studio/api/stream/{id}' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"multistream": {
"targets": []
}
}'
Response
The response should be a 204
Manage Multistream targets in the Livepeer Studio Dashboard
To add, manage, and delete Multistream Targets
, navigate to the Streams page
(livepeer.studio/dashboard/streams)
and click on a stream name. On the stream detail page, on the Overview
tab,
you can view all configured targets. You must configure new
Multistream Targets
for each stream. This will apply the multistream
configuration to that stream. Multistream Targets
do not carry over when you
create new streams.
To add a new target, select Create
on the right side of the
Multistream Targets
section. You'll be asked to name your target, provide the
Ingest URL and a stream key, being Ingest URL the only required value. The
Ingest URL and stream key should be provided by the platform that you're
streaming into and can be of the RTMP, RTMPS or SRT protocols. Select the
rendition profile that you'd like to send to that target and click
Create Target
. Once created, you can toggle the targets on and off.
To edit a Multistream Target
, click on the three dots to the right of the
target name and then on Edit
to open up the target settings. Select
Update target
when you've completed your changes.
To delete a multistream target, click on the three dots to the right of the
target name and then on Delete
.
Note: Any changes to
Multistream Targets
, including creating new targets, will apply only to the next active session. If you make changes while a stream is active, those changes will not apply until the current session has ended and a new session begins.
Managing Multistream targets with the API
About Multistream Target Objects
You can also manage Multistream Target
objects, /multistream/target
, from
the API. Each target represents a specific endpoint where a stream could be
multistreamed to. See details in the API reference.
Notice that the existence of a Multistream Target
object itself is not enough
for the multistream to happen. You also need to reference the target from the
Stream
object that should be multistreamed. To avoid managing the separate
Multistream Target
objects, you can also create the targets inlined in the
Stream
creation and update APIs. See: the
Stream Object section for more information.
Create Targets inlined in the Stream
creation
Request
curl -X POST 'https://livepeer.studio/api/multistream/target' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"name": "Eli\'s Twitch",
"url": "rtmp://rtmp.twitch.tv/live/SECRET"
}'
Note: Supported Protocols --
RTMP, RTMPS and SRT.
Response
{
"id": "{id}",
"userId": "USER123",
"name": "Eli's Twitch",
"url": "rtmp://rtmp.twitch.tv/live/SECRET"
}
Read
You can fetch a specific Multistream Target
with their ID, returned on the
creation request. The destination url will not be returned since it contains
sensitive user data. This way the application developer doesn't have to worry
about storing and securing their users' stream keys.
Request
GET /api/multistream/target/{id}
curl 'https://livepeer.studio/api/multistream/target/{id}' \
-H 'authorization: Bearer {api-key}'
Response
{
"id": "{id}",
"userId": "USER123",
"name": "Eli's Twitch"
}
List
You can also list all existing Multistream Targets
in the account by omitting
the {id}
segment in the above request.
Request
curl 'https://livepeer.studio/api/multistream/target' \
-H 'authorization: Bearer {api-key}'
Response
The response is an array of Multistream Target
objects, as returned from the
read API above. The pagination should be done exactly the same as the other
Livepeer Studio list APIs.
Update
You can change an existing target properties at will, and it will affect any stream that is currently using it. Notice that changes will only take effect when the next stream session is started.
One of the updateable properties is the disabled
field. It can be used to
disable multistreaming to a specific target without the need of removing them
from streams nor deleting the target completely.
Request
PATCH /api/multistream/target/{id}
curl -X PATCH 'https://livepeer.studio/api/multistream/target/{id}' \
-H 'content-type: application/json' \
-H 'authorization: Bearer {api-key}' \
-d '{
"name": "Not Eli\'s Twitch",
"url": "rtmp://rtmp.twitter.com/SECRET",
"disabled": true
}'
Response
All request fields are optional. There is no response on a success (HTTP
204 No Content
).
Delete
Finally, you can also delete a Multistream Target
object completely by calling
the delete API. You should not do this if any Streams
are still referencing
that target or a broken reference will be left. So first update (PATCH
) any
Stream
removing the reference to the Multistream Target
and only then
actually delete it.
Request
DELETE /api/multistream/target/{id}
curl -X DELETE 'https://livepeer.studio/api/multistream/target/{id}' \
-H 'authorization: Bearer {api-key}'
Response
There is no response on a success (HTTP 204 No Content
).
Understanding Multistream Performance
Dashboard
While a session is active that has multistream targets configured, you'll be able to see if a destination is "Active" or "Offline". NOTE: There may be a slight delay between starting the stream and the push destinations connecting. When starting to stream to multistream targets, use these indicators to understand whether it has connected to its target(s).
On the stream page where you've configured your multistream targets, select the "Health" tab at the top. While a session is active, you'll see the ingest rate of the source stream.
API
We have 3 webhooks to help you monitor the state of your Multistream Targets
::
multistream.connected
: When we have successfully connected to theMultistream Target
and you're also online in the other service you are multistreaming to.multistream.error
: In case any error has occurred during connection to theMultistream Target
. This means some kind of problem with the configuration or the other service you are multistreaming to.multistream.disconnected
: Sent after a stream is ended to indicate that Multistream has also ended for the respective target.