Stream Manager 2.0 Restreamer Example – RTMP Push
Several scenarios are supported:
- Immediate: Begin pushing an existing stream immediately, returning any error
- With retries: Begin pushing an existing or soon-to-be-created stream, retrying for a limited time
- Persist: Create a standing order to push a given stream any time it may exist
Note that for simplicity when testing, in these examples we push the stream right back to the same origin (with a new name). This way the examples do not depend on external resources. However in any real use case you would specify some external rtmpUri
and would probably not loop back to localhost
.
These examples also assume there is a stream manager at as-test1.example.org
and that a NodeGroup exists, named nodegroup1
. The NodeGroup is assumed to have nodes capable of PUBLISH and SUBSCRIBE (whether all-in-one or arranged into origins/edges).
Immediate
In this use case, we want to begin pushing an existing stream immediately, returning any error.
First, you should be publishing live/stream1
.
Second, create a restreamer provision:
restreamer-rtmp-push-sm-immediate.json
[
{
"provisionGuid": "social1",
"streams": [
{
"streamGuid": "live/stream1",
"abrLevel": 0,
"camParams": {
"properties": {
"action": "create",
"type": "rtmp-push",
"rtmpUri": "rtmp://localhost/live/social1",
"immediate": "true",
"persist": "false"
}
}
}
]
}
]
Of note: immediate
is true
, and persist
is false
(or not present; default is false).
Create Provision API call:
curl -s -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT}" -X POST --data @restreamer-rtmp-push-sm-immediate.json https://as-test1.example.org/as/v1/streams/provision/nodegroup1
At this point we can List Provisions to find our new provision:
curl -s -H "Authorization: Bearer ${JWT}" https://as-test1.example.org/as/v1/streams/provision/nodegroup1 | json_pp
Now that the Restreamer provision exists, any call to Get Server for Publish must include the restream=true
flag to indicate intent to distribute this provision.
Further, because the provision specifies "immediate": "true"
, when the provision is distributed, the Restreamer Plugin will immediately try to forward the stream and return a synchronous response. If it responds 200 OK, we are restreaming. Or we expect an HTTP error status if there is some problem.
So let’s distribute our provision by calling Get Server for Publish:
curl -s -H "Content-Type: application/json" https://as-test1.example.org/as/v1/streams/stream/nodegroup1/publish/live/stream1?restream=true
Now the stream should be forwarding, so we should find a new stream live/social1
when we list all streams:
curl -s -H "Content-Type: application/json" https://as-test1.example.org/as/v1/streams/stream/nodegroup1?aggregate=false | json_pp
Later, when you wish to disable forwarding (or after the source stream has ended), delete the provision:
curl -s -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT}" -X DELETE https://as-test1.example.org/as/v1/streams/provision/nodegroup1/social1
With Retries
In this case, we want to begin pushing an existing or soon-to-be-created stream, retrying for a limited time. We will show the soon-to-be-created
case.
First, create a provison,
restreamer-rtmp-push-sm-retries.json
[
{
"provisionGuid": "social1",
"streams": [
{
"streamGuid": "live/stream1",
"abrLevel": 0,
"camParams": {
"properties": {
"action": "create",
"type": "rtmp-push",
"rtmpUri": "rtmp://localhost/live/social1",
"immediate": "false",
"attempts": "12",
"delayS": "10",
"persist": "false"
}
}
}
]
}
]
Of note: immediate
is false
, and persist
is false
. We define 12
attempts with 10
second delay between attempts (a total of 120 seconds). Therefore after we call Get Server for Publish to distribute the provision to an origin, we then have two minutes to begin publishing to that origin. After that time we would need to call Get Server for Publish again to begin a new round of retries.
Create Provision API call (note that Provision related functions require an authorized JWT):
curl -s -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT}" -X POST --data @restreamer-rtmp-push-sm-retries.json https://as-test1.example.org/as/v1/streams/provision/nodegroup1
At this point we can List Provisions to find our new provision:
curl -s -H "Authorization: Bearer ${JWT}" https://as-test1.example.org/as/v1/streams/provision/nodegroup1 | json_pp
Now let’s distribute our provision by calling Get Server for Publish (also starting our retries):
curl -s -H "Content-Type: application/json" https://as-test1.example.org/as/v1/streams/stream/nodegroup1/publish/live/stream1?restream=true
Then we will quickly publish (within two minutes) to the returned serverAddress
(here using ffmpeg
to publish via RTMP):
ffmpeg -stream_loop -1 -re -i test_video.mp4 -c:v libx264 -pix_fmt yuv420p -profile:v baseline -c:a aac -ar 48000 -b:a 128k -g 10 -ac 2 -b:v 500k -f flv rtmp://203.0.113.42:1935/live/stream1
Now the stream should be forwarding, so we should find a new stream live/social1
when we list all streams:
curl -s -H "Content-Type: application/json" https://as-test1.example.org/as/v1/streams/stream/nodegroup1?aggregate=false | json_pp
Later, when you wish to disable forwarding (or after the source stream has ended), delete the provision:
curl -s -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT}" -X DELETE https://as-test1.example.org/as/v1/streams/provision/nodegroup1/social1
Persist
In this case, we want to create a standing order to push a given stream any time it may exist. While the stream could exist before creating the provision, for the sake of example we will assume it does not.
First, create a provison,
restreamer-rtmp-push-sm-persist.json
[
{
"provisionGuid": "social1",
"streams": [
{
"streamGuid": "live/stream1",
"abrLevel": 0,
"camParams": {
"properties": {
"action": "create",
"type": "rtmp-push",
"rtmpUri": "rtmp://localhost/live/social1",
"immediate": "false",
"persist": "true"
}
}
}
]
}
]
Of note: immediate
is false
, and persist
is true
.
Create Provision API call:
curl -s -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT}" -X POST --data @restreamer-rtmp-push-sm-persist.json https://as-test1.example.org/as/v1/streams/provision/nodegroup1
At this point we can List Provisions to find our new provision:
curl -s -H "Authorization: Bearer ${JWT}" https://as-test1.example.org/as/v1/streams/provision/nodegroup1 | json_pp
Now let’s distribute our provision by calling Get Server for Publish:
curl -s -H "Content-Type: application/json" https://as-test1.example.org/as/v1/streams/stream/nodegroup1/publish/live/stream1?restream=true
At this point — if the source stream was already live, then forwarding will begin. Otherwise, forwarding will begin when the stream does exist. Also, because of the persist
flag, once the provision has been distributed (with Get Server for Publish), the Stream Manager will keep it distributed, continually attempting to forwarding the stream. Any time the stream is published, it will begin forwarding until the provision has been deleted.
Next publish to the returned serverAddress
(here using ffmpeg
to publish via RTMP):
ffmpeg -stream_loop -1 -re -i test_video.mp4 -c:v libx264 -pix_fmt yuv420p -profile:v baseline -c:a aac -ar 48000 -b:a 128k -g 10 -ac 2 -b:v 500k -f flv rtmp://203.0.113.42:1935/live/stream1
Now the stream should be forwarding, so we should find a new stream live/social1
when we list all streams:
curl -s -H "Content-Type: application/json" https://as-test1.example.org/as/v1/streams/stream/nodegroup1?aggregate=false | json_pp
Now if you stop ffmpeg
(with Ctrl-C) and after a while start it again, the source stream will begin forwarding again (repeat the previous two steps).
Later, when you wish to disable forwarding (or after the source stream has ended), delete the provision:
curl -s -H "Content-Type: application/json" -H "Authorization: Bearer ${JWT}" -X DELETE https://as-test1.example.org/as/v1/streams/provision/nodegroup1/social1