'How do I use ffmpeg with Python by passing File Objects (instead of locations to files on disk)

I'm trying to use ffmpeg with Python's subprocess module to convert some audio files. I grab the audio files from a URL and would like to just be able to pass the Python File Objects to ffmpeg, instead of first saving them to disk. It would also be very nice if I could just get back a file stream instead of having ffmpeg save the output to a file.

For reference, this is what I'm doing now:

tmp = "/dev/shm"
audio_wav_file = requests.get(audio_url)
##              ##                         ##
## This is what I don't want to have to do ##
wavfile = open(tmp+filename, 'wrb')   
wavfile.write(audio_wav_file.content)
wavfile.close()
##              ##                         ##
conversion = subprocess.Popen('ffmpeg -i "'+tmp+filename+'" -y "'+tmp+filename_noext+'.flac" 2>&1', shell = True, stdout = subprocess.PIPE).stdout.read()

Does anyone know how to do this?

Thanks!



Solution 1:[1]

For anyone still reading this: This can be done without subprocesses by using FFMPEG's pipe protocol instead. If FFMPEG is called using the package ffmpeg-python, the stdout, stderr output of the FFMPEG command can be fed into Python variables as seen here:

out, err = inpstream.output('pipe:', ... ).run(capture_stdout=True)

Solution 2:[2]

Since it looks like you're on Unix (no .exe on the end of 'ffmpeg'), I would recommend using a named pipe, a.k.a. fifo:

mkfifo multimedia-pipe

Have the Python script write the audio data into 'multimedia-file' and ask FFmpeg to read from the same file. I have used this pattern to decode multimedia files into their huge, raw representations for validation without having to occupy disk space.

Alternatively, try passing the 'http://...' URL directly to FFmpeg's input option.

Solution 3:[3]

PyAV can be used with paths or file like objects, from the docs:

file (str) – The file to open, which can be either a string or a file-like object.

(If you have a byte array, you can wrap it with io.BytesIO before passing it to av.open)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 metacollision
Solution 2 Multimedia Mike
Solution 3 jns