Triggering renders from PHP
To trigger a Lambda render using PHP, you need to use the AWS SDK directly. Below you find a snippet showing the sample call to the AWS SDK. Note the following:
- You first need to complete the Lambda setup.
- Unstable API: The format that Remotion Lambda accepts can change in every version. You need to consult the history of this page to see the changes over time. This page always shows the latest version of the payload.
- Sending large input props (>200KB) is not supported with PHP at the moment.
remotion.phpphp
<?php// We'll assume you use Composer, which will add autoload.phprequire_once __DIR__ . '/vendor/autoload.php';use Aws\Lambda\LambdaClient;<?php// Specify your environment variables in a .env file$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);$dotenv->load();// Specify the region you deployed to, for example "us-east-1"$region = $_ENV['REMOTION_APP_REGION'];// Specify your S3 bucket name$bucketName = $_ENV['REMOTION_APP_BUCKET'];// Specify the function you would like to call$functionName = $_ENV['REMOTION_APP_FUNCTION_NAME'];// Specify the URL to your Webpack bundle$serveUrl = $_ENV["REMOTION_APP_SERVE_URL"];$credentials = null;// If you don't have credentials but want to retrieve them using STS, use the AssumeRole featureif ($_ENV["REMOTION_APP_IS_ASSUME_ROLE"] === true) {$credentials = assumeRole($_ENV["REMOTION_APP_REGION"],$_ENV["REMOTION_APP_ROLE_ARN"], $_ENV["REMOTION_APP_ROLE_SESSION_NAME"]);}$client = LambdaClient::factory(['version' => 'latest','region' => $region,'credentials' => $credentials,]);// Specify your input props here$data = array("data" => "");$input = serializeInputProps($data,$region,"video-or-audio",null);// Note that the payload format may change in any version.// This is the structure of the latest version.$params = array("serveUrl" => $serverUrl,"inputProps" => $input,"composition" => "main","type" => "start","codec" => "h264",// Specify the Remotion version you are using"version" => "3.3.82","codec" => "h264","imageFormat" => "jpeg","crf" => null,"envVariables" => array(),"quality" => 80,"maxRetries" => 1,"privacy" => 'public',"logLevel" => 'info',"frameRange" => null,"outName" => null,"timeoutInMilliseconds" => 30000,"chromiumOptions" => array(),"scale" => 1,"everyNthFrame" => 1,"numberOfGifLoops" => 0,"concurrencyPerLambda" => 1,"downloadBehavior" => array("type" => "play-in-browser",),"muted" => false,"overwrite" => false,"audioBitrate" => null,"videoBitrate" => null,"webhook" => null,"forceHeight" => null,"forceWidth" => null,"bucketName" => null,"audioCodec" => null,"forceBucketName" => $bucketName,"dumpBrowserLogs" => false,);try {// Invoke the Lambda function$result = $client->invoke(['InvocationType' => 'RequestResponse','FunctionName' => $functionName,'Payload' => json_encode($params),]);$json_response = $result['Payload']->getContents();echo $json_response;} catch (AwsException $e) {// Handle the exceptionecho $e->getMessage();}function serializeInputProps($inputProps, string $region, string $type, ?string $userSpecifiedBucketName): array{try {$payload = json_encode($inputProps);$hash = randomHash();$MAX_INLINE_PAYLOAD_SIZE = 200000;if (strlen($payload) > $MAX_INLINE_PAYLOAD_SIZE) {throw new Exception(sprintf("Warning: inputProps are over %dKB (%dKB) in size.\n This is not currently supported.",round($MAX_INLINE_PAYLOAD_SIZE / 1000),ceil(strlen($payload) / 1024)));}return ['type' => 'payload','payload' => $payload,];} catch (Exception $e) {throw new Exception('Error serializing inputProps. Check it has no circular references or reduce the size if the object is big.');}}function assumeRole($region, $ARN, $sessionName){try {$stsClient = new Aws\Sts\StsClient(['region' => $region,'version' => 'latest',]);$result = $stsClient->AssumeRole(['RoleArn' => $ARN,'RoleSessionName' => $sessionName,]);return ['key' => $result['Credentials']['AccessKeyId'],'secret' => $result['Credentials']['SecretAccessKey'],'token' => $result['Credentials']['SessionToken'],];} catch (AwsException $e) {// Handle the exceptionecho $e->getMessage();return null;}}
remotion.phpphp
<?php// We'll assume you use Composer, which will add autoload.phprequire_once __DIR__ . '/vendor/autoload.php';use Aws\Lambda\LambdaClient;<?php// Specify your environment variables in a .env file$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);$dotenv->load();// Specify the region you deployed to, for example "us-east-1"$region = $_ENV['REMOTION_APP_REGION'];// Specify your S3 bucket name$bucketName = $_ENV['REMOTION_APP_BUCKET'];// Specify the function you would like to call$functionName = $_ENV['REMOTION_APP_FUNCTION_NAME'];// Specify the URL to your Webpack bundle$serveUrl = $_ENV["REMOTION_APP_SERVE_URL"];$credentials = null;// If you don't have credentials but want to retrieve them using STS, use the AssumeRole featureif ($_ENV["REMOTION_APP_IS_ASSUME_ROLE"] === true) {$credentials = assumeRole($_ENV["REMOTION_APP_REGION"],$_ENV["REMOTION_APP_ROLE_ARN"], $_ENV["REMOTION_APP_ROLE_SESSION_NAME"]);}$client = LambdaClient::factory(['version' => 'latest','region' => $region,'credentials' => $credentials,]);// Specify your input props here$data = array("data" => "");$input = serializeInputProps($data,$region,"video-or-audio",null);// Note that the payload format may change in any version.// This is the structure of the latest version.$params = array("serveUrl" => $serverUrl,"inputProps" => $input,"composition" => "main","type" => "start","codec" => "h264",// Specify the Remotion version you are using"version" => "3.3.82","codec" => "h264","imageFormat" => "jpeg","crf" => null,"envVariables" => array(),"quality" => 80,"maxRetries" => 1,"privacy" => 'public',"logLevel" => 'info',"frameRange" => null,"outName" => null,"timeoutInMilliseconds" => 30000,"chromiumOptions" => array(),"scale" => 1,"everyNthFrame" => 1,"numberOfGifLoops" => 0,"concurrencyPerLambda" => 1,"downloadBehavior" => array("type" => "play-in-browser",),"muted" => false,"overwrite" => false,"audioBitrate" => null,"videoBitrate" => null,"webhook" => null,"forceHeight" => null,"forceWidth" => null,"bucketName" => null,"audioCodec" => null,"forceBucketName" => $bucketName,"dumpBrowserLogs" => false,);try {// Invoke the Lambda function$result = $client->invoke(['InvocationType' => 'RequestResponse','FunctionName' => $functionName,'Payload' => json_encode($params),]);$json_response = $result['Payload']->getContents();echo $json_response;} catch (AwsException $e) {// Handle the exceptionecho $e->getMessage();}function serializeInputProps($inputProps, string $region, string $type, ?string $userSpecifiedBucketName): array{try {$payload = json_encode($inputProps);$hash = randomHash();$MAX_INLINE_PAYLOAD_SIZE = 200000;if (strlen($payload) > $MAX_INLINE_PAYLOAD_SIZE) {throw new Exception(sprintf("Warning: inputProps are over %dKB (%dKB) in size.\n This is not currently supported.",round($MAX_INLINE_PAYLOAD_SIZE / 1000),ceil(strlen($payload) / 1024)));}return ['type' => 'payload','payload' => $payload,];} catch (Exception $e) {throw new Exception('Error serializing inputProps. Check it has no circular references or reduce the size if the object is big.');}}function assumeRole($region, $ARN, $sessionName){try {$stsClient = new Aws\Sts\StsClient(['region' => $region,'version' => 'latest',]);$result = $stsClient->AssumeRole(['RoleArn' => $ARN,'RoleSessionName' => $sessionName,]);return ['key' => $result['Credentials']['AccessKeyId'],'secret' => $result['Credentials']['SecretAccessKey'],'token' => $result['Credentials']['SessionToken'],];} catch (AwsException $e) {// Handle the exceptionecho $e->getMessage();return null;}}
Reference applications
2 reference projects are available:
- php-remotion. This is an application that invokes the Remotion Lambda function containing the minimum parameters to render a video.
- remotion-laravel is an application that serves a REST endpoint using Laravel PHP framework. This endpoint invokes the Remotion lambda function with the necessary parameters to render a video.
Both use remotion-app, which includes a Remotion composition and utility scripts for deploying and deleting Remotion Lambda infrastructure in AWS.
Bare PHP
Ensure that remotion-app is already deployed on your AWS Account.
The php-remotion
application will call Remotion Lambda to render a video and contains the bare minimum parameters for Remotion's Lambda arguments. Once the parameters are constructed, they will be passed on to the AWS Lambda Client using the AWS PHP SDK. This project imitates the operation of rendermediaonlambda and uses composer.
Clone the project using:
bash
git clone https://github.com/alexfernandez803/php-remotion
bash
git clone https://github.com/alexfernandez803/php-remotion
remotion-serverless/php-remotion
bash
cd remotion-serverless && cd php-remotion
bash
cd remotion-serverless && cd php-remotion
bash
php composer.phar update
bash
php composer.phar update
The application has a .env
file that needs to be populated for the video render to work properly. An .env.example
has been included in the project containing example values.
.envbash
REMOTION_APP_IS_ASSUME_ROLE="false"REMOTION_APP_REGION="ap-southeast-2"REMOTION_APP_BUCKET="remotionlambda-apsoutheast2-xxxxxx"REMOTION_APP_FUNCTION_NAME="remotion-render-3-3-78-mem2048mb-disk2048mb-240sec"REMOTION_APP_SERVE_URL="https://remotionlambda-apsoutheast2-qv16gcf02l.s3.ap-southeast-2.amazonaws.com/sites/remotion-render-app-3.3.78/index.html"REMOTION_APP_ROLE_ARN="arn:aws:iam::123456789012:role/xaccounts3access"REMOTION_APP_ROLE_SESSION_NAME="remotion_session_name"
.envbash
REMOTION_APP_IS_ASSUME_ROLE="false"REMOTION_APP_REGION="ap-southeast-2"REMOTION_APP_BUCKET="remotionlambda-apsoutheast2-xxxxxx"REMOTION_APP_FUNCTION_NAME="remotion-render-3-3-78-mem2048mb-disk2048mb-240sec"REMOTION_APP_SERVE_URL="https://remotionlambda-apsoutheast2-qv16gcf02l.s3.ap-southeast-2.amazonaws.com/sites/remotion-render-app-3.3.78/index.html"REMOTION_APP_ROLE_ARN="arn:aws:iam::123456789012:role/xaccounts3access"REMOTION_APP_ROLE_SESSION_NAME="remotion_session_name"
REMOTION_APP_REGION
Is the AWS region you are using, e.gus-east-1
.REMOTION_APP_IS_ASSUME_ROLE
accepts eithertrue
orfalse
. When set totrue
the application the application calls the AWS STSAssumeRole
command, retrieve thekey
,secret
andtoken
and pass those credentials inLambdaClient::factory
. Ensure thatREMOTION_APP_ROLE_ARN
andREMOTION_APP_ROLE_SESSION_NAME
are provided when using this flag. This approach is appropriate if you want to deploy this application in AWS EC2. Roles are required to be set up for the application. Please refer to the Authenticating Lambda with EC2 guide and follow steps 1 to 4.Assume rolebash$credentials = NULL;if ($_ENV["REMOTION_APP_IS_ASSUME_ROLE"] === true) {$credentials = assumeRole($_ENV["REMOTION_APP_REGION"],$_ENV["REMOTION_APP_ROLE_ARN"], $_ENV["REMOTION_APP_ROLE_SESSION_NAME"]);}$client = LambdaClient::factory(['version' => 'latest','region' => $region,'credentials' => $credentials,]);Assume rolebash$credentials = NULL;if ($_ENV["REMOTION_APP_IS_ASSUME_ROLE"] === true) {$credentials = assumeRole($_ENV["REMOTION_APP_REGION"],$_ENV["REMOTION_APP_ROLE_ARN"], $_ENV["REMOTION_APP_ROLE_SESSION_NAME"]);}$client = LambdaClient::factory(['version' => 'latest','region' => $region,'credentials' => $credentials,]);
The following variables can be retrieved by completing the Lambda setup:
REMOTION_APP_BUCKET
- Your bucket nameREMOTION_APP_FUNCTION_NAME
- The name of your deployed function. Note that it changes on every Remotion version.REMOTION_APP_SERVE_URL
is where your Webpack bundle is hosted.
When you use Remotion on an AWS EC2 instance, set the following env variables. To set up the required roles, please refer to the Authenticating Lambda with EC2 guide and follow steps 1
to 4
.
REMOTION_APP_ROLE_ARN
represents the ARN of the role which the application assume to render the video, for this instance it isremotion-ec2-executionrole
ARN fromstep 2
on this guide.REMOTION_APP_ROLE_SESSION_NAME
a name to uniquely identify the role session when the same role is assumed by different principals.
Run the application by executing the command below:
Run applicationbash
php lambda-remotion-render.php
Run applicationbash
php lambda-remotion-render.php
Sample application responsebash
{"bucketName":"remotionlambda-apsoutheast2-xxxx","renderId":"b2xhi715yn"}
Sample application responsebash
{"bucketName":"remotionlambda-apsoutheast2-xxxx","renderId":"b2xhi715yn"}
Once the execution is successful, the API will responsd with the bucketName
and renderId
. These are metadata required to get the status the video render or retrieving video.
Laravel
This application can be executed on a local machine or computing instance, such as AWS EC2, to call Remotion Lambda and render a video. It includes the minimum parameters required for Remotion's Lambda arguments from a REST endpoint.
After constructing the parameters, they will be passed on to the AWS Lambda Client using the AWS PHP SDK. It also contains Laravel boilerplate code for setting up a REST endpoint that calls the Remotion Lambda. This project imitates the operation of renderMediaOnLambda()
and uses Composer.
bash
git clone https://github.com/alexfernandez803/remotion-laravel
bash
git clone https://github.com/alexfernandez803/remotion-laravel
remotion-serverless/remotion-laravel
bash
cd remotion-serverless && cd remotion-laravel
bash
cd remotion-serverless && cd remotion-laravel
bash
php composer.phar update
bash
php composer.phar update
Refer to the bare PHP example for setting up the environment variables.
The application requires a database, and for this application, SQLLite is used. Therefore, the configuration details from the .env
file need to be provided.
.env (continued)bash
DB_CONNECTION=sqliteDB_DATABASE=database.sqlite
.env (continued)bash
DB_CONNECTION=sqliteDB_DATABASE=database.sqlite
DB_CONNECTION
is the connection type that represents which database to use ie,MYSQL
DB_DATABASE
is the database name, for this instance this represents the absolute URL path of the SQLite database.
Create the database and table in SQLite defined in DB_DATABASE
by executing the command below:
Create a database and tablebash
php artisan vendor:publish --tag=sanctum-migrations
Create a database and tablebash
php artisan vendor:publish --tag=sanctum-migrations
Run the application by executing the command below:
Run applicationbash
php artisan serve
Run applicationbash
php artisan serve
Send register requestbash
curl --location 'http://127.0.0.1:8000/api/register' \--header 'Content-Type: application/json' \--data-raw '{"name": "John Doe","email": "testuser@example.com","password": "L3tm3in@@","confirm_password": "L3tm3in@@"}'
Send register requestbash
curl --location 'http://127.0.0.1:8000/api/register' \--header 'Content-Type: application/json' \--data-raw '{"name": "John Doe","email": "testuser@example.com","password": "L3tm3in@@","confirm_password": "L3tm3in@@"}'
Log into the applicationbash
curl --location 'http://127.0.0.1:8000/api/login' \--header 'Content-Type: application/json' \--data-raw '{"email": "alex.frndz@gmail.com","password": "L3tm3in@@"}'
Log into the applicationbash
curl --location 'http://127.0.0.1:8000/api/login' \--header 'Content-Type: application/json' \--data-raw '{"email": "alex.frndz@gmail.com","password": "L3tm3in@@"}'
Sample responsejson
{"success": true,"data": {"token": "2|ykXXPxXXX86pO4rXXXF49VhVXX34yGupU","name": "John Doe"},"message": "User login successfully."}
Sample responsejson
{"success": true,"data": {"token": "2|ykXXPxXXX86pO4rXXXF49VhVXX34yGupU","name": "John Doe"},"message": "User login successfully."}
Render video requestbash
curl --location --request POST 'http://127.0.0.1:8000/api/renders' \--header 'Authorization: Bearer 2|ykXXPxXXX86pO4rXXXF49VhVXX34yGupU'
Render video requestbash
curl --location --request POST 'http://127.0.0.1:8000/api/renders' \--header 'Authorization: Bearer 2|ykXXPxXXX86pO4rXXXF49VhVXX34yGupU'
Example responsejson
{"success": true,"data": {"bucketName": "remotionlambda-apsoutheast2-xxxxx","renderId": "745b9itxb2"},"message": "Render Successful."}
Example responsejson
{"success": true,"data": {"bucketName": "remotionlambda-apsoutheast2-xxxxx","renderId": "745b9itxb2"},"message": "Render Successful."}
Checking progress
For retrieving the progress of a Lambda render, you need to send another request to the Lambda function. Currently we do not have instructions for it, as a reference you may see here for the payload that is being sent by the TypeScript SDK.