Building a Tool/Web-API in Rust to generate and serve audio files— Part I
Tags: rust, actix, devops, docker
Published: 2023-02-03 11:57:25

Well, at some point, we all used YouTube to mp3 conversion websites like ytmp3, etc., but did you ever want to get even slightly close to making something like that? That is what I wanted to do. So, I started this simple project called rytaud. In part, I made a simple web server that utilizes the youtube-dl CLI tool to get the mp3 file and serve it to the user.

Setting up the server
To set up the web server, I used the actix-web framework in rust and set up the required endpoints with their function calls. I used actix because initially, I wanted to keep my project simple, and writing my server configuration would have deviated me from the actual aim. While developing anything on your own, you should try to follow the KISS principle as much as possible; you can always customize things later.

Here is the code for my server:
{% embed https://gist.github.com/destrex271/f69e09a77ea2da79162cbafe76f054b7 %}

As you can see, I have set up three endpoints, out of which the delete_vid endpoint is not of concern. The endpoint POST ‘/download_audio’ triggers the youtube-dl utility interface that we will look into later. It returns a reference to the ‘/audio’ endpoint, which is an actix_files endpoint acting as a file hosting service in a way.

## CLI interfacing
To interface with the youtube-dl CLI, I used the std::Command library available in rust as follows:
{% embed https://gist.github.com/destrex271/15a313c2e093d810c39904cac6129f47 %}
This function calls the youtube-dl CLI and generates the mp3 file according to the key provided by the user. This file is being stored in the root of the program as of now. The HTTP server returns the path as ‘/audio/file.mp3’, which the user can then access to use the audio file.

## Containerization
{% embed https://gist.github.com/destrex271/1535998ec2a9ebe9e575148432b80d1d %}
I also decided to containerize the application and set up a GitHub workflow to automatically build and deploy the image as a package on GitHub for public use. The docker image multi-stage stage was constructed with the rust image to compile the project and a Debian bullseye image to run the compiled program.

## Goals for the next stages
### <u>Improved Storage</u>
Storing multiple audio files on a single system in a container is not a good practice. Still, since I was unable to get any other cloud storage services, I decided to go with it and instead implement a background service that deletes all the MP3 files in 24 hours, which can be seen in the code for the server, but remember the project is still in its initial stages. As of now, I need to find a storage service that abstracts all of this for me or design something like that on my own.
### <u>Writing the download tool</u>
youtube-dl is a fantastic tool, but the end goal of this project is to implement that utility in my way to give me more control and optimize the entire process because the speed at which youtube-dl downloads the file is pretty slow, and it affects the overall performance of the API. The tool should also allow users to get audio from other platforms as well.

### <u>Reduce the Image size</u>
The docker image for the project is huge as of now, around 912 MB. I need to find a way to reduce this size further. Also, I want to set up an orchestration service for deploying projects like Kubernetes, but before that, I need to fix the problems mentioned above to optimize my builds.

## Conclusion 
So that was it for Part I. The project needs more improvements. I hope you guys test out the project. Suggestions and feedback are always welcome. Please check out the <a href="https://github.com/destrex271/rytaud">GitHub repository</a> if you wish to contribute to the project. A <a href="https://github.com/destrex271/rytaud/pkgs/container/rytaud">docker image</a> for the same is available on github packages, so if you want to look into that you are welcome to do so.