Serverless mp3 and mp4 to HLS converter using Zappa, AWS Lambda, API Gateway, S3 and FFmpeg : Create lambda handler

Create lambda handler

Let us create a lambda handler function that will be executed when we upload an mp4 or mp3 to an AWS S3 bucket. This function will read the input file, convert it to .ts files and a playlist file (.m3u8) and then finally upload it to an output S3 bucket.

First you need to create two S3 buckets in AWS console. Let us call the first bucket input-bucket and the output bucket hls-ready

Then install boto3 in your virtualenv. Boto3 is an AWS SDK that enables developers to configure and interact with AWS resources in Python. To be able to write our converted files to the output S3 bucket, we need an S3 client using boto3.

$ pip install boto3

Let us call the file

import boto3
import os
import tempfile
import subprocess
import urllib.parse
import glob
from datetime import datetime
import json
import sys

s3_client = boto3.client('s3')

media_out_bucket_name = 'hls-ready'

def convert_to_hls(event, context):
   bucket = urllib.parse.unquote(event['Records'][0]['s3' ['bucket']['name'])
   key = urllib.parse.unquote(event['Records'][0]['s3']['object']['key'])
   path_no_ext, file_ext = os.path.splitext(key)
   if file_ext == '.mp4' or file_ext == '.mp3':
      file_name = os.path.basename(key)
      file_name_no_ext = os.path.basename(path_no_ext)
      presigned_file_url = s3_client.generate_presigned_url(
         'Bucket': bucket,
         'Key': key
      # Delete all video/audio files in tmp 
      files = [f for f in os.listdir('.') if os.path.isfile(f)]
      for f in files:
         if f.endswith('.mp3') or f.endswith('.mp4') or f.endswith('.ts') or f.endswith('.m3u8'):

      # Now transcode to 360p resolution
      cmd = ['/opt/ffmpeg', '-i', presigned_file_url, '-profile:v', 'baseline', '-level', '3.0', '-s', '640x360', '-start_number', '0', '-hls_time', '10', '-hls_list_size', '0', '-f', 'hls', file_name_no_ext + '.m3u8']

      if file_ext == '.mp3':
         cmd = ['/opt/ffmpeg', '-i', presigned_file_url, '-vn', '-ac', '2', '-acodec', 'aac', '-f', 'segment', '-segment_format', 'mpegts', '-segment_time', '10', '-segment_list', file_name_no_ext + '.m3u8', file_name_no_ext + '-%05d.ts']

      p =, stdin=subprocess.DEVNULL)

      if p == 0:
         for f in glob.glob(file_name_no_ext + "*.ts"):
            s3_client.upload_file(f, media_out_bucket_name, file_name_no_ext + '/' + f)
            s3_client.upload_file(file_name_no_ext + '.m3u8', media_out_bucket_name, file_name_no_ext + '/' + file_name_no_ext + '.m3u8')

In the subsequent sections, we will explain what is going on in the code above.

course logo
Serverless mp3 and mp4 to HLS converter using Zappa, AWS Lambda, API Gateway, S3 and FFmpeg
Number of sections:
Content length:
Delivery formats:


Evans Boateng Owusu
Evans is a Computer Engineer and cloud technology enthusiast. He has a Masters degree in Embedded Systems (focusing on Software design) from the Technical University of Eindhoven (The Netherlands) and a Bachelor of Science in Electronic and Computer Engineering from the Polytechnic University of Turin (Italy). In addition, he has worked for the high-tech industry in the the Netherlands and other large corporations for over seven years.... Show more
Serverless mp3 and mp4 to HLS converter using Zappa, AWS Lambda, API Gateway, S3 and FFmpeg