I'm very new
So this getLength function will run fine in python 2.7 but I can't get it to work in 3.10. Was wondering if anyone could suggest what may need to be changed because I am at a loss. When I try to print the return there is nothing there. I am 95% sure the issue is with the result = subprocess.Popen() line but I include the entire function for completeness
#function... returns the duration HH:MM:SS of a video file
def getLength(filename):
#uses ffprobe to get info about the video file
result = subprocess.Popen(["ffprobe", filename],
stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
#finds the info that has the word "Duration"
y = [x for x in result.stdout.readlines() if "Duration: " in x]
#get the location of the "Duration: " phrase
loc = y[0].find("Duration: ")
#assuming we find the location of that phrase..
if loc != -1:
#cut out everything before and everything more than 10 characters later
print ( y[0][loc 10:loc 18] )
return y[0][loc 10:loc 18]
else:
#if we don't find anything then set it to be 2 seconds of nothing...
print ( y[0][loc 10:loc 18] )
return '00:00:02'
CodePudding user response:
I'm pretty sure that the output in python3 is a byte stream rather than a str.
Try this:
import subprocess
media = "/home/rolf/BBB.ogv"
try:
comm = subprocess.Popen(['ffprobe', '-hide_banner', '-show_entries', 'format=size, duration',\
'-i', media], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
except Exception as e:
pass
try:
with comm.stdout:
for i in iter(comm.stdout.readline, b''):
if i != '':
print(i)
else:
break
except Exception as e:
print("Error: ", str(e))
Output:
python probe.py
Input #0, ogg, from '/home/rolf/BBB.ogv':
Duration: 00:01:00.14, start: 0.000000, bitrate: 264 kb/s
Stream #0:0(eng): Video: theora, yuv420p, 640x360 [SAR 1:1 DAR 16:9], 24 fps, 24.04 tbr, 24.04 tbn
Metadata:
creation_time : 2011-03-16 10:41:52
handler_name : Apple Video Media Handler
encoder : Lavc56.60.100 libtheora
major_brand : mp42
minor_version : 1
compatible_brands: mp42avc1
Stream #0:1(eng): Audio: vorbis, 44100 Hz, mono, fltp, 80 kb/s
Metadata:
creation_time : 2011-03-16 10:41:53
handler_name : Apple Sound Media Handler
encoder : Lavc56.60.100 libvorbis
major_brand : mp42
minor_version : 1
compatible_brands: mp42avc1
[FORMAT]
duration=60.139683
size=1992112
[/FORMAT]
CodePudding user response:
If you are OK with the duration in seconds (not in the HH:MM:SS
notation), I prefer to use the -of json
option so I can use json
package to parse the ffprobe output:
import subprocess as sp
import json
from pprint import pprint
out = sp.run(f'ffprobe -hide_banner -of json -show_entries format:stream "{filename}"',
stdout=sp.PIPE, universal_newlines=True)
results = json.loads(out.stdout)
pprint(results) # to see the full details
format_duration = float(results['formats']['duration']) # in seconds
stream_durations = [float(st['duration']) for st in results['streams']] # in seconds
Note: You must specify -show_entries
option or it'll return an empty JSON
Just to plug my library (pip install fmpegio-core
), you can alternately run:
import ffmpegio
file_duration = ffmpegio.probe.format_basic(filename)['duration']