reordered code to a more logical order. dict comprehension is now used.

This commit is contained in:
Kjistóf 2017-02-06 13:10:47 +01:00
parent a0a040389f
commit 8d19a00cf5

View File

@ -38,19 +38,37 @@ def print_opt(*args, **kwargs):
print(*args, **kwargs) print(*args, **kwargs)
def get_command_stderr(command): def run(url, files_dict, directory):
process = Popen(command, stderr=PIPE, stdout=PIPE) # download streams and update FILE dict with extensions
out, err = process.communicate() download_audio_stream(url, files_dict)
return err download_video_stream(url, files_dict)
read_extensions(files_dict, directory)
# get stream lengths via ffprobe
audioLen = get_length(files_dict[Stream.AUDIO])
videoLen = get_length(files_dict[Stream.VIDEO])
def get_duration(ffprobe_output): # decide which stream needs some looping
durationPattern = r'.*Duration:\s(.+),\sstart.*' longer = audioLen if audioLen > videoLen else videoLen
regex = match(durationPattern, str(ffprobe_output)) shorter = audioLen if audioLen < videoLen else videoLen
duration = regex.groups()[0] if regex else None shorterFile = files_dict[Stream.AUDIO] if audioLen < videoLen else files_dict[Stream.VIDEO]
if not duration: files_dict[File.LOOP] += splitext(shorterFile)[1]
raise ValueError('Cannot process ffprobe output!') files_dict[File.FRACTION] += splitext(shorterFile)[1]
return duration
# calculate how many times to loop
times = longer.total_seconds() / shorter.total_seconds()
timesLoop_base = floor(times)
timesLoop_fraction = times % 1
# write concat helper file for ffmpeg
with open(files_dict[File.LIST], 'w') as f:
for i in range(timesLoop_base):
print("file '{}'".format(shorterFile), file=f)
print("file '{}'".format(files_dict[File.FRACTION]), file=f)
# loop & mux streams
loop_shorter_stream(files_dict, shorter, shorterFile, timesLoop_fraction)
mux_streams(files_dict)
@call_verbose(before_message='Downloading audio stream... ') @call_verbose(before_message='Downloading audio stream... ')
@ -78,6 +96,26 @@ def read_extensions(file_dict, directory):
file_dict[filename] = fullname file_dict[filename] = fullname
def get_length(file):
data = get_duration(get_command_stderr(('ffprobe', file))).split(':')
return timedelta(hours=float(data[0]), minutes=float(data[1]), seconds=float(data[2]))
def get_command_stderr(command):
process = Popen(command, stderr=PIPE, stdout=PIPE)
out, err = process.communicate()
return err
def get_duration(ffprobe_output):
durationPattern = r'.*Duration:\s(.+),\sstart.*'
regex = match(durationPattern, str(ffprobe_output))
duration = regex.groups()[0] if regex else None
if not duration:
raise ValueError('Cannot process ffprobe output!')
return duration
@call_verbose(before_message='Looping shorter stream... ') @call_verbose(before_message='Looping shorter stream... ')
def loop_shorter_stream(file_dict, shorter, shorter_file, loop_fraction): def loop_shorter_stream(file_dict, shorter, shorter_file, loop_fraction):
# prepare last fractional loop # prepare last fractional loop
@ -99,11 +137,6 @@ def mux_streams(file_dict):
stdout=DEVNULL, stderr=DEVNULL) stdout=DEVNULL, stderr=DEVNULL)
def get_length(file):
data = get_duration(get_command_stderr(('ffprobe', file))).split(':')
return timedelta(hours=float(data[0]), minutes=float(data[1]), seconds=float(data[2]))
def determine_output_filename(url, user_supplied, extension, files_dict): def determine_output_filename(url, user_supplied, extension, files_dict):
if user_supplied is None: if user_supplied is None:
files_dict[File.OUTPUT] = check_output(('youtube-dl', '--get-title', url)).decode('utf-8').strip() files_dict[File.OUTPUT] = check_output(('youtube-dl', '--get-title', url)).decode('utf-8').strip()
@ -148,42 +181,12 @@ def yes_no_question(question, default):
print("Please respond with 'yes'(y) or 'no'(n)!") print("Please respond with 'yes'(y) or 'no'(n)!")
def run(url, files_dict, directory):
# download streams and update FILE dict with extensions
download_audio_stream(url, files_dict)
download_video_stream(url, files_dict)
read_extensions(files_dict, directory)
# get stream lengths via ffprobe
audioLen = get_length(files_dict[Stream.AUDIO])
videoLen = get_length(files_dict[Stream.VIDEO])
# decide which stream needs some looping
longer = audioLen if audioLen > videoLen else videoLen
shorter = audioLen if audioLen < videoLen else videoLen
shorterFile = files_dict[Stream.AUDIO] if audioLen < videoLen else files_dict[Stream.VIDEO]
files_dict[File.LOOP] += splitext(shorterFile)[1]
files_dict[File.FRACTION] += splitext(shorterFile)[1]
times = longer.total_seconds() / shorter.total_seconds()
timesLoop_base = floor(times)
timesLoop_fraction = times % 1
# write concat helper file for ffmpeg
with open(files_dict[File.LIST], 'w') as f:
for i in range(timesLoop_base):
print("file '{}'".format(shorterFile), file=f)
print("file '{}'".format(files_dict[File.FRACTION]), file=f)
loop_shorter_stream(files_dict, shorter, shorterFile, timesLoop_fraction)
mux_streams(files_dict)
if __name__ == '__main__': if __name__ == '__main__':
args = parse_cmd_arguments() args = parse_cmd_arguments()
VERBOSE = False if args.nonverbose else True VERBOSE = False if args.nonverbose else True
# create dict that contains files used
FILES = {Stream.AUDIO: 'audio', Stream.VIDEO: 'video', FILES = {Stream.AUDIO: 'audio', Stream.VIDEO: 'video',
File.LIST: 'list.txt', File.LOOP: 'loop', File.FRACTION: 'fraction', File.LIST: 'list.txt', File.LOOP: 'loop', File.FRACTION: 'fraction',
File.OUTPUT: 'output'+args.extension} File.OUTPUT: 'output'+args.extension}
@ -202,10 +205,10 @@ if __name__ == '__main__':
else: else:
remove(FILES[File.OUTPUT]) remove(FILES[File.OUTPUT])
# create temporary directory to work in
with TemporaryDirectory() as dir: with TemporaryDirectory() as dir:
# update temporary file locations in FILES dict # update temporary file locations in FILES dict
for key in FILES: for key in {key: FILES[key] for key in FILES if key not in OUTPUT_KEYS}:
if key not in OUTPUT_KEYS:
FILES[key] = join(dir, FILES[key]) FILES[key] = join(dir, FILES[key])
run(URL, FILES, dir) run(URL, FILES, dir)