Stream API
Bunny Stream was designed for developers to easily upload, process, and display videos in any type of use-case.
Setup
<?php
require 'vendor/autoload.php';
use ToshY\BunnyNet\Client\BunnyClient;
use ToshY\BunnyNet\StreamAPI;
$bunnyClient = new BunnyClient(
client: new \Symfony\Component\HttpClient\Psr18Client()
);
// Provide the specific video library API key.
$streamApi = new StreamAPI(
apiKey: '710d5fb6-d923-43d6-87f8-ea65c09e76dc',
client: $bunnyClient
);
Usage
Manage Collections
Get Collection
$streamApi->getCollection(
libraryId: 1,
collectionId: '97f20caa-649b-4302-9f6e-1d286e0da144',
query: [
'includeThumbnails' => true,
],
);
Note
- If the query parameter
includeThumbnails
is set totrue
, the response item(s) will include a non-empty array keypreviewImageUrls
containing the URLs for the corresponding image thumbnails.
Update Collection
$streamApi->updateCollection(
libraryId: 1,
collectionId: '97f20caa-649b-4302-9f6e-1d286e0da144',
body: [
'name' => 'Bunny Hopping Collection V2',
],
);
Delete Collection
$streamApi->deleteCollection(
libraryId: 1,
collectionId: '97f20caa-649b-4302-9f6e-1d286e0da144',
);
List Collections
$streamApi->listCollections(
libraryId: 1,
query: [
'page' => 1,
'perPage' => 100,
'search' => 'bunny',
'orderBy' => 'date',
'includeThumbnails' => true,
],
);
Note
- If the query parameter
includeThumbnails
is set totrue
, the response item(s) will include a non-empty array keypreviewImageUrls
containing the URLs for the corresponding image thumbnails.
Create Collection
$streamApi->createCollection(
libraryId: 1,
body: [
'name' => 'Bunny Collection',
],
);
Manage Videos
Get Video
$streamApi->getVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
);
Update Video
$streamApi->updateVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
body: [
'title' => 'Bunny Hoppers',
'collectionId' => '97f20caa-649b-4302-9f6e-1d286e0da144',
'chapters' => [
[
'title' => 'Chapter 1',
'start' => 0,
'end' => 300,
],
[
'title' => 'Chapter 2',
'start' => 301,
'end' => 500,
],
],
'moments' => [
[
'label' => 'Awesome Scene 1',
'timestamp' => 70,
],
[
'label' => 'Awesome Scene 2',
'timestamp' => 120,
],
],
'metaTags' => [
[
'property' => 'description',
'value' => 'My Video Description',
],
[
'property' => 'robots',
'value' => 'noindex,nofollow',
],
],
],
);
Delete Video
$streamApi->deleteVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
);
Create Video
$streamApi->createVideo(
libraryId: 1,
body: [
'title' => 'Bunny Hoppers',
'collectionId' => '97f20caa-649b-4302-9f6e-1d286e0da144',
],
);
Note
- The
title
does not need to match the video filename and/or extension you're intending to upload. - A
collectionId
is not required. - The response returns the video's GUID, which is required for video upload (see Upload Video).
Upload Video
/*
* File contents read into string from the local filesystem.
*/
$content = file_get_contents('./bunny-hop.mp4');
/*
* File contents handle from a `$filesystem` (Flysystem FtpAdapter).
*/
$content = $filesystem->readStream('./bunny-hop.mp4');
// Upload video.
$streamApi->uploadVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
body: $content,
query: [
'enabledResolutions' => '240p,360p,480p,720p,1080p,1440p,2160p',
],
);
Get Video Heatmap
$streamApi->getVideoHeatmap(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
);
Warning
- This endpoint currently returns a
500
status code with the following response:
A support ticket has been created at bunny.net regarding this issue.Internal Server Error
Get Video Play Data
$streamApi->getVideoPlayData(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
query: [
'token' => 'ead85f9a-578b-42b7-985f-9a578b12b776',
'expires' => 3600,
],
);
Get Video Statistics
$streamApi->getVideoStatistics(
libraryId: 1,
query: [
'dateFrom' => 'm-d-Y',
'dateTo' => 'm-d-Y',
'hourly' => false,
'videoGuid' => 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
],
);
Re-encode Video
$streamApi->reEncodeVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
);
Repackage Video
$streamApi->repackageVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
query: [
'keepOriginalFiles' => true,
],
);
Note
- This method allows repackaging of videos for libraries that have Enterprise DRM enabled.
List Videos
$streamApi->listVideos(
libraryId: 1,
query: [
'page' => 1,
'itemsPerPage' => 100,
'search' => 'bunny',
'collection' => '97f20caa-649b-4302-9f6e-1d286e0da144',
'orderBy' => 'date',
],
);
Set Thumbnail
$streamApi->setThumbnail(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
query: [
'thumbnailUrl' => 'https://cdn.example.com/thumbnail.jpg',
],
);
Set Thumbnail (by body)
/*
* File contents read into string from the local filesystem.
*/
$content = file_get_contents('./thumbnail.jpg');
/*
* File contents handle from a `$filesystem` (Flysystem FtpAdapter).
*/
$content = $filesystem->readStream('./thumbnail.jpg');
// Set video thumbnail by body contents.
$streamApi->setThumbnailByBody(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
body: $content,
headers: [
'Content-Type' => 'image/jpeg',
],
);
Note
- This method allows for uploading a thumbnail based on body contents.
Warning
- Adding a thumbnail by uploading body contents is not documented in the official Bunny.net API specification for the Set Thumbnail endpoint.
Fetch Video
$streamApi->fetchVideo(
libraryId: 1,
body: [
'url' => 'https://example.com/bunny-hop.mp4',
'headers' => [
'newKey' => 'New Value',
'newKey-1' => 'New Value 1',
'newKey-2' => 'New Value 2',
],
],
query: [
'collectionId' => '97f20caa-649b-4302-9f6e-1d286e0da144',
],
);
Add Caption
$streamApi->addCaption(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
sourceLanguage: 'ja',
body: [
'srclang' => 'ja',
'label' => 'Subtitles (Japanese)',
'captionsFile' => 'MQowMDowMDowMCwwMDAgLS0+IDAwOjAxOjAwLDAwMApOZXZlciBnb25uYSBnaXZlIHlvdSB1cC4K',
],
);
Note
- The
sourceLanguage
/srclang
should be an ISO 639-1 / ISO 639-3 language abbreviation. - The
captionsFile
requires the file contents to be sent as a base64 encoded string.
Delete Caption
$streamApi->deleteCaption(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
sourceLanguage: 'ja',
);
Note
- The
sourceLanguage
should be an ISO 639-1 / ISO 639-3 language abbreviation.
Warning
- If a caption was created with a specific ISO standard for the
sourceLanguage
, then you have to delete it with the same standard. Example: a caption created withsourceLanguage
ISO 639-1 can only be deleted by sending a request withsourceLanguage
ISO 639-1. - This endpoint will always return a
200
status code, even if the subtitle with specificiedsourceLanguage
does not exist.
Tip
- If you (regularly) update captions make sure to purge the captions directory associated with the video. If it's not purged you might notice outdated subtitles displayed on the video. You can get the URL for the captions directory by using the Get Video Play Data endpoint.
Transcribe Video
$streamApi->transcribeVideo(
libraryId: 1,
videoId: 'e7e9b99a-ea2a-434a-b200-f6615e7b6abd',
query: [
'language' => 'fi',
'force' => true,
],
);
Note
- The
language
is a two-letter (set 1) language abbreviation for transcribing the video. - Once a video has transcribed you need to set
force
totrue
in order to force a new transcription to be added.
Get OEmbed
$streamApi->getOEmbed(
query: [
'url' => 'https://iframe.mediadelivery.net/embed/182595/8a800e53-c949-46d0-8818-af566f032ec1',
'maxWidth' => 1280,
'maxHeight' => 720,
'token' => 'ead85f9a-578b-42b7-985f-9a578b12b776',
'expires' => 3600,
],
);
Note
- The
url
is a required query parameter.