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'])
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).
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
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
.
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
.