This page shows you how to create a digital video recorder (DVR) session from a live stream using the Live Stream API. You can view a DVR session during a live stream as well as after it ends.
Differences between DVR sessions and channel clips
DVR sessions are similar to channel clips (also known as VOD clips) with the following key differences:
- DVR sessions:
- The API saves the DVR manifest in the same location as the live stream segments so there is no additional copying to Cloud Storage. The DVR manifest is similar to the live stream manifest but longer. When the retention window expires, the manifest is deleted along with the segment files.
- You can create a DVR session for past, current, and future content. For example, a DVR session can follow a live stream, or you can schedule a DVR session to start and stop at a future time.
- A typical use case for DVR sessions is to support DVR capabilities for live streaming events. For example, a viewer can join the live stream one hour after it begins and view the content with a one hour lag (or skip parts of it).
- Channel clips:
- The Live Stream API copies the clip manifest and the associated segment files to a user-specified directory so they are not deleted when the retention window expires. You have complete control of the clip.
- Only past content can be clipped. Live clips and scheduling future clips are not supported.
- A typical use case for clips is to archive a live stream, making the live stream available as a VOD file indefinitely.
For more information on channel clips, see Create VOD clips from a live stream.
Set up your Google Cloud project and authentication
If you have not created a Google Cloud project and credentials, see Before you begin.Create an input endpoint
To create an input endpoint, use the
projects.locations.inputs.create
method.
Before using any of the request data, make the following replacements:
PROJECT_NUMBER
: your Google Cloud project number; this is located in the Project number field on the IAM Settings pageLOCATION
: the location in which to create the input endpoint; use one of the supported regionsShow locationsus-central1
us-east1
us-east4
us-west1
us-west2
northamerica-northeast1
southamerica-east1
asia-east1
asia-east2
asia-south1
asia-northeast1
asia-southeast1
australia-southeast1
europe-north1
europe-west1
europe-west2
europe-west3
europe-west4
INPUT_ID
: a user-defined identifier for the new input endpoint to create (to which you send your input stream). This value must be 1-63 characters, begin and end with[a-z0-9]
, and can contain dashes (-) between characters. For example,my-input
.
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": CREATE_TIME, "target": "projects/PROJECT_NUMBER/locations/LOCATION/inputs/INPUT_ID", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
This command creates a long-running operation (LRO) that you can use to track the progress of your request. See Manage long-running operations for more information.
Get input endpoint details
To get the details of the input endpoint, use the
projects.locations.inputs.get
method.
Before using any of the request data, make the following replacements:
PROJECT_NUMBER
: your Google Cloud project number; this is located in the Project number field on the IAM Settings pageLOCATION
: the location where your input endpoint is located; use one of the supported regionsShow locationsus-central1
us-east1
us-east4
us-west1
us-west2
northamerica-northeast1
southamerica-east1
asia-east1
asia-east2
asia-south1
asia-northeast1
asia-southeast1
australia-southeast1
europe-north1
europe-west1
europe-west2
europe-west3
europe-west4
INPUT_ID
: the user-defined identifier for the input endpoint
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/inputs/INPUT_ID", "createTime": CREATE_TIME, "updateTime": UPDATE_TIME, "type": "RTMP_PUSH", "uri": "INPUT_STREAM_URI", # For example, "rtmp://1.2.3.4/live/b8ebdd94-c8d9-4d88-a16e-b963c43a953b", "tier": "HD" }
Find the uri
field and copy the returned
INPUT_STREAM_URI to use later
in the Send the input test stream section.
Create a channel
To create a channel, use the
projects.locations.channels.create
method. The following
samples create a channel that generates an HLS live stream. The live stream
consists of a single, high-definition (1280x720) rendition.
To enable the creation of DVR sessions, add the
retentionConfig
object to the channel configuration.
"retentionConfig": {
"retentionWindowDuration": {
"seconds": 86400
}
},
When retention is enabled for a live stream channel, the live stream segments
and manifest are retained in order to create DVR sessions. The
retentionWindowDuration
object specifies the
length of time for which the live stream output is saved after being uploaded to
Cloud Storage. The retention window begins at the time the segment is
created in Cloud Storage.
The retention window is limited to 30 days. After the retention window has passed, the segment files, live stream manifest, and DVR manifest are automatically deleted from Cloud Storage. You can't create DVR sessions using deleted segments. The deletion process is asynchronous and may take up to 24 hours to complete.
Specify a key for the manifest to enable DVR session creation. You refer to this key when actually creating the session. Only HLS manifests are supported.
"manifests": [
{
...
"key": "manifest_hls"
}
Before using any of the request data, make the following replacements:
PROJECT_NUMBER
: your Google Cloud project number; this is located in the Project number field on the IAM Settings pageLOCATION
: the location in which to create the channel; use one of the supported regionsShow locationsus-central1
us-east1
us-east4
us-west1
us-west2
northamerica-northeast1
southamerica-east1
asia-east1
asia-east2
asia-south1
asia-northeast1
asia-southeast1
australia-southeast1
europe-north1
europe-west1
europe-west2
europe-west3
europe-west4
CHANNEL_ID
: a user-defined identifier for the channel to create; this value must be 1-63 characters, begin and end with[a-z0-9]
, and can contain dashes (-) between charactersINPUT_ID
: the user-defined identifier for the input endpointBUCKET_NAME
: the name of the Cloud Storage bucket you created to hold the live stream manifest and segment files
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": CREATE_TIME, "target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
This command creates a long-running operation (LRO) that you can use to track the progress of your request. See Manage long-running operations for more information.
Start the channel
To start a channel, use the projects.locations.channels.start
method.
Before using any of the request data, make the following replacements:
PROJECT_NUMBER
: your Google Cloud project number; this is located in the Project number field on the IAM Settings pageLOCATION
: the location where your channel is located; use one of the supported regionsShow locationsus-central1
us-east1
us-east4
us-west1
us-west2
northamerica-northeast1
southamerica-east1
asia-east1
asia-east2
asia-south1
asia-northeast1
asia-southeast1
australia-southeast1
europe-north1
europe-west1
europe-west2
europe-west3
europe-west4
CHANNEL_ID
: a user-defined identifier for the channel
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": CREATE_TIME, "target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID", "verb": "start", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
This command creates a long-running operation (LRO) that you can use to track the progress of your request. See Manage long-running operations for more information.
Send the input test stream
Open a new terminal window. Run the following command, using INPUT_STREAM_URI from the Get input endpoint details section:
ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \
-acodec aac -vcodec h264 -f flv INPUT_STREAM_URI
Create a DVR session
To create a DVR session, use the
projects.locations.channels.dvrSessions.create
method.
Use the manifestKey
field in the
dvrManifests
array to specify the manifest to save content
from. In the example channel configuration on this page, this
key is set to manifest_hls
.
You can combine multiple time sections from the live stream into a single DVR
session by adding timeInterval
objects to the
dvrWindows
array.
"dvrManifests": [
{
"manifestKey": "manifest_hls"
}
],
"dvrWindows": [
{
"timeInterval": {
"startTime": "2022-07-08T23:03:20.000Z",
"endTime": "2022-07-08T23:04:20.000Z"
}
},
{
"timeInterval": {
"startTime": "2022-07-08T23:05:20.000Z",
"endTime": "2022-07-08T23:06:20.000Z"
}
}
]
Note the following:
- Each DVR session must contain at least one
timeInterval
indvrWindows
. - The
dvrManifests.manifestKey
field must refer to a defined HLS manifest in the DVR session's parent channel. If the DVR session creation request succeeds, then the URI of the generated DVR manifest is returned in thedvrManifests.outputUri
field. This URI is in the path specified by the channel'soutputUri
field. - The
dvrManifests
array supports only one manifest per request. If you want to generate multiple manifests for the same DVR windows, then you need to split the manifests into multiple DVR sessions. - The set of
timeInterval
objects must be non-overlapping and in chronological order. ThestartTime
must be earlier than theendTime
in everytimeInterval
. - The
startTime
andendTime
refer to the live stream timeline. If embedded timecode is enabled for the manifest, this timeline is based on the embedded timecode provided in the input stream and may differ from the wall clock. - The maximum total duration for the DVR window is 24 hours.
- The
endTime
of the lasttimeInterval
indvrWindows
can be left empty. In this case, theendTime
is automatically calculated to maximize the DVR session duration (that is, a total duration of 24 hours). - The DVR windows can cover any time range, including those in the future.
However, the number of DVR sessions with
dvrWindows
extending to a future time is limited to one. - There is no limit on the number of DVR sessions where all DVR windows are strictly in the past.
Before using any of the request data, make the following replacements:
PROJECT_NUMBER
: your Google Cloud project number; this is located in the Project number field on the IAM Settings pageLOCATION
: the location where your channel is located; use one of the supported regionsShow locationsus-central1
us-east1
us-east4
us-west1
us-west2
northamerica-northeast1
southamerica-east1
asia-east1
asia-east2
asia-south1
asia-northeast1
asia-southeast1
australia-southeast1
europe-north1
europe-west1
europe-west2
europe-west3
europe-west4
CHANNEL_ID
: a user-defined identifier for the channelDVR_SESSION_ID
: a user-defined identifier for the DVR sessionINTERVAL_START_TIME
: the mark-in Unix epoch time in the original live stream manifest; uses a timestamp in RFC3339 UTC "Zulu" format (for example,2014-10-02T15:01:23Z
)INTERVAL_END_TIME
: the mark-out Unix epoch time in the original live stream manifest; uses a timestamp in RFC3339 UTC "Zulu" format (for example,2014-10-02T15:01:23Z
)
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/OPERATION_ID", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": CREATE_TIME, "target": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID/dvrSessions/DVR_SESSION_ID", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
This command creates a long-running operation (LRO) that you can use to track the progress of your request. See Manage long-running operations for more information.
Get the DVR session
To get a DVR session, use the
projects.locations.channels.dvrSessions.get
method.
Before using any of the request data, make the following replacements:
PROJECT_NUMBER
: your Google Cloud project number; this is located in the Project number field on the IAM Settings pageLOCATION
: the location where your channel is located; use one of the supported regionsShow locationsus-central1
us-east1
us-east4
us-west1
us-west2
northamerica-northeast1
southamerica-east1
asia-east1
asia-east2
asia-south1
asia-northeast1
asia-southeast1
australia-southeast1
europe-north1
europe-west1
europe-west2
europe-west3
europe-west4
CHANNEL_ID
: a user-defined identifier for the channelDVR_SESSION_ID
: a user-defined identifier for the DVR session
To send your request, expand one of these options:
You should receive a JSON response similar to the following:
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/channels/CHANNEL_ID/dvrSessions/DVR_SESSION_ID", "createTime": CREATE_TIME, "startTime": START_TIME, "updateTime": UPDATE_TIME, "state": "SUCCEEDED", "dvrManifests": [ { "manifestKey": "manifest_hls", "outputUri": "gs://BUCKET_NAME/dvr/DVR_SESSION_ID/main.m3u8" } ], "dvrWindows": [ { "timeInterval": { "startTime": "INTERVAL_START_TIME", "endTime": "INTERVAL_END_TIME" } } ] }
The response should contain a state
field that indicates
the state of the session:
{
...
"state": "PENDING" // DVR session is waiting to be processed (for example, it is waiting for the channel to start)
...
}
See the state
reference documentation for the list of
states and their descriptions.
Verify bucket contents
Open the Cloud Storage bucket as specified in the DVR session's
dvrManifests.outputUri
field. Verify that it
contains the following files and directories:
- A top-level manifest for the DVR session with the same name as the
manifests.fileName
specified in the channel configuration (for example,main.m3u8
). You can play this manifest using an online media player. - A subdirectory for each
muxStreams.key
specified in the channel (for example,mux_video_ts
). Each subdirectory contains a playlist for the DVR session (for example,index-1.m3u8
).
Play the DVR session
To play the generated media file in Shaka Player, complete the following steps:
- Make the Cloud Storage bucket you created publicly readable.
- To enable cross-origin resource
sharing (CORS) on a Cloud Storage bucket, do the following:
- Create a JSON file that contains the following:
[ { "origin": ["https://shaka-player-demo.appspot.com/"], "responseHeader": ["Content-Type", "Range"], "method": ["GET", "HEAD"], "maxAgeSeconds": 3600 } ]
-
Run the following command after replacing
JSON_FILE_NAME
with the name of the JSON file you created in the previous step:gcloud storage buckets update gs://BUCKET_NAME --cors-file=JSON_FILE_NAME.json
- Create a JSON file that contains the following:
- In the Cloud Storage bucket, find the generated file. Click Copy URL in the file's Public access column.
- Navigate to Shaka Player, an online live stream player.
- Click Custom Content in the top navigation bar.
- Click the + button.
Paste the public URL of the file into the Manifest URL box.
Type a name in the Name box.
Click Save.
Click Play.
You should see a test pattern play as the live stream.
Ad break events
If you created an ad break event for the live stream, the DVR session contains the ad segments as they appear in the live stream.