Download YouTube videos to S3 using Lambda powered by ytdl.
You need an up-to-date AWS CLI installed and configured on your machine and Node.js v12.
If you never worked with aws cloudformation package
before, create an S3 bucket that stores the ZIP files that the package
command generates. Run the following command and replace YOUR_BUCKET
with a unique bucket name: aws s3 mb s3://YOUR_BUCKET
.
Run the following commands (replace $BUCKET
with your S3 bucket name to store ZIP files) to package the source code:
yarn
aws cloudformation package --s3-bucket $BUCKET --template-file template.yml --output-template-file .packaged.yml
Your output will look like this:
Uploading to 864a6c31b9b19e4abfba8d28d719b9a8 8460482 / 8460482.0 (100.00%)
Successfully packaged artifacts and wrote output template to file .packaged.yml.
Execute the following command to deploy the packaged template:
aws cloudformation deploy --template-file .../.packaged.yml --stack-name <YOUR STACK NAME>
Now it's time to deploy the CloudFormation stack (replace $STACK
with your desired name):
aws cloudformation deploy --stack-name $STACK --template-file .packaged.yml --capabilities CAPABILITY_IAM
Your output will look like this:
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - $STACK
Find the same steps, with detailed explanations, in the AWS Lambda Docs.
aws apigateway create-rest-api --name $STACK
Grab the id
from the response; from now on we will refer to it as $API
aws apigateway get-resources --rest-api-id $API
Grab the id
from the response; from now on we will refer to it as $PARENT
aws apigateway create-resource --rest-api-id $API --path-part $STACK --parent-id $PARENT
Grab the id
from the response; from now on we will refer to it as $RESOURCE
aws apigateway put-method --rest-api-id $API --resource-id $RESOURCE --http-method GET --authorization-type NONE
In the following commands:
$REGION
refers to the region where you want the API to be deployed;$ACCOUNT
refers to your account id (find it in your Console account settings)
aws apigateway put-integration --rest-api-id $API --resource-id $RESOURCE --http-method GET --type AWS_PROXY --integration-http-method GET \
--uri arn:aws:apigateway:$REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:$REGION:$ACCOUNT:function:$STACK
aws apigateway put-method-response --rest-api-id $API --resource-id $RESOURCE --http-method GET \
--status-code 200 --response-models application/json=Empty
aws apigateway put-integration-response --rest-api-id $API --resource-id $RESOURCE --http-method GET \
--status-code 200 --response-templates application/json=""
aws apigateway create-deployment --rest-api-id $API --stage-name prod
aws lambda add-permission --function-name $STACK --statement-id apigateway-test-2 --action lambda:InvokeFunction \
--principal apigateway.amazonaws.com --source-arn "arn:aws:execute-api:$REGION:$ACCOUNT:$API/*/GET/$STACK"
aws lambda add-permission --function-name $STACK --statement-id apigateway-prod-2 --action lambda:InvokeFunction \
--principal apigateway.amazonaws.com --source-arn "arn:aws:execute-api:$REGION:$ACCOUNT:$API/prod/GET/$STACK"
To clean up:
- empty the S3 bucket that stores your video
- remove the CloudFormation stack you created
- remove the API gateway you created
GET
https://$API.execute-api.$REGION.amazonaws.com/prod/$STACK?videoId=<ANY PUBLIC YOUTUBE VIDEO ID>
or
GET
https://$API.execute-api.$REGION.amazonaws.com/prod/$STACK?videoUrl=<ANY PUBLIC YOUTUBE VIDEO URL>
or
GET
https://$API.execute-api.$REGION.amazonaws.com/prod/$STACK?videoId=<ANY PUBLIC YOUTUBE VIDEO ID>&path=/some/folder/path/in/the/s3/bucket
Note
See the queryParameters in index.js
.
{
"bucketName": "test",
"path": "xyz.mp4",
"url": "s3://test/xyz.mp4"
}
- The download from YouTube and upload to S3 must finish within 15 minutes (I have not found a video that was too big).