avconv with subprocess - python

It's seems like I never really manage to wrap my head around subprocess. This commandline works in bash
avconv -i "concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts" -vcodec copy -acodec copy /tmp/test1.ts
Bu if I try this:
cmdline = ['avconv', '-i "concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts"', '-vcodec copy', '-acodec copy', '/tmp/test1.ts']
subprocess.call(cmdline)
It exit avconv with the following error:
avconv version 0.8.3-4:0.8.3-0ubuntu0.12.04.1, Copyright (c) 2000-2012 the Libav developers
built on Jun 12 2012 16:52:09 with gcc 4.6.3
Unrecognized option 'i "concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts"'
Failed to set value '-vcodec copy' for option 'i "concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts"'
1
I've tried some variants (including shell=True) but I can't figure out the problem.
Update
Cjb made an answer that really worked. But my real code is more complicated. I believe it's hard to get something out of it. But I throw it in here just in case there is an obvoius problem that I missed.
def run_avconv(output_dir, fnames):
full_fnames = [os.path.join(output_dir, fname.replace('\n', ''))
for fname in fnames]
concatted_files = '|'.join(full_fnames)
cmd_line = [AVCONV_CMD,
'-i',
'"concat:' + concatted_files + '"',
'-vcodec',
'copy',
'-acodec',
'copy',
os.path.join(output_dir, 'out.ts')]
subprocess.Popen(cmd_line)
the full_fnames variable is:
['/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment2.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment3.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment4.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment5.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment6.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment7.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment8.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment9.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment10.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment11.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment12.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment13.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment14.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment15.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment16.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment17.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment18.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment19.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment20.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment21.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment22.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment23.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment24.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment25.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment26.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment27.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment28.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment29.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment30.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment31.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment32.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment33.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment34.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment35.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment36.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment37.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment38.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment39.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment40.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment41.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment42.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment43.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment44.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment45.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment46.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment47.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment48.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment49.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment50.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment51.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment52.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment53.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment54.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment55.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment56.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment57.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment58.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment59.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment60.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment61.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment62.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment63.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment64.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment65.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment66.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment67.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment68.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment69.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment70.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment71.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment72.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment73.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment74.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment75.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment76.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment77.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment78.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment79.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment80.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment81.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment82.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment83.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment84.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment85.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment86.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment87.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment88.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment89.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment90.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment91.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment92.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment93.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment94.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment95.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment96.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment97.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment98.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment99.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment100.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment101.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment102.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment103.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment104.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment105.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment106.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment107.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment108.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment109.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment110.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment111.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment112.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment113.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment114.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment115.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment116.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment117.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment118.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment119.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment120.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment121.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment122.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment123.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment124.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment125.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment126.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment127.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment128.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment129.ts',
'/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment130.ts']

Try it with this:
cmdline = [
'avconv',
'-i',
'concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts',
'-vcodec',
'copy',
'-acodec',
'copy',
'/tmp/test1.ts',
]
subprocess.call(cmdline)
You really want to pass each separate part as a different item in the list.

The answer by #djc is correct, however if you wanted to work by copying and pasting a string, you can do something like this:
import shlex
from pprint import pprint
cmd = """avconv -i "concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts" -vcodec copy -acodec copy /tmp/test1.ts"""
for_subprocess = shlex.split(cmd)
pprint(for_subprocess)
['avconv',
'-i',
'concat:/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment0.ts|/tmp/BABAR_AND_THE_A-011A-hts-a-v1-cc3651d01841d748_Layer6/6148_Period1/segment1.ts',
'-vcodec',
'copy',
'-acodec',
'copy',
'/tmp/test1.ts']

Related

FFMPEG Frame-exact Video Cropping

Goal: To crop a video at a specific frame using FFMPEG
Problem: Video freezes at the end for ~1s
I'm new to FFMPEG, so not sure if any other details are needed to debug this.
import subprocess
import datetime
# Calculate start and end times in hh:mm:ss.ms
start_frame, end_frame = (9553, 10181)
start_time = str(datetime.timedelta(seconds=start_frame/fps))
end_time = str(datetime.timedelta(seconds=end_frame/fps))
cmd = ['ffmpeg', '-y', '-ss', start_time, '-to', end_time, '-i', input_path, '-c', 'copy', clip_path]
subprocess.call(cmd)
Values:
Start Frame: 9553
End Frame: 10181
Start Time: 0:06:22.120000
End Time: 0:06:47.240000
You will have to cut on key frames only or remove -c copy and re-encode.

How to check if a video has sound in Python?

I would just like a True if a video has audio or False if it does not have audio.
I feel like I'm almost there using subprocess.
I get info about the video file running ffprobe and splitting the results into a list.
I've tried matching a string that does or does not have audio in the list but this is not giving me consistant results.
from subprocess import Popen, PIPE
import subprocess
b = '/path/to/mp4'
'0:1' in str(subprocess.run(['ffprobe', b], stdout=PIPE, stderr=PIPE).stderr.split()[-20])
The line above checks if there is a second stream in the video file in the 20th from the last line. Like I said, not always consistent.
I'm just having trouble requesting or parsing what I'm getting from ffmprobe.
Here is everything returned from ffprobe instead of just the 20th from the last item.
b = '/path/to/mp4'
subprocess.run(['ffprobe', b], stdout=PIPE, stderr=PIPE).stderr.split()
returns...
[b'ffprobe',
b'version',
b'4.2.4-1ubuntu0.1',
b'Copyright',
b'(c)',
b'2007-2020',
b'the',
b'FFmpeg',
b'developers',
b'built',
b'with',
b'gcc',
b'9',
b'(Ubuntu',
b'9.3.0-10ubuntu2)',
b'configuration:',
b'--prefix=/usr',
b'--extra-version=1ubuntu0.1',
b'--toolchain=hardened',
b'--libdir=/usr/lib/x86_64-linux-gnu',
b'--incdir=/usr/include/x86_64-linux-gnu',
b'--arch=amd64',
b'--enable-gpl',
b'--disable-stripping',
b'--enable-avresample',
b'--disable-filter=resample',
b'--enable-avisynth',
b'--enable-gnutls',
b'--enable-ladspa',
b'--enable-libaom',
b'--enable-libass',
b'--enable-libbluray',
b'--enable-libbs2b',
b'--enable-libcaca',
b'--enable-libcdio',
b'--enable-libcodec2',
b'--enable-libflite',
b'--enable-libfontconfig',
b'--enable-libfreetype',
b'--enable-libfribidi',
b'--enable-libgme',
b'--enable-libgsm',
b'--enable-libjack',
b'--enable-libmp3lame',
b'--enable-libmysofa',
b'--enable-libopenjpeg',
b'--enable-libopenmpt',
b'--enable-libopus',
b'--enable-libpulse',
b'--enable-librsvg',
b'--enable-librubberband',
b'--enable-libshine',
b'--enable-libsnappy',
b'--enable-libsoxr',
b'--enable-libspeex',
b'--enable-libssh',
b'--enable-libtheora',
b'--enable-libtwolame',
b'--enable-libvidstab',
b'--enable-libvorbis',
b'--enable-libvpx',
b'--enable-libwavpack',
b'--enable-libwebp',
b'--enable-libx265',
b'--enable-libxml2',
b'--enable-libxvid',
b'--enable-libzmq',
b'--enable-libzvbi',
b'--enable-lv2',
b'--enable-omx',
b'--enable-openal',
b'--enable-opencl',
b'--enable-opengl',
b'--enable-sdl2',
b'--enable-libdc1394',
b'--enable-libdrm',
b'--enable-libiec61883',
b'--enable-nvenc',
b'--enable-chromaprint',
b'--enable-frei0r',
b'--enable-libx264',
b'--enable-shared',
b'libavutil',
b'56.',
b'31.100',
b'/',
b'56.',
b'31.100',
b'libavcodec',
b'58.',
b'54.100',
b'/',
b'58.',
b'54.100',
b'libavformat',
b'58.',
b'29.100',
b'/',
b'58.',
b'29.100',
b'libavdevice',
b'58.',
b'8.100',
b'/',
b'58.',
b'8.100',
b'libavfilter',
b'7.',
b'57.100',
b'/',
b'7.',
b'57.100',
b'libavresample',
b'4.',
b'0.',
b'0',
b'/',
b'4.',
b'0.',
b'0',
b'libswscale',
b'5.',
b'5.100',
b'/',
b'5.',
b'5.100',
b'libswresample',
b'3.',
b'5.100',
b'/',
b'3.',
b'5.100',
b'libpostproc',
b'55.',
b'5.100',
b'/',
b'55.',
b'5.100',
b'Input',
b'#0,',
b'mov,mp4,m4a,3gp,3g2,mj2,',
b'from',
b"'/media/iii/Q2/tor/Reddit/Subs/unexpected/l2aifial2ir51.mp4':",
b'Metadata:',
b'major_brand',
b':',
b'isom',
b'minor_version',
b':',
b'512',
b'compatible_brands:',
b'isomiso2avc1mp41',
b'encoder',
b':',
b'Lavf58.29.100',
b'Duration:',
b'00:00:16.27,',
b'start:',
b'0.000000,',
b'bitrate:',
b'1341',
b'kb/s',
b'Stream',
b'#0:0(und):',
b'Video:',
b'h264',
b'(Main)',
b'(avc1',
b'/',
b'0x31637661),',
b'yuv420p,',
b'384x480',
b'[SAR',
b'1:1',
b'DAR',
b'4:5],',
b'1205',
b'kb/s,',
b'30',
b'fps,',
b'30',
b'tbr,',
b'12k',
b'tbn,',
b'60',
b'tbc',
b'(default)',
b'Metadata:',
b'handler_name',
b':',
b'Bento4',
b'Video',
b'Handler',
b'Stream',
b'#0:1(und):',
b'Audio:',
b'aac',
b'(LC)',
b'(mp4a',
b'/',
b'0x6134706D),',
b'48000',
b'Hz,',
b'stereo,',
b'fltp,',
b'128',
b'kb/s',
b'(default)',
b'Metadata:',
b'handler_name',
b':',
b'Bento4',
b'Sound',
b'Handler']
I have also tried modifying this function from one that returns the duration of video files to one that returns True or False for audio because this is probably a less hacky way of getting the bool. I'm a bit out of my depth trying to use these different options.
def get_length(filename):
result = subprocess.run(["ffprobe", "-v", "error", "-show_entries",
"format=duration", "-of",
"default=noprint_wrappers=1:nokey=1", filename],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return float(result.stdout)
I believe I found the option to sort any video file with an output of 1 (for True, has sound), or 0 (for False, does not have sound) by passing nb_streams in the format option below.
Used a combination of this answer and the docs for ffmpeg to figure this out.
def has_audio(filename):
result = subprocess.run(["ffprobe", "-v", "error", "-show_entries",
"format=nb_streams", "-of",
"default=noprint_wrappers=1:nokey=1", filename],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return (int(result.stdout) -1)
The code actually returns the number of streams. 2 for two streams, video and audio, or 1 for just video. I subtracted a one because I want the bool answer.
This should probably not be used to sort audio only files. Though I wonder if 1 for just video and 2 for audio and video is always the case for known video files. Can a video file have 3 or more streams?
Building on previous answers, this will check each stream to see if at least one has an "audio" type codec. Please note that an audio stream may be present but silent, in which case this will still return True.
from subprocess import check_output
import json
def has_audio_streams(file_path):
command = ['ffprobe', '-show_streams',
'-print_format', 'json', file_path]
output = check_output(command)
parsed = json.loads(output)
streams = parsed['streams']
audio_streams = list(filter((lambda x: x['codec_type'] == 'audio'), streams))
return len(audio_streams) > 0
The answer isn't too hard.
MAC
pip3 install ffprobe
WINDOWS
pip install ffprobe
LINUX
pip install ffprobe
USAGE
ffprobe -show_streams -print_format json input.mov should work.
One can use pymediainfo module for this.
def has_audio(p):
from pymediainfo import MediaInfo
fileInfo = MediaInfo.parse(p)
return any([track.track_type == 'Audio' for track in fileInfo.tracks])

Python subprocess - returned non-zero exit status 1

I want to execute this UNIX command using python 3.6 and subprocess module:
cat report_html | ./wkhtmltopdf - test.pdf
What I tried
import subprocess
report_html = "<html><body><h1>Hello World</h1></body></html>"
subprocess.run(['cat', report_html, '|', '/tmp/wkhtmltopdf', '-', '/tmp/test.pdf'], check=True)
Error I am getting
{
"errorMessage": "Command '['cat', '<html><body><h1>Hello World</h1></body></html>', '|', '/tmp/wkhtmltopdf', '-', '/tmp/test.pdf']' returned non-zero exit status 1.",
"errorType": "CalledProcessError",
"stackTrace": [
[
"/var/task/lambda_function.py",
30,
"lambda_handler",
"subprocess.run(['cat', report_html, '|', '/tmp/wkhtmltopdf', '-', '/tmp/test.pdf'], check=True)"
],
[
"/var/lang/lib/python3.6/subprocess.py",
438,
"run",
"output=stdout, stderr=stderr)"
]
]
}
Please guide me on how to fix this.
If you want to use pipe in subprocess, you must use shell=True argument, which is not the best solution for multiple reasons.
Usually, this is done by running two separate processes and pass the output of the first one into the second one, for example:
cat = subprocess.Popen(['cat', 'report_html'], stdout=subprocess.PIPE) # Change stdout to PIPE
output = subprocess.check_output(['wkhtmltopdf', '-', 'xxx.pdf'], stdin=cat.stdout) # Get stdin from cat.stdout

How to preview the ffmpeg command line while using ffmpeg-python

Let's say I implement the following python script that uses ffmpeg-python:
# facetime.py
import ffmpeg
ffmpeg \
.input(
'FaceTime',
format='avfoundation',
pix_fmt='uyvy422',
framerate=30
) \
.output(
'out.mp4',
pix_fmt='yuv420p',
vframes=100
) \
.run()
Is there a mechanism to print to the stdout the corresponding ffmpeg command that will be executed?
Found it:
cmd = ffmpeg \
.input(
'FaceTime',
format='avfoundation',
pix_fmt='uyvy422',
framerate=30
) \
.output(
'out.mp4',
pix_fmt='yuv420p',
vframes=100
)
args = cmd.get_args()
print(f'Args: {args}')
Output:
Args: ['-f', 'avfoundation', '-framerate', '30', '-pix_fmt', 'uyvy422', '-i', 'FaceTime', '-pix_fmt', 'yuv420p', '-vframes', '100', 'out.mp4']

Printing a calendar via Python. Code is not working =/

I am making a small program in Python (PyGTK) that prints out a calendar (Gregorian) for a year the user inputs.
Here is my code:
#!/usr/bin/env python
import pygtk, gtk, subprocess
pygtk.require("2.0")
class Base:
def printing(self, widget):
text = self.textbox.get_text()
printingit = "cal -y %s | lpr" % (text)
process = subprocess.Popen(printingit.split(), stdout=subprocess.PIPE)
output = process.communicate()[0]
def __init__(self):
self.win = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.win.set_position(gtk.WIN_POS_CENTER)
self.win.set_size_request(350, 200)
self.win.set_resizable(False)
self.win.set_title("Calendar")
self.win.connect('destroy',lambda w: gtk.main_quit())
self.textbox = gtk.Entry()
self.textbox.set_size_request(70, 30)
self.lable = gtk.Label("Year:")
self.button = gtk.Button("Print")
self.button.set_size_request(60, 45)
self.button.connect("clicked", self.printing)
box = gtk.Fixed()
box.put(self.lable, 160, 25)
box.put(self.textbox, 140, 40)
box.put(self.button, 145, 100)
self.win.add(box)
self.win.show_all()
def main(self):
gtk.main()
if __name__ == "__main__":
base = Base()
base.main()
It's not working when actually printing the command cal -y %s | lpr % (text). I have made it so it replaces the textbox's text with the final command it should get and it changes to what I want it to be cal -y 2015 | lpr. I tried just putting that into terminal and it worked as usual, it's confusing me a lot!
I ran the program in terminal and this is the message I recieve when it tries to print:
Usage: cal [general options] [-hjy] [[month] year]
cal [general options] [-hj] [-m month] [year]
ncal [general options] [-bhJjpwySM] [-s country_code] [[month] year]
ncal [general options] [-bhJeoSM] [year]
General options: [-NC3] [-A months] [-B months]
For debug the highlighting: [-H yyyy-mm-dd] [-d yyyy-mm]
If anyone understands why this is happening I would be extremely grateful! Thank you in advance =D
Harry
If you want to use shell syntax (pipe) in your command, you need to pass the command as as string to the Popen constructor, not as list. And you must use shell=True:
output = subprocess.check_output(printingit, shell=True)
Without that, the executed command would be the same as:
cal '-y' 'text' '|' 'lpr'
But as you're getting part of the input from a text field, you shouldn't directly pass it tho a shell.
Alternatively, you can create the pipe yourself:
lpr = subprocess.Popen('lpr', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
process = subprocess.Popen(['cal', '-y', text], stdout=lpr.stdin)
output = lpr.communicate()
process.wait()
By the way, instead of using subprocess to invoke cal you could use the calendar module. cal -y 2012 does the same as calendar.calendar(2014), so you could replace your code with:
cal = calendar.calendar(int(text))
process = subprocess.Popen(['lpr'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = process.communicate(cal) # cal.encode(locale.getpreferredencoding(False)) for python3

Categories