Using ffmpeg in a subprocess

I’m using ffprobe from ffmpeg to get information about user-selected image dimensions. I’m doing this inside of a subprocess, but after my deployed app failed to work I realized I need to detect the right Python executable to use. I found this article helpful for better understanding what the issue is, but I’m having trouble actually resolving it. I don’t really know Python very well.

Here’s what the code looks like now (this works locally):

selected_image_height = subprocess.run(f'ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 {selected_image}', stdout=subprocess.PIPE)

Here’s an example of something I’ve tried based on the help article that doesn’t work:

selected_image_height = subprocess.run([f'{sys.executable}','ffprobe -v error -select_streams v:0 -show_entries stream=width -of csv=s=x:p=0 {selected_image}'], stdout=subprocess.PIPE)

I’ve tried a bunch of other things, but I feel like I’m missing something really fundamental because I don’t know Python well enough. I also realize this is probably really ugly code, sorry! :sweat_smile:

Some additional information in case it’s helpful. I’m using this custom image selector module to let the user pick from a set of images that live together in a folder.

background_input_path = "./input/backgrounds/"
backgrounds = []

for path in os.listdir(background_input_path):
    # Check if current path is a file and add it to a list
    # All the files here should be images. They don't need to be the same size, but ideally they're square
    if os.path.isfile(os.path.join(background_input_path, path)):
        backgrounds.append(background_input_path + path)

# Image selector widget
selected_image = image_select("Background choices", backgrounds)

ETA: Adding ffmpeg to packages.txt did not change the error. I still see:

FileNotFoundError: [Errno 2] No such file or directory: 'ffprobe -v error -select_streams v:0 -show_entries stream=width -of csv=s=x:p=0 ./input/backgrounds/background_5.jpg'

ETA #2: I ended up “fixing” it by just removing this step and instead processing the images so that they’re all 512x512 so that I can make more assumptions later on. Would still be interested to learn more about how to use subprocesses on Streamlit Cloud, but my app is working again for now.

Without digging too deeply, I see that the only thing in your requirement files is streamlit-image-select. I you are going to run system command line processes, you’ll need to make sure the instance spun up to host your app has not just the Python packages added, but also any command-line tools that don’t come out of the box.

@Franky1 has a little example deploying with ffmpeg you can look at: GitHub - Franky1/Streamlit-ffmpeg-Test: Streamlit app to test ffmpeg on Streamlit Cloud (You can see how the extra dependency on ffmpeg–external to Python–is in the packages file. Reference in step 2 of the Streamlit dependencies documentation, then a few more words at the end of the page saying Streamlit Cloud will automatically apt-get whatever you put in the packages file.)

1 Like

Thank you! Since I don’t know Python well, I’d love to avoid using the ffmpeg-python Python wrapper and just continue use the CLI directly if possible. If I want to make sure ffmpeg is installed in the Streamlit environment, do I just add sudo apt install ffmpeg to requirements.txt? It did seem like it was already present because I was able to use it before without installing it separately.

requirements.txt is for your Python packages. packages.txt is for the things outside of Python.

Start by adding a packages.txt file to your project that is just ffmpeg like in the example. :slight_smile:

1 Like

Thank you!

Adding ffmpeg to packages.txt doesn’t change the error I see which still makes me suspect it’s an issue with what I’m trying to do within a subprocess:

FileNotFoundError: [Errno 2] No such file or directory: 'ffprobe -v error -select_streams v:0 -show_entries stream=width -of csv=s=x:p=0 ./input/backgrounds/background_5.jpg'

I ended up “fixing” it by just removing this step and instead processing the images so that they’re all 512x512 so that I can make more assumptions later on. Would still be interested to learn more about how to use subprocesses on Streamlit Cloud, but my app is working again for now. Thanks again for your help!