Rumbling, skip as you like...

Ever fall in love with a youtube channel that you only want to listen to? I know I do. For some channels, I want to carry only the audio around vs. keeping the video playing and let it exhaust my phone's battery and waste a bunch mobile data. With Azure container instance and logic app, there is a solution.

About Logic App

It provides hundreds of connectors that connects to all different kinds of services. You can easily set up triggers and actions to build your own business workflow. See more.

Youtube downloader workflow

The workflow is fairly simple:

  1. Whenever a channel you'd like to track uploads a video (there is a logic app connector)
  2. Spin up a container instance to download it and convert it to audio (here comes the ACI)
  3. Save the audio somewhere (ideally it would be something like Dropbox)

In reality, there is a little bit more details, which I will cover below.

Step by step

Docker image

There is this amazing command line tool youtube-dl. I built a docker image that has youtube-dl installed. The dockerfile is here.

FROM debian:latest

RUN apt update -y \
    && apt upgrade -y \
    && apt install curl -y \
    && apt install python -y

RUN curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/bin/youtube-dl \
    && chmod a+rx /usr/bin/youtube-dl \
    && apt install ffmpeg -y

CMD ["bash"]

Feel free to use my existing docker image shou3301/youtube-dl.

Create container instance

When creating a container instance to download a youtube video, I want to save the downloade file to Azure File first so that I can sync it to a more personal storage later.

Here is how I manually run the docker image with azure container instance using azure cli:

> az container create -g chshou -n youtube-dl --image shou3301/youtube-dl --restart-policy OnFailure --azure-file-volume-share-name youtube --azure-file-volume-account-name chshoustore --azure-file-volume-account-key xxxxxxx --azure-file-volume-mount-path /mnt/azfile --command "youtube-dl -x --audio-format mp3 -o /mnt/azfile/%(uploader)s/%(playlist)s/%(title)s.%(ext)s https://youtube.com/abcdefg"

Here I mount my Azure File volume to path /mnt/azfile and when I download a youtube video, I have the output folder in the mount path.

Also make sure to set to --restart-policy so that the container will run-to-completion.

Set up logic app

The workflow starts with a trigger: When a video is uploaded by a channel. You will need to create a connection using your youtube account.

Then it creates a container group basically just using the same set of parameters we used above in the azure cli. Logic App provides the capability to use outputs from previous step. As a result, in the youtube-dl command, I can use the video link from the previous step. When the step gets expaned, it looks something like:

The only thing that doesn't seem working very well is the input of the command property on the "Logic App Designer". The hint asks me to put the command as one parameter per line, but in the generated json code, it's not really what I want. So I have to go to the "Logic App Code View" to edit the json directly. Afterwards, the json of the request body looks like:

"body": {
    "location": "WestUS",
    "properties": {
        "containers": [
            {
                "name": "youtube-dl",
                "properties": {
                    "command": [
                        "youtube-dl",
                        "-x",
                        "--audio-format",
                        "mp3",
                        "-o",
                        "/mnt/azfile/%(uploader)s/%(playlist)s/%(title)s.%(ext)s",
                        "@{triggerBody()?['htmlLink']}"
                    ],
                    "image": "shou3301/youtube-dl",
                    "resources": {
                        "requests": {
                            "cpu": 1,
                            "memoryInGB": 1.5
                        }
                    },
                    "volumeMounts": [
                        {
                            "mountPath": "/mnt/azfile",
                            "name": "azfile"
                        }
                    ]
                }
            }
        ],
        "osType": "Linux",
        "restartPolicy": "OnFailure",
        "volumes": [
            {
                "azureFile": {
                    "shareName": "youtube",
                    "storageAccountKey": "your_key",
                    "storageAccountName": "chshou"
                },
                "name": "azfile"
            }
        ]
    }
}

How to clean up run-to-completion container group?

The only tricky part of the workflow is the clean up of the container group. The provisioningState of a container group will become Succeeded as soon as the creation is done. So the task could be still in progress even if provisioning state is succeeded. The actual indicator of whether the task is completed or not is properties.instanceView.state. Only when it equals Succeeded, then it really means the task is completed and we can delete the container group. A simple delay won't always work because downloading video with different size could result in different time cost.

Logic App provides a special logic called Until loop. It works just as a do ... while loop. It also provides a Condition logic which works just as if ... else .... In this case, I created a Until loop that firstly gets the container group created. Then in the Until loop, add a Condition that checks if properties.instanceView.state equals Succeeded. If so, go delete the container group, else schedule a delay. See the top graph.

Run it

All the run history will be listed in logic app. Once it's triggered, find your files in your Azure File share.

Make it better

Azure File is not really designed for daily personal use. A better storage would be like Dropbox or OneDrive. I was being lazy and didn't do that.

In the container image, you can for sure call some API to upload the downloaded file to your personal storage. The only problem is how to have the key/secret available in the container to do the API authentication. No worries! Azure container instance now supports secret volume where you can have your key/secret available in the container.

Notice

This artile only works as an introduction to the integration for Azure container instance and Logic App. Use everything in this article at your own risk. Also please only download videos of free distribution.

results matching ""

    No results matching ""