over.core.app configured, beginning main loop
This commit is contained in:
parent
a5c1b81a3a
commit
3243f46772
2 changed files with 79 additions and 6 deletions
31
aux.py
Normal file
31
aux.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#! /bin/env python3
|
||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
|
class Command:
|
||||||
|
def __init__(self, sequence):
|
||||||
|
self.__dict__["sequence"] = list(sequence)
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
found = False
|
||||||
|
|
||||||
|
for i, word in enumerate(self.sequence):
|
||||||
|
if word == name:
|
||||||
|
self.sequence[i] = value
|
||||||
|
found = True
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
raise AttributeError("Command has no attribute \'%s\'" %(name))
|
||||||
|
|
||||||
|
def dump(self, sequence=None):
|
||||||
|
out = []
|
||||||
|
|
||||||
|
if not sequence:
|
||||||
|
sequence = self.sequence
|
||||||
|
|
||||||
|
for item in sequence:
|
||||||
|
if type(item) is list:
|
||||||
|
out += self.dump(item)
|
||||||
|
else:
|
||||||
|
out.append(str(item))
|
||||||
|
|
||||||
|
return out
|
54
over-video.py
Normal file → Executable file
54
over-video.py
Normal file → Executable file
|
@ -1,11 +1,53 @@
|
||||||
#! /bin/env python3
|
#! /bin/env python3
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
# ffmpeg -i 2518* -codec:v libtheora -qscale:v 3 -codec:a libvorbis -qscale:a 2 output.ogv
|
import json
|
||||||
# ffmpeg -i 2518* -c:v libx264 -preset slow -crf 22 -profile:v high -level 4.2 -codec:a libvorbis -qscale:a 2 output.mp4
|
import os
|
||||||
|
|
||||||
# ffmpeg -i 2518* -af "volumedetect" -f null /dev/null | parse mean_volume: -22.8 dB
|
|
||||||
# -filter:a "volume=2.8dB"
|
|
||||||
|
|
||||||
import over
|
import over
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
from aux import Command
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
prefix = over.core.textui.prefix
|
||||||
|
_print = over.core.textui.Output("over.video")
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
command = over.core.types.ndict()
|
||||||
|
command.identify = ("ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "INFILE")
|
||||||
|
command.normalize_prepass = ("ffmpeg", "-i", "INFILE", "-af", "volumedetect", "-f", "null", "/dev/null")
|
||||||
|
command.encode_theora = ("ffmpeg", "-i", "INFILE", "-codec:v", "libtheora", "-qscale:v", "VQ", "-codec:a", "libvorbis", "-qscale:a", "AQ", "NORMALIZE", "OUTFILE")
|
||||||
|
command.encode_x264 = ("ffmpeg", "-i", "INFILE", "-c:v", "libx264", "-preset", "slow", "-crf", "VQ", "-profile:v", "high", "-level", "4.2", "-codec:a", "libvorbis", "-qscale:a", "AQ", "NORMALIZE", "OUTFILE")
|
||||||
|
command.normalize = ("-filter:a", "VOLUME")
|
||||||
|
|
||||||
|
# --------------------------------------------------
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main = over.core.app.Main("Over-Video", "0.1", "AWARE-Overwatch Joint Software License", "~/.over/video.cfg")
|
||||||
|
main.add_option("profile", "str", "x264", "Encoding profile to use. Available are either §mtheora§/ for Theora and Vorbis in an Ogg container, or §mx264§/ for H.264 and Vorbis in an MP4 container.")
|
||||||
|
main.add_option("video-quality", "float", 22, "Video encoding quality. Use 0-10 for Theora (0 being the lowest, 5-7 is generally watchable) and 0-51 for x264 (0 being lossless, 18-28 is reasonable).", short_name="v")
|
||||||
|
main.add_option("audio-quality", "float", 2, "Audio encoding quality with -1 being the worst and 10 being the best.", short_name="a")
|
||||||
|
main.add_option("normalize", "bool", True, "Normalize the audio track.", short_name="N")
|
||||||
|
main.add_option("normalize-mean", "float", -20.0, "Target mean volume to target.", short_name="n")
|
||||||
|
main.add_option("dump-commands", "bool", False, "Print ffmpeg commands that would be executed. Implies §B--no-§garmed§/. If §B--§gnormalize§/ is in effect, the normalization pre-pass will still be performed so that the proper volume correction can be computed.", short_name="D")
|
||||||
|
main.add_option("armed", "bool", False, "Perform the suggested action.", short_name="A", use_cfg_file=False)
|
||||||
|
main.enable_help("h")
|
||||||
|
main.add_help("Description", ["Over-Video is a simple video converter."])
|
||||||
|
main.parse()
|
||||||
|
|
||||||
|
for tgt in main.targets:
|
||||||
|
if not os.path.exists(tgt) or os.path.isdir(tgt):
|
||||||
|
_print("target §y%s§/ §ris not a readable file§/, skipping" %(tgt), prefix.fail)
|
||||||
|
continue
|
||||||
|
|
||||||
|
_print("processing §B%s§/" %(tgt), prefix.start)
|
||||||
|
|
||||||
|
identify_cmd = Command(command.identify)
|
||||||
|
identify_cmd.INFILE = tgt
|
||||||
|
identify_raw = subprocess.check_output(identify_cmd.dump()).decode("utf-8")
|
||||||
|
identify_dict = json.loads(identify_raw)
|
||||||
|
|
||||||
|
print(identify_dict)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue