Using ffmpeg with subprocess python - python

I am trying to download videos from Wistia and I managed to download them but in .bin&amp format ; I'd like to convert them to .mp4 in order to use OpenCV. For this I am calling ffmpeg with subprocess on Python but I get 1 as the value for the return code, meaning the process has failed. Any idea why, and how I can change this...?
Code is the following:
import subprocess
infile = filename #a bin&amp file
outfile = filename[:-7]+'mp4'
subprocess.run(['ffmpeg', '-i', infile, outfile],shell=True)
I get :
CompletedProcess(args=['ffmpeg', '-i', '58c63bccfcc1c150646c261caad97a58ced4b5e3.bin&amp', '58c63bccfcc1c150646c261caad97a58ced4b5e3.mp4'], returncode=1)
Also, it works in the command prompt...
Thank you for your help,
Sincerely,

Try to use Popen. I I'm using FFmpeg in python and it works well
process_ = subprocess.Popen(ffmpeg_cmd, start_new_session=True)

Related

How can I run a binary executable with input file (bash command) in Python?

I have a binary executable named as "abc" and I have a input file called as "input.txt". I can run these with following bash command:
./abc < input.txt
How can I run this bash command in Python, I tried some ways but I got errors.
Edit:
I also need the store the output of the command.
Edit2:
I solved with this way, thanks for the helps.
input_path = path of the input.txt file.
out = subprocess.Popen(["./abc"],stdin=open(input_path),stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
stdout,stderr = out.communicate()
print(stdout)
use os.system
import os
os.system("echo test from shell");
Using subprocess is the best way to invoke system commands and executables. It provides better control than os.system() and is intended to replace it. The python documentation link below provides additional information.
https://docs.python.org/3/library/subprocess.html
Here is a bit of code that uses subprocess to read output from head to return the first 100 rows from a txt file and process it row by row. It gives you the output (out) and any errors (err).
mycmd = 'head -100 myfile.txt'
(out, err) = subprocess.Popen(mycmd, stdout=subprocess.PIPE, shell=True).communicate()
myrows = str(out.decode("utf-8")).split("\n")
for myrow in myrows:
# do something with myrow
This can be done with os module. The following code works perfectly fine.
import os
path = "path of the executable 'abc' and 'input.txt' file"
os.chdir(path)
os.system("./abc < input.txt")
Hope this works :)

Shell output to a txt file using subprocess in Windows

I am trying to make an output txtfile by using subprocess in Python 3.6 but the thing is that the documention does not really show me how to code in Windows. For instance,
import subprocess
subprocess.run(["ls", "-l"])
FileNotFoundError: [WinError 2] The system cannot find the file specified
Does not work on my computer somehow and neither other examples.
Could you kindly give me some hints to complete this code?
f = open('output.txt', 'w')
subprocess.check_output( ? , shell=True, ? )
print("Example")
print("Example")
f.close()
EDIT: make sure you use subprocess.run or subprocess.Popen
Windows differences aside (like martineau said in the comments to your OP, ls won't work on Windows, you need to use the dir command), you want to use subprocess.PIPE to be able to store the output of a command to a variable. Then you should be able to iterate through that variable, storing it in a file, something like:
# Save the output of the `dir` command
var = subprocess.run( <dir_command>, stdout=subprocess.PIPE, shell=True)
# Iterate through the lines saved in `var`, and write them to `file`, line by line
with open('path/to/file', 'a') as file:
for line in var:
file.write(line)
file.close()

python subprocess with ffmpeg give no output

I m want to extract the scene change timestamp using the scene change detection from ffmpeg. I have to run it on a few hundreds of videos , so i wanted to use a python subprocess to loop over all the content of a folder.
My problem is that the command that i was using for getting these values on a single video involve piping the output to a file which seems to not be an option from inside a subprocess call.
this is my code :
p=subprocess.check_output(["ffmpeg", "-i", sourcedir+"/"+name+".mpg","-filter:v", "select='gt(scene,0.4)',showinfo\"","-f","null","-","2>","output"])
this one tell ffmpeg need an output
output = "./result/"+name
p=subprocess.check_output(["ffmpeg", "-i", sourcedir+"/"+name+".mpg","-filter:v", "select='gt(scene,0.4)',metadata=print:file=output","-an","-f","null","-"])
this one give me no error but doesn't create the file
this is the original command that i use directly with ffmpeg:
ffmpeg -i input.flv -filter:v "select='gt(scene,0.4)',showinfo" -f null - 2> ffout
I just need the ouput of this command to be written to a file, anyone see how i could make it work?
is there a better way then subprocess ? or just another way ? will it be easier in C?
You can redirect the stderr output directly from Python without any need for shell=True which can lead to shell injection.
It's as simple as:
with open(output_path, 'w') as f:
subprocess.check_call(cmd, stderr=f)
Things are easier in your case if you use the shell argument of the subprocess command and it should behave the same. When using the shell command, you can pass in a string as the command rather then a list of args.
cmd = "ffmpeg -i {0} -filter:v \"select='gt(scene,0.4)',showinfo\" -f {1} - 2> ffout".format(inputName, outputFile)
p=subprocess.check_output(cmd, shell=True)
If you want to pass arguments, you can easily format your string

Manipulating image output from shell in python without storing external file

I am trying to store an image that is the result of ffmpeg.
Using this command, I have frame.png as an external file output:
ffmpeg -flags2 +export_mvs -i video.avi -vf 'select=gte(n\,200),codecview=mv=pf+bf+bb' -vframes 1 frame.png
I want to be able to load the frame.png directly into python, maybe using openCV but without saving it in the computer.
I thought of something like this:
cmd = "ffmpeg -flags2 +export_mvs -i video.avi -vf 'select=gte(n\,200),codecview=mv=pf+bf+bb' -vframes 1 frame.png"
img = cv.imread(sp.Popen(cmd, shell=True, stdout = sp.PIPE, stderr = sp.PIPE).communicate()[0])
But I get an error:
TypeError: bad argument type for built-in operation
Any clue how to do this? The idea is, no frame.png should be generated as a file.
You can set the output file as /dev/stdout (you might need to specify the output format with -f)
Then you redirect your output to your python script like so
ffmpeg options /dev/stdout | python your_script.py
Then you can read this question to see how you can read an image from a file object. Just replace StringIO with sys.stdin

Convert mp3 to wav on the fly using ffmpeg in Python

I'm trying to convert a mp3 file on the fly in Python to wav file using ffmpeg.
I call it using subprocess, how can I get it's output to play it as wav on the fly wthout saving it as the file (or playing it while its converting) and then playing it?
This is what I have so far:
I'm using aplay just for a example.
FileLocation = "/home/file.mp3"
subprocess.call(["ffmpeg", "-i", FileLocation etc etc "newfail.wav"])
os.system("aplay ... ") #play it on the fly here
As far as I understand, if I put "-" as file name, it will output it instead to stdout, but I don't know how to read stdout...
To emulate source arg1 arg2 | sink shell command without the shell:
from subprocess import Popen, PIPE
source = Popen(['source', 'arg1', 'arg2'], stdout=PIPE)
sink = Popen(['sink'], stdin=source.stdout)
source.stdout.close()
source.wait()
sink.wait()

Categories