DEV Community

Cover image for Creating A Video Converter Using Flask And GStreamer
Ethan
Ethan

Posted on • Originally published at ethan-dev.com

Creating A Video Converter Using Flask And GStreamer

Introduction

Hello! 😎

In this tutorial, I will show you how to use Flask to create an endpoint that receives a video file, converts it to mp4, and then returns the mp4 to the user.


Requirements

  • GStreamer Installed
  • GObject Installed

The installation may vary depending on the operating system you are using.


Creating The Virtual Environment

First, we need to create the Python virtual environment, this can be done via the following command:

python3 -m venv env  
Enter fullscreen mode Exit fullscreen mode

Then it can be activated via the following:

source env/bin/activate  
Enter fullscreen mode Exit fullscreen mode

Done. Next,  we need to install the dependencies. 


Installing The Dependencies

Next, create a file called "requirements.txt" and add the following to it:

flask  
pygobject  
tempdir  
Enter fullscreen mode Exit fullscreen mode

To install the dependencies, run the following command:

pip install -r requirements.txt  
Enter fullscreen mode Exit fullscreen mode

All done! 😄 Now we can actually get coding.


Creating The Endpoint

Next, open up "main.py" First,  we import the modules needed. Add the following imports:

from flask import Flask, request, send_file  
import os  
import gi  
gi.require_version('Gst', '1.0')  
from gi.repository import Gst, GObject  
import tempfile  
import shutil  
Enter fullscreen mode Exit fullscreen mode

We also ensure GStreamer is above version 1.0.

Next, we need to initialize the Flask application and GStreamer; this can be done via the following line:

app = Flask(__name__)  
Gst.init(None)  
Enter fullscreen mode Exit fullscreen mode

Next we will create the endpoint that will take a file, use GStreamer to convert the video into an mp4 and then return the file to the user.

@app.route('/convert', methods=['POST'])  
def convert():  
    if 'file' not in request.files:  
        return 'No file part in the request', 400 

    file = request.files['file']

    if file.filename == '':   
        return 'No selected file', 400 

    tmp_file = tempfile.NamedTemporaryFile(delete = False)  
    tmp_file.write(file.read())  
    tmp_file.close()

    pipeline_str = f'filesrc location={tmp_file.name} ! decodebin ! x264enc ! mp4mux ! filesink location={tmp_file.name}.mp4'

    pipeline = Gst.parse_launch(pipeline_str)  
    pipeline.set_state(Gst.State.PLAYING)

    bus = pipeline.get_bus()

    msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE,  
         Gst.MessageType.ERROR | Gst.MessageType.EOS)

    pipeline.set_state(Gst.State.NULL)

    if msg.type == Gst.MessageType.ERROR:  
        os.remove(tmp_file.name)  
        return f'Error converting file: {msg.parse_error()}'

    return send_file(tmp_file.name + ".mp4", mimetype='video/mp4', as_attachment=True, download_name=tmp_file.name)

    os.remove(tmp_file.name)

Enter fullscreen mode Exit fullscreen mode

The code does quite a bit, but I try to explain it in order.

First of all, we check that the user has actually sent something and has a name; if not, we return the error to the user.

We then create a temp file to save the file that the user sent via the request in order to convert it using GStreamer.

We then create the GStreamer pipeline and then convert the file, we listen for any errors during conversion and, if an error occurs, inform the user.

If the conversion was a success, the file is sent back to the user, and the temporary file is removed.

Phew! Hopefully that explained it well enough for you to understand. 🥴

Finally, we need to write the main method:

if __name__ == "__main__":  
    app.run(debug=True)  
Enter fullscreen mode Exit fullscreen mode

Done! 😄


Trying It Out

Now we can actually run the code and try to convert a file. 👀

Start up the server with the following command:

python main.py  
Enter fullscreen mode Exit fullscreen mode

Once the server is started, you can try converting a file with the following curl command:

curl -X POST -F file=@big-buck-bunny_trailer.webm http://localhost:5000/convert -o output.mp4  
Enter fullscreen mode Exit fullscreen mode

You will need a file to test it with, so make sure to change the file option. Once done, you should see an output.mp4 file in the directory. You should also be able to play it.😺


Conclusion

Here I have shown how to create a simple video converter using Flask, Python, and GStreamer. 

Hopefully this has been of some use to you, and as always, happy coding! 😎

You can find the source code for this tutorial via:
https://github.com/ethand91/flask-video-converter


Like me work? I post about a variety of topics, if you would like to see more, please like and follow me.

Also, I love coffee. 

"Buy Me A Coffee"

If you are looking to learn Algorithm Patterns to ace the coding interview, I recommend the following course

Top comments (1)

Collapse
 
stuaxo profile image
Stuart Axon

Good stuff. Anyone productising this will want to have some background process doing the transcoding, otherwise it will tie up a web server connection.

If I had my complicators gloves on it would be interesting to have the encoding process run by another service, e.g. celery, but also have some way for it to communicate back to the user.

The file could be piped to that service as it uploads, where possible encoding can happen at the same time and get status back to the user about the encoding process.