Offloading FFMPEG to Azure Container Instances

Mohammed Brückner
Serverless and Low Code pioneers
4 min readOct 5, 2022

Azure Container Instances is easy to use and takes away the burden of managing containers. A good fit to run some custom batch job, like in this very example converting a video from one format to another. FFMPEG is a widely known open source tool which is great at this, so let’s go for it.

This approach here is really, really good, and Mark explains very well why:

https://markheath.net/post/serverless-media-processing-with-aci

Acting on it, I would recommend to first set the subscription to use — in Azure Cloudshell, why not?

(Note: There is a complete bash script at the end of this tutorial. I recommend you actually use it to run the whole thing and read the following just for your understanding.)

We proceed from the bash prompt in CloudShell as follow.

Differentiate the subscriptions with this cmd:

az account subscription list

The subscription will have an ID like 850b39c1–6axe-4c98-a701–7ed8e14369f0.

If you need to change the subscription used, do it like this:

az account set — subscription “850b39c1–6axe-4c98-a701–7ed8e14369f0”

Now unlike in Mark’s tutorial, let us proceed in bash instead of Powershell. And unlike Mark, we’ll use linuxserver/ffmpeg as baseline container image.

resourceGroup=”hackathonffmpegRG”location=”northeurope”storageAccountName=”hackathonacifshare”az group create -n $resourceGroup -l $locationaz storage account create -g $resourceGroup -n $storageAccountName — sku Standard_LRSstorageConnectionString=$(az storage account show-connection-string -n $storageAccountName -g $resourceGroup — query connectionString -o tsv)#creating an environment variable for easier scriptingexport AZURE_STORAGE_CONNECTION_STRING=$storageConnectionStringshareName=”acishare”#creating a file shareaz storage share create -n $shareName

Now upload some video into CloudShell by simply dragging and dropping it into CloudShell. Hint: “clouddrive” is the (default) mounted drive name for your attached file storage for CloudShell. Basically, where your files persists in CloudShell.

With ls -lh you get the files in your cloud drive in human readable size.

Let us assume you already copied a file called tollesvideo.mp4 into the clouddrive folder. Make sure to cd into your clouddrive folder proceed in your bash prompt:

filename=”tollesvideo.mp4"az storage file upload -s $shareName — source “$filename”

Now you have copied over your video into your file share as you can see in the Portal.

A file sitting in the file share created earlier — names might vary

And on we go:

#let us stash the storage key into a variablestorageKey=$(az storage account keys list -g $resourceGroup — account-name $storageAccountName — query “[0].value” — output tsv)containerGroupName=”hackathontranscode”#the image comes from a public Docker repoaz container create \-g $resourceGroup \-n $containerGroupName \— image linuxserver/ffmpeg \— restart-policy never \— azure-file-volume-account-name $storageAccountName \— azure-file-volume-account-key $storageKey \— azure-file-volume-share-name $shareName \— azure-file-volume-mount-path “/mnt/azfile” \— cpu 2 — memory 4 \— command-line “ffmpeg -i /mnt/azfile/$filename -vf “”thumbnail,scale=640:360"” -frames:v 1 /mnt/azfile/thumb.png”

Check out what’s going on by accessing the logs:

az container logs -g $resourceGroup -n $containerGroupName

Note that the container instance will be terminated as soon as the command execution finishes.

And here is a complete and tested bash script you can use right away:

  1. In CloudShell, in your clouddrive directory enter touch containerfun.sh
  2. Type code . (out of the clouddrive folder in your CloudShell) — this will bring up a handy graphical code editor you can use on top of CloudShell!
  3. Copy & paste the script below and adapt to your needs into containerfun.sh
  4. Run it: ./containerfun.sh

Once it ran through and everything worked, you will see a thumbnail file in your file share.

Things to consider: Using this in real-life scenarios

For the purpose of taking Container Instances for a spin, the file to be processed with FFMPEG was just sitting in a CloudShell mounted drive. It was easy enough to upload it to CloudShell in Azure Portal and from there “locally” to the file share. In real-life, the file would probably have a different origin story.

  • Like in shape of a a pre-signed URL passed on to the container — and the actual file needs to be downloaded first.
  • The file on the file share mounted within the container could be the result of an Azure Function or maybe another Container Instance as well.
  • It could as well be the result of a “Copy data” pipeline task in DataFactory. (Or Synapse Analytics pipelines.)

How and where could you use this?

Out of Logic Apps for example, very similar to Power Automate. There are actions for Azure Container Instances you can utilize.

Straight out of Powershell or bash, for one-offs for example, or out of Automation Runbooks for regular tasks.

Using Azure SDKs (and APIs) there is no limit in what context you could spin up these Container Instances to do any processing of your liking.

The explanation so far covered FFMPEG, it could be virtually anything else, really.

As Mark pointed out in the article I quoted at the beginning, this whole approach only makes sense if you have a fairly low number of conversions to cover. (Both from a cost and feasibility point of view.)

Otherwise, you need to think about queuing up conversion tasks and re-use Container Instances. Or use the dedicated services like Azure Media Services and deal with the learning curve.

How to use Azure Media Services to do the job is for another time.

Go wild, have fun!

--

--

Mohammed Brückner
Serverless and Low Code pioneers

Author of "IT is not magic, it's architecture", "The DALL-E Cookbook For Great AI Art: For Artists. For Enthusiasts."- Visit https://platformeconomies.com