khooz02
khooz02

Reputation: 13

How to use the Heroku buildpack ffmpeg for Python?

I want to use the ffmpeg buildpack in my Python app on Heroku.
I am using the ffmpeg buildpack from https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.

How can I use buildpack? subprocess? os? How to call the ffmpeg? Anybody can teach me?

This is my code and I want to convert mp4 file to mp3 file. Actually,I don`t know about the detect/compile/release file.

   subprocess.call(['ffmpeg', '-i', 'xxx.mp4','-vn','-f mp3', 'xxx.mp3'])
   subprocess.call(['ffmpeg', '-i', 'xxx.mp4','-vn','-f mp3', 'xxx.mp3'])

Upvotes: 1

Views: 2787

Answers (1)

Gino Mempin
Gino Mempin

Reputation: 29678

First of, I assume you already know how to deploy a Python app to Heroku and you already have a working app accessible from Heroku, as this answer is specific to how to use the ffmpeg buildpack. (If you don't yet, check Getting Started on Heroku with Python first).

Step 1: Adding the ffmpeg buildpack

Buildpacks basically tell Heroku how to setup the environment for your app (which dependencies to install, which scripts to run, etc.). For Python apps, you need to have the official heroku/python buildpack, and you can check this by:

$ heroku buildpacks
=== ginomempin-ffmpeg-app Buildpack URL
heroku/python

To add other dependencies (ffmpeg), you need to install the buildpack for it on your Heroku app (ex. https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest). From the Heroku docs on Adding a buildpack, this is done by heroku buildpacks:add <buildpack>:

$ heroku buildpacks:add --index 2 https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git
Buildpack added. Next release on ginomempin-ffmpeg-app will use:
  1. heroku/python
  2. https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git
Run git push heroku master to create a new release using these buildpacks.

$ heroku buildpacks
=== ginomempin-ffmpeg-app Buildpack URLs
1. heroku/python
2. https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git

Note the --index 2 there in my example. This is just to order the buildpacks, Python first since it's the main buildpack, then ffmpeg second. It depends on your app.

Now, test it by making changes to your code then deploy (i.e. git push heroku master). The Heroku logs should display that the buildpack is now added:

remote: -----> Python app detected
remote: -----> Installing requirements with pip
remote:
remote: -----> ffmpeg app detected
remote: -----> Install ffmpeg
remote:        DOWNLOAD_URL =  https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz
remote:        exporting PATH

Step 2: Checking the ffmpeg buildpack

Use the heroku run command to check how to use the installed ffmpeg. For this sample app, I pushed a assets/sample.mp4 test file on the root directory of my app.

├── app.py
├── assets
│   └── sample.mp4
├── ...
└── runtime.txt
$ heroku run "which ffmpeg"
Running which ffmpeg on ⬢ ginomempin-ffmpeg-app... up, run.7460 (Free)
/app/vendor/ffmpeg/ffmpeg

$ heroku run "ffmpeg -i assets/sample.mp4 -vn -f mp3 assets/sample.mp3"
...
Output #0, mp3, to 'assets/sample.mp3':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    ...

Once you now know how to run your ffmpeg commands (and that it works), all you have to do is call the same set of commands from your app. Note that, you don't need to change directories (as you did with your initial code) or specify the path to ffmpeg.

Step 3: Calling ffmpeg from Python app

Using Python's subprocess to call the same commands:

cmd = ['ffmpeg', '-i', './assets/sample.mp4', '-vn', '-f', 'mp3', './assets/sample.mp3']
out = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(out.stdout)
print(out.stderr)
for f in os.listdir("./assets"):
    print(f)

Make sure that you separate all the space-separated parts of the command into a separate element in the list. You can then check the output using heroku logs --tail (for some reason, the ffmpeg output is stored in stderr instead of stdout):

2019-09-29T11:54:57.050692+00:00 app[web.1]: b''
2019-09-29T11:54:57.050736+00:00 app[web.1]: b"ffmpeg version N-50091-gfc20ba9e04-static https://johnvansickle.com/ffmpeg/  
...  
Output #0, mp3, to './assets/sample.mp3':\n  
  Metadata:\n    
    major_brand     : isom\n  
    minor_version   : 512\n  
    compatible_brands: isomiso2avc1mp41\n    
    TSSE            : Lavf58.33.100\n   
...
2019-09-29T11:54:57.050809+00:00 app[web.1]: sample.mp4
2019-09-29T11:54:57.050815+00:00 app[web.1]: sample.mp3

You should be getting the same subprocess.run output as the output you get when you use heroku run.

Upvotes: 2

Related Questions