ffmpeg utils as py module

This commit is contained in:
Ville Rantanen
2021-12-07 20:58:41 +02:00
parent 6c37663f9f
commit a7710d7df9
7 changed files with 210 additions and 4 deletions

View File

@@ -1 +1 @@
../av/ffmpeg-parser ../py-packages/ffmpeg-parser/ffmpegparser/ffmpegparser.py

1
bin/ffprobe-parser Symbolic link
View File

@@ -0,0 +1 @@
../py-packages/ffmpeg-parser/ffmpegparser/ffprobeparser.py

View File

@@ -25,7 +25,7 @@ format: ## Reformat packages with black
black SimpleWebPage/ black SimpleWebPage/
black TSVFilter/ black TSVFilter/
black markslider/ black markslider/
black ffmpeg-parser/
tar-SimpleWebPage: clean ## Create package for SimpleWebPage tar-SimpleWebPage: clean ## Create package for SimpleWebPage
tar czf SimpleWebPage.tgz SimpleWebPage/ tar czf SimpleWebPage.tgz SimpleWebPage/

View File

@@ -8,6 +8,7 @@ import parse
from ansi import cursor from ansi import cursor
from datetime import datetime from datetime import datetime
__version__=1.0
class Chopper: class Chopper:
def __init__(self, buf): def __init__(self, buf):
@@ -247,11 +248,13 @@ def ask_for_overwrite(commands, path):
return commands return commands
if __name__ == "__main__": def main():
commands = sys.argv[1:] commands = sys.argv[1:]
if len(commands) == 1: if len(commands) == 1:
if commands[0] == "-h": if commands[0] == "-h":
print("This command passes all arguments to FFMPEG, and parses output to readable format with progress") print(
"This command passes all arguments to FFMPEG, and parses output to readable format with progress"
)
sys.exit(0) sys.exit(0)
try: try:
has_overwrite = parse_overwrite(commands) has_overwrite = parse_overwrite(commands)
@@ -290,3 +293,7 @@ if __name__ == "__main__":
while process.poll() != None: while process.poll() != None:
time.sleep(1) time.sleep(1)
sys.exit(1) sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,172 @@
#!/usr/bin/env python3
import subprocess
import sys
import os
import time
import parse
import argparse
import json
from ansi.colour import fg, fx
from datetime import datetime
class Probe:
def __init__(self):
parser = argparse.ArgumentParser(description="Readable version of ffprobe. Give filename as argument.")
parser.add_argument("-c", dest="colorize", action="store_true", default=False, help="Colorize")
parser.add_argument("filename", help="File to probe")
parsed = parser.parse_args()
self.filename = parsed.filename
self.colorize = parsed.colorize
self.run_probe()
self.print()
def run_probe(self):
process = subprocess.Popen(
[
"",
"-v",
"error",
"-hide_banner",
"-of",
"default=noprint_wrappers=0",
"-print_format", "json",
"-show_format",
"-show_streams",
self.filename,
],
executable="ffprobe",
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
self.raw_data, errors = process.communicate()
if len(errors) > 0:
print(errors)
self.json_data = json.loads(self.raw_data)
def print(self):
# ~ print(self.json_data['format'])
self.json_data['format']['time'] = self._timestr(self.json_data['format'].get('duration',"0"))
self.json_data['format']['hrate'] = self._speedfmt(self.json_data['format'].get('bit_rate',"0"))
self.json_data['format']['hsize'] = self._sizefmt(float(self.json_data['format'].get('size',0)))
self.json_data['format'].update(self._get_colors())
msg = """{Y}==== Format ===={z}
File: {filename}
Format: {format_long_name} ({format_name})
Length: {time}
Size: {hsize}
Bitrate: {hrate}
Streams: {nb_streams}""".format(**self.json_data['format']
)
print(msg)
for stream in self.json_data['streams']:
original = stream.copy()
stream.update(self._get_colors())
if stream['codec_type'] == "video":
msg = self.format_video(stream)
elif stream['codec_type'] == "audio":
msg = self.format_audio(stream)
elif stream['codec_type'] == "subtitle":
msg = self.format_subtitle(stream)
else:
msg = "Unrecognized stream\n{}".format(json.dumps(original, indent=2))
print(msg)
def format_subtitle(self, stream):
stream['tags-lang'] = stream.get('tags',{}).get('language',"NA")
msg = """{Y}==== Stream:{index} ===={z}
Type: {G}{codec_type}{z}
Codec: {codec_long_name} ({codec_name})
Language: {tags-lang}""".format(**stream)
return msg
def format_video(self, stream):
stream['hrate'] = self._speedfmt(stream.get("bit_rate",0))
stream['fps'] = "{:.2f}".format(float(stream['r_frame_rate'].split('/')[0]) / float(stream['r_frame_rate'].split('/')[1]))
msg = """{Y}==== Stream:{index} ===={z}
Type: {G}{codec_type}{z}
Codec: {codec_long_name} ({codec_name})
Bitrate: {hrate}
Resolution: {width}x{height}
Aspect: {display_aspect_ratio}
Profile: {profile}
FPS: {r_frame_rate} ({fps})""".format(**stream)
return msg
def format_audio(self, stream):
stream['hrate'] = self._speedfmt(stream.get("bit_rate",0))
msg = """{Y}==== Stream:{index} ===={z}
Type: {G}{codec_type}{z}
Codec: {codec_long_name} ({codec_name})
Bitrate: {hrate}
Sample Rate: {sample_rate} Hz
Channels: {channels} ({channel_layout})""".format(**stream)
return msg
def _timestr(self, sec):
msec = int((float(sec) - int(float(sec)))*1000)
sec = int(float(sec))
try:
hours = int(sec) // 3600 % 24
minutes = int(sec) // 60 % 60
seconds = int(sec) % 60
return "{:02d}:{:02d}:{:02d}.{:03d}".format(hours, minutes, seconds, msec)
except Exception:
return sec
def _mbstr(self, b):
try:
return "{:.1f}".format((float(b) / (1024 ** 2)))
except Exception:
return b
def _speedfmt(self, b):
return self._sizefmt(float(b), suffix="bit/s")
try:
return "{:.1f}".format((float(b) / (1024 ** 2)))
except Exception:
return b
def _sizefmt(self, num, suffix='B'):
num = float(num)
for unit in ['','K','M','G','T','P','E','Z']:
if abs(num) < 1024.0:
return "%3.1f %s%s" % (num, unit, suffix)
num /= 1024.0
return "%.1f %s%s" % (num, 'Y', suffix)
def _get_colors(self):
if self.colorize:
return {
'Y': fg.boldyellow,
'G': fg.boldgreen,
'z': fx.reset,
}
else:
return {
'Y': "",
'G': "",
'z': "",
}
def main():
Probe()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,26 @@
from distutils.core import setup
def version_reader(path):
for line in open(path, "rt").read(1024).split("\n"):
if line.startswith("__version__"):
return line.split("=")[1].strip().replace('"', "")
version = version_reader(os.path.join("ffmpegparser", "ffmpegparser.py"))
setup(
name="ffmpegparser",
packages=["ffmpegparser"],
version=version,
description="View parse ffmpeg and ffprobe output nicer",
author="Ville Rantanen",
author_email="ville.q.rantanen@gmail.com",
keywords=["ffmpeg"],
entry_points={
"console_scripts": [
"ffmpeg-parser = ffmpegparser.ffmpegparser:main",
"ffprobe-parser = ffmpegparser.ffprobeparser:main"
]
},
install_requires=["parse", "ansi"],
)