1

I am iterating through a directory and running ffprobe against each file to get it's duration. However, the only output I get is

b''
b''

Below is the part of the code I am using,

for y in filename:
    p1 = subprocess.Popen (['ffprobe', '-i', y, '-show_entries', 'format=duration', '-sexagesimal', '-v', 'quiet', '-of', 'csv=%s' % ("p=0")], stdout=subprocess.PIPE).communicate()[0]
    print (p1)

Currently, the directory I am iterating through has two files in it.

Any ideas how to get the actual duration printed please?

Thanks.

user243
  • 53
  • 5
  • Have you tested the output of the command you pass to `Popen` inside a terminal? – ImranD Nov 04 '19 at 15:19
  • 1
    yes, and it works. Below is the result,`fprobe -i /Users/mbpuser1/Desktop/Remote2/av4_file1.ts -show_entries format=duration -sexagesimal -v quiet -of csv="p=0" 0:09:11.112389 ` – user243 Nov 04 '19 at 15:22
  • Have you verified the `filename` var? Does it contain the strings it is supposed to contain? If they contain a relative path, try an absolute path. If nothing is wrong with `filename`, try using `os.system` or `os.popen` instead of `subprocess.Popen`. You can directly pass a string to these methods, no need to split it. If it still doesn't work, I'm sorry but I'm out of ideas :/ – ImranD Nov 04 '19 at 15:53
  • I must admit that I am very new to programming but I guess there is no output being printed. I think the `b' '` output is because I was interpreting the code using `python3.7`. If I interpret the code using `python2.7` then I get blank line as output . – user243 Nov 04 '19 at 16:01
  • You are right, there is a difference between python 3 and 2. You can read a bit more [here](https://stackoverflow.com/a/6269785/12096138) but it will probably not help you there. Try printing the value of `y` inside the `for` loop (you can juste do : `print(y)`) and check if its values are correct. If they are correct, replace the line `p1 = subprocess.Popen(...` with : `p1 = os.popen("ffprobe -i " + y + " -show_entries ...).read()` (don't put literal `...` obviously, replace them with the rest of the cmd) and don't forget to `import os` beforehand. It this doesn't work, I'm out of ideas – ImranD Nov 04 '19 at 16:12

2 Answers2

1
import subprocess
import glob

for y in glob.glob("*.mkv"):
    p1 = subprocess.check_output(
        [
            "ffprobe",
            "-i",
            y,
            "-show_entries",
            "format=duration",
            "-sexagesimal",
            "-v",
            "quiet",
            "-of",
            "csv=%s" % ("p=0"),
        ],
        encoding="utf-8",
    ).strip()
    print(y, p1)

works fine for me. (That is, using check_output() and adding the encoding parameter.)

The result is

2018-02-19T00:01.mkv 0:17:47.120000

as expected.

My Ffmpeg version is, for what it's worth,

ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers
built with Apple clang version 11.0.0 (clang-1100.0.33.8)
libavutil      56. 31.100 / 56. 31.100
libavcodec     58. 54.100 / 58. 54.100
libavformat    58. 29.100 / 58. 29.100
libavdevice    58.  8.100 / 58.  8.100
libavfilter     7. 57.100 /  7. 57.100
libavresample   4.  0.  0 /  4.  0.  0
libswscale      5.  5.100 /  5.  5.100
libswresample   3.  5.100 /  3.  5.100
libpostproc    55.  5.100 / 55.  5.100
AKX
  • 152,115
  • 15
  • 115
  • 172
0

If your internal command is correct, the way to get subprocess output is as so:

p1 = subprocess.run(['ffprobe', '-i', y, '-show_entries', 'format=duration', '-sexagesimal', '-v', 'quiet', '-of', 'csv=%s' % ("p=0")], shell=True, capture_output=True).stdout

DUDANF
  • 2,618
  • 1
  • 12
  • 42