def convert_audio_file(file, file_out, args): global audio_container, info, exit_code, FFMPEG_PROGRESS, FFMPEG_DURATION, FFMPEG_SIZE # ffmpeg progress FFMPEG_PROGRESS = 0.0 FFMPEG_DURATION = '00:00:00.000' FFMPEG_SIZE = 0.0 print('# Converting to Audio file') show_file_size(file) seconds = show_file_duration(file, args) T = ExtendedTimer(5, 0, False, timerShowOutputFileSize, file_out) T.start() try: audio_command = audio_container[args.container].format( args.bin, info[args.verbose], file, file_out) st, out, err = c.exec(audio_command, get_stdout=False, verbose=args.verbose, user_function=ffmpegProgress, seconds=seconds) exit_code = st if exit_code != 0: print('!!! ERROR: Excuting command [{}] (exit code {})'.format( audio_command, exit_code)) finally: T.cancel() del T
def get_file_tag(file, bins=''): tag = '' ffprobe_video = '{}ffprobe -v error -print_format csv -show_streams -select_streams v -show_entries stream=index,codec_name,width,height,bit_rate -i "{}"' ffprobe_args = ffprobe_video.format(bins, file) st, out, err = c.exec(ffprobe_args, get_stdout=True) if st == 0: for line in out: lv = line.split(',') if lv[0] == 'stream': lv = lv[1:6] index = ToInt(lv[0]) codec = lv[1] width = ToInt(lv[2]) height = ToInt(lv[3]) bitrate = lv[4] # Only the first one is returned tag = '[{}x{}-{}]'.format(width, height, codec) return st, tag return st, tag
def convert_video_file(file, file_out, args): global exit_code, info, video_container, video_resolution, FPS, FFMPEG_PROGRESS, FFMPEG_DURATION, FFMPEG_SIZE options = [] if args.fps != 0.0: options.append(FPS.format(args.fps)) st_v = st_a = st_s = 255 print('# Converting to Video file') show_file_size(file) seconds = show_file_duration(file, args) st_v = get_video_streams(file, options, args) if st_v == 0: st_a = get_audio_streams(file, options, args) if st_a == 0: st_s = get_subs_streams(file, options, args) if st_v == 0 and st_a == 0 and st_s == 0: # ffmpeg progress FFMPEG_PROGRESS = 0.0 FFMPEG_DURATION = '00:00:00.000' FFMPEG_SIZE = 0.0 # Correct stream data # Building FFMPEG command options_string = '' for opt in options: options_string = options_string + opt + ' ' options_string = options_string.strip() T = ExtendedTimer(5, 0, False, timerShowOutputFileSize, file_out) T.start() # Final command try: comm = ffmpeg_comm.format(args.bin, info[args.verbose], file, options_string, file_out) st, out, err = c.exec(comm, verbose=args.verbose, user_function=ffmpegProgress, seconds=seconds) exit_code = st if exit_code != 0: print('!!! ERROR: Excuting command [{}] (exit code {})'.format( comm, exit_code)) finally: T.cancel() del T else: # Error obtaining streams data exit_code = 255
def get_file_info(file, args): global exit_code options = [] st_v = st_a = st_s = 255 show_file_size(file) show_file_duration(file, args) st_v = get_video_streams(file, options, args, info=True) st_a = get_audio_streams(file, options, args, info=True) st_s = get_subs_streams(file, options, args, info=True) if st_v != 0 or st_a != 0 or st_s != 0: # Error obtaining streams data exit_code = 255 comm = ffprobe_info.format(args.bin, file) c.exec(comm, verbose=args.verbose)
def show_file_duration(file, args, verbose=True): comm = ffprobe_dur.format(args.bin, file) st, out, err = c.exec(comm, get_stdout=True, verbose=args.verbose) try: auxi = out[0] auxi = auxi.split(':') seconds = (ToFloat(auxi[0]) * 3600.0) + (ToFloat(auxi[1]) * 60) + (ToFloat(auxi[2])) except: seconds = 0.0 if verbose: print('# Duration: {} ({} seconds)'.format(out, seconds)) return (seconds)
def join_input_files(files, f_out, args): global ffmpeg_join, info, exit_code c.sep() # Create temporary file tmppath = '.conv_to.join.{}'.format(os.getpid()) # Remove temporary file if c.rm_file(tmppath): print('# Temp file:{} removed'.format(f_out)) # Writing temporary file stream tmp = open(tmppath, 'w') for f in files: print('file \'{}\''.format(f), file=tmp) print('# Registering file [{}]:'.format(f)) show_file_size(f) show_file_duration(f, args) c.sep() tmp.close() #exec_command ('cat {}'.format(tmppath), get_stdout=True, verbose=True) # Remove out file if c.rm_file(f_out): print('# Output file:{} removed'.format(f_out)) else: print('# Output file:{} do not exist (will be created)'.format(f_out)) c.sep() # ffmpeg progress #FFMPEG_PROGRESS = 0.0 #FFMPEG_DURATION = '00:00:00.000' #FFMPEG_SIZE = 0.0 #T = ExtendedTimer(5, 0, False, timerShowOutputFileSize, f_out) #T.start() try: # Command to join join_command = ffmpeg_join.format(args.bin, info[args.verbose], tmppath, f_out) st, out, err = c.exec(join_command, verbose=args.verbose) exit_code = st if exit_code != 0: print('!!! ERROR: Excuting command [{}] (exit code {})'.format( join_command, exit_code)) finally: #T.cancel() #del T pass # Remove temporary file if not c.rm_file(tmppath): print('\n!!! ERROR: Removing temporary file:{}'.format(tmppath)) c.sep() # File Joined print('>>> Input files joined to: [{}]'.format(f_out)) get_file_info(f_out, args) c.sep()
def get_subs_streams(file, options, args, info=False): global subtitles, ffprobe_subs, O_copy, OS_stream, not_OS_stream if args.no_subs and not info: # Do not copy audio streams options.append(subtitles['none']) print('# Subtitle[X]: Do not process subtitles streams') st = 0 else: # Get audio streams info ffprobe_args = ffprobe_subs.format(args.bin, file) st, out, err = c.exec(ffprobe_args, get_stdout=True, verbose=args.verbose) if st == 0: subs = False for line in out: ignored = False lss = line.split(',') if lss[0] == 'stream': ls = lss[1:3] try: ls.append(lss[15]) except: ls.append('und') index = ToInt(ls[0].strip()) codec = ls[1].strip() title = ls[2].strip() if codec not in ignored_codecs: if info: # Just show stream info print('# Subtitle[{}]: {} ({})'.format( index, codec, title)) else: if args.container != 'avi': # Process stream data print('# Subtitle[{}]: {} ({}) --> '.format( index, codec, title), end='') # Process Stream stream = OS_stream.format(index) print('{}'.format(subtitles[args.container])) options.append(stream) subs = True else: # Stream is text based. An SRT file has to be extracted print( '# Subtitle[{}]: {} ({}) --> {}: '.format( index, codec, title, subtitles[args.container]), end='') extract_subs_to_SRT(args, file, index, title) else: print( '# Subtitle[{}]: {} ({}) --> Ignored CODEC (only text subtitles supported)' .format(index, codec, title)) # Process Stream stream = not_OS_stream.format(index) options.append(stream) ignored = True if subs: # Codec for subtitles streams (MP4) options.append(OS_codec.format(subtitles[args.container])) else: if not ignored: # No subtitles inside XVID file options.append(subtitles['none']) return st
def get_audio_streams(file, options, args, info=False): global ffprobe_audio, stream_audio_quality, OA_stream, O_copy if args.no_audio and not info: # Do not copy audio streams options.append(stream_audio_quality['none'][1]) print('# Audio[X]: Do not process audio streams') st = 0 else: # Get audio streams info ffprobe_args = ffprobe_audio.format(args.bin, file) st, out, err = c.exec(ffprobe_args, get_stdout=True, verbose=args.verbose) if st == 0: for line in out: lsa = line.split(',') if lsa[0] == 'stream': la = lsa[1:3] try: la.append(lsa[15]) except: la.append('und') index = ToInt(la[0].strip()) codec = la[1].strip() title = la[2].strip() if codec not in ignored_codecs: if info: # Just show file information print('# Audio[{}]: {} ({})'.format( index, codec, title)) else: # Process audio stream print('# Audio[{}]: {} ({}) --> '.format( index, codec, title), end='') # Codec patch if codec == 'ac3': codec = 'aac' # Process Stream if codec != stream_audio_quality[args.container][0] or \ args.fps != 0.0 or args.force: # Reencode streama stream = OA_stream.format( index, index, stream_audio_quality[args.container][1]) print('{}'.format( stream_audio_quality[args.container][0])) else: # Copy stream stream = OA_stream.format(index, index, O_copy) print('Copy audio stream') options.append(stream) else: print('# Audio[{}]: {} ({}) --> Ignored CODEC'.format( index, codec, title)) return st
def get_video_streams(file, options, args, info=False): global ffprobe_video, video_resolution, video_container, stream_video_quality, \ OV_stream, O_copy, rotate180, video_filters ffprobe_args = ffprobe_video.format(args.bin, file) st, out, err = c.exec(ffprobe_args, get_stdout=True, verbose=args.verbose) header = False if st == 0: for line in out: lv = line.split(',') if lv[0] == 'stream': lv = lv[1:6] index = ToInt(lv[0].strip()) codec = lv[1].strip() width = ToInt(lv[2].strip()) height = ToInt(lv[3].strip()) bitrate = lv[4].strip() if codec not in ignored_codecs: if info: # Just show information print('# Video[{}]: {}, {}x{}, BR:{}'.format( index, codec, width, height, bitrate)) else: # Manage Options print('# Video[{}]: {}, {}x{} --> '.format( index, codec, width, height), end='') # Codec patch if codec == 'xvid': codec = 'mpeg4' # Smart resize detection resize = False scale_v = '' if args.resol != 'input' and not header: if width > video_resolution[args.resol][0]: scale_v = video_resolution[args.resol][1] width = video_resolution[args.resol][0] resize = True # libx264 restriction about odd sizes if not resize and not header: if (width % 2 == 1) or (height % 2 == 1): scale_v = 'scale=trunc(iw/2)*2:trunc(ih/2)*2' resize = True # Rotate 180 flip = False flip_v = '' if args.flip and not header: flip_v = rotate180 flip = True # Deal with filter separator if both filters present if resize and flip: filter_sep = ',' else: filter_sep = '' # Final video filters option if resize or flip: stream_filter = video_filters.format( flip_v, filter_sep, scale_v) options.append(stream_filter) # Container headers if not header: options.append(video_container[args.container][1]) header = True # Process Stream if codec != video_container[args.container][0] or \ args.fps != 0.0 or resize or flip or args.force: # Reencode streama vr = args.resol + '-' + args.container stream = OV_stream.format(index, index, stream_video_quality[vr]) print('{}:{}, Resolution:{} (max width={} px)'. format(args.container, video_container[args.container][0], args.resol, width)) else: # Copy stream stream = OV_stream.format(index, index, O_copy) print('Copy video stream') options.append(stream) else: print('# Video[{}]: {}, {}x{}, BR:{} --> Ignored CODEC'. format(index, codec, width, height, bitrate)) return st