Skip to content

Instantly share code, notes, and snippets.

@Lewiscowles1986
Last active May 14, 2018 22:27
Show Gist options
  • Save Lewiscowles1986/ff7ae9db160dce7275227b03d11a542e to your computer and use it in GitHub Desktop.
Save Lewiscowles1986/ff7ae9db160dce7275227b03d11a542e to your computer and use it in GitHub Desktop.
get media folder length (HH:MM:SS.MS) python

Media Length Utility

Simple wrapper around ffbrobe system utility to allow scanning current folder for total media duration

Currently tested with .mp4, .avi & .mkv could expand to any file with mime-type .startswith('video/') check

Would be nice to have it cycle through subfolders (hence move from listdir to scandir) to give a summary per sub-folder

Changelog

  • Python 3 changes
  • Initial Release
#!/usr/bin/python3
import os
import subprocess
import json
import magic
def ext_cmd(cmd):
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
process.wait()
if process.returncode is 0:
output, errs = process.communicate()
return output.decode("utf-8")
return ""
def get_len(filename):
try:
return float(
json.loads(
ext_cmd([
"ffprobe",
filename,
'-print_format',
'json',
'-show_entries',
'format=duration',
'-loglevel',
'quiet'])
)['format']['duration'])
except:
pass
return 0.0
def is_media_file(x):
if not x.is_file():
return False
if has_media_mime_type(x):
return True
if has_media_ext(x):
return True
return False
def has_media_mime_type(x):
m = magic.Magic(
mime=True,
uncompress=True,
mime_encoding=True,
keep_going=False)
mimetype = m.from_file(x.path)
return (
mimetype.startswith('video/') or
mimetype.startswith('audio/'))
def has_media_ext(x):
return (
# audio types
x.name.endswith('.mp3') or
x.name.endswith('.wav') or
x.name.endswith('.ogg') or
x.name.endswith('.flac') or
# video types
x.name.endswith('.mp4') or
x.name.endswith('.mpeg') or
x.name.endswith('.avi') or
x.name.endswith('.mkv'))
def scandir(mypath=None, depth=-1):
out = ""
totalsecs = sum(
[get_len(x.path) for x in os.scandir(mypath) if is_media_file(x)])
totalmins = int(totalsecs / 60)
totalsecs -= float(totalmins * 60)
totalhours = int(totalmins / 60)
totalmins -= int(totalhours * 60)
out += "{:s}: {:02d}:{:02d}:{:02.2f}\n".format(
mypath,
int(totalhours),
int(totalmins),
float(totalsecs))
if depth > 0 or depth is -1:
n = max(-1, depth-1)
out += "".join(
[scandir(x.path, n) for x in os.scandir(mypath) if x.is_dir()])
return out
if __name__ == '__main__':
print(
scandir(".", -1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment