VOD with Access Control
Adding access control to a video on-demand only takes a few lines of code.
The example below uses useCreateAsset
and a webhook to create and watch a gated video on-demand.
The webhook
access control flow also works the same with Streams - this
example just shows it being used with Assets as a demonstration.
Create an Access Control Webhook Handler
Set up an endpoint (e.g., https://yourdomain.com/api/check-access (opens in a new tab)) to handle the logic for granting or denying access to your VOD assets. This endpoint should accept a POST request with a JSON payload containing the access key and webhook context.
This is an example of a payload this endpoint would receive:
{
"accessKey": "your-access-key",
"context": {
"assetId": "abcd1234",
"userId": "user5678"
},
"timestamp": 1680530722502
}
The payload in context
is defined by your application.
Register an Access Control Webhook
Use the Livepeer Studio dashboard to create a new webhook with the type playback.accessControl
and specify the URL of your access control endpoint.
https://livepeer.studio/dashboard/developers/webhooks (opens in a new tab)
You can then take the ID of the webhook you created and use it in the next step.
Create an asset with a playback policy webhook
You can now create an asset with a playback policy webhook, passing the ID of the webhook you created in Step 2.
import { useCreateAsset } from '@livepeer/react';
import { useCallback, useState, useMemo } from 'react';
import { useDropzone } from 'react-dropzone';
export const CreateAndViewAsset = () => {
const [video, setVideo] = useState<File | undefined>();
const {
mutate: createAsset,
data: asset,
status: createStatus,
progress,
error: createError,
} = useCreateAsset(
video
? {
sources: [
{
name: video.name,
file: video,
playbackPolicy: {
type: 'webhook',
// This is the id of the webhook you created in step 2
webhookId: '<webhook_id>',
webhookContext: {
// This is the context you want to pass to your webhook
// It can be anything you want, and it will be passed back to your webhook
},
},
},
] as const,
}
: null,
);
const onDrop = useCallback(async (acceptedFiles: File[]) => {
if (acceptedFiles && acceptedFiles.length > 0 && acceptedFiles?.[0]) {
setVideo(acceptedFiles[0]);
}
}, []);
const { getRootProps, getInputProps } = useDropzone({
accept: {
'video/*': ['*.mp4'],
},
maxFiles: 1,
onDrop,
});
const progressFormatted = useMemo(
() =>
progress?.[0].phase === 'failed'
? 'Failed to process video.'
: progress?.[0].phase === 'waiting'
? 'Waiting'
: progress?.[0].phase === 'uploading'
? `Uploading: ${Math.round(progress?.[0]?.progress * 100)}%`
: progress?.[0].phase === 'processing'
? `Processing: ${Math.round(progress?.[0].progress * 100)}%`
: null,
[progress],
);
return (
<>
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drag and drop or browse files</p>
</div>
{createError?.message && <p>{createError.message}</p>}
{video ? <p>{video.name}</p> : <p>Select a video file to upload.</p>}
{progressFormatted && <p>{progressFormatted}</p>}
<button
onClick={() => {
createAsset?.();
}}
disabled={!createAsset || createStatus === 'loading'}
>
Upload
</button>
</>
);
};
Configure the Player with an Access Key
If you are using the Livepeer.js Player, you can use the accessKey
prop to provide your custom access key, which is then passed to the webhook you created to verify that it is valid.
import { Player } from '@livepeer/react';
export const CreateAndViewAsset = () => {
const accessKey = getAccessKeyForYourApplication();
return <Player playbackId={playbackId} accessKey={accessKey} />;
};
If you are not using the player, you will need to manually append the access key to the m3u8 URL as a query parameter, similar to:
https://playback.livepeer.studio/asset/hls/abcd1234/index.m3u8?accessKey=your-access-key
Receive the Webhook from Livepeer
When a user attempts to access the VOD asset, Livepeer will call your access control endpoint with the access key and webhook context. Your endpoint should process the request and return a response indicating whether the stream access should be allowed or disallowed.
Here is an example request sent to your access control endpoint:
{
"context": {
// Same value from the `asset.playbackPolicy.webhookContext` field
},
"accessKey": "<access_key>" // this is exact value of the prop passed to the Player, or the query parameter
}
In your access control endpoint, implement the logic to verify the access key and decide whether to grant access to the VOD asset.
If the access is allowed, return a 2XX
response. Otherwise, the playback will be disallowed.
Wrap Up
That's it! Access control, added. You now have a solution for gating on-demand content with webhooks! This also works for streams as well.