def recode_to_mp4(v, v_mp4): cmds = ['ffmpeg', '-y', '-i', v, '-vcodec', 'copy', v_mp4] try: system_cmd_result('.', cmds, display_stdout=False, display_stderr=False, raise_on_error=True, capture_keyboard_interrupt=False) except CmdException: raise
def ffmpeg_get_metadata(video): cmds = ['ffmpeg', '-i', video, '-f', 'ffmetadata', '-'] try: res = system_cmd_result('.', cmds, display_stdout=False, display_stderr=False, raise_on_error=True, capture_keyboard_interrupt=False) except CmdException as e: # TODO: be more descriptive logger.debug(e) return {} lines = res.stdout.split('\n') assert lines[0] == ';FFMETADATA1' keys = {} for line in lines[1:]: line = line.strip() if not line: continue k, v = line.split('=') if v[0] == "'": v = v[1:-1] k = k.lower() keys[k] = v return dict(keys)
def ffmpeg_get_metadata(video): cmds = ["ffmpeg", "-i", video, "-f", "ffmetadata", "-"] try: res = system_cmd_result( ".", cmds, display_stdout=False, display_stderr=False, raise_on_error=True, capture_keyboard_interrupt=False ) except CmdException as e: # TODO: be more descriptive logger.debug(e) return {} lines = res.stdout.split("\n") assert lines[0] == ";FFMETADATA1" keys = {} for line in lines[1:]: line = line.strip() if not line: continue k, v = line.split("=") if v[0] == "'": v = v[1:-1] k = k.lower() keys[k] = v return dict(keys)
def mplayer_identify(filename): """ Returns a dictionary, with fields: width, height fps length extra_mencoder_info """ keys = ["ID_VIDEO_WIDTH", "ID_VIDEO_HEIGHT", "ID_VIDEO_FPS", "ID_LENGTH"] id_width, id_height, id_fps, id_length = keys args = ('mplayer -identify -vo null -ao null -frames 0'.split() + [filename]) try: res = system_cmd_result('.', args, display_stdout=False, display_stderr=False, raise_on_error=True, capture_keyboard_interrupt=False) except CmdException: raise output = res.stdout info = {} for line in output.split('\n'): if line.startswith('ID_'): key, value = line.split('=', 1) try: # interpret numbers if possible value = eval(value) except: pass info[key] = value for k in keys: if not k in info: msg = ('Could not find key %r in properties %s.' % (k, sorted(info.keys()))) raise Exception(msg) if id_length == 0: msg = 'I could not find find the length of this movie.' msg += (' I ran:\n\t%s\n and this is the output:\n' % (" ".join(args), output)) raise Exception(msg) res = {} res['width'] = info[id_width] res['height'] = info[id_height] res['fps'] = info[id_fps] res['length'] = info[id_length] res['extra_mencoder_info'] = info return res
def do_quickstart(source, target): # TODO: check file exists names = ['qtfaststart', 'qt-faststart'] errors = [] for name in names: cmd = [name, source, target] try: system_cmd_result('.', cmd, display_stdout=False, display_stderr=False, raise_on_error=True, capture_keyboard_interrupt=False) break except CmdException as e: errors.append(e) else: msg = ('Could not call either of %s. ' 'The file will not be ready for streaming.\n%s' % (names, errors)) logger.error(msg) os.rename(source, target)
def do_quickstart(source, target): # TODO: check file exists names = ['qtfaststart', 'qt-faststart'] errors = [] for name in names: cmd = [name, source, target] try: system_cmd_result('.', cmd, display_stdout=True, display_stderr=True, raise_on_error=True, capture_keyboard_interrupt=False) break except CmdException as e: errors.append(e) else: msg = ('Could not call either of %s. ' 'The file will not be ready for streaming.\n%s' % (names, errors)) logger.error(msg) os.rename(source, target)
def mplayer_identify(filename, intolerant=True): """ Returns a dictionary, with fields: width, height fps * length * extra_mencoder_info Mplayer might fail to identify FPS and length. If intolerant=True, an error is raised, otherwise they are set to None. """ # need at least 1 frame otherwise sometimes the video aspect is not known args = ('mplayer -identify -vo null -ao null -frames 1'.split() + [filename]) try: try: res = system_cmd_result('.', args, display_stdout=False, display_stderr=False, raise_on_error=True, capture_keyboard_interrupt=False) except CmdException: raise except Exception as e: raise_wrapped(Exception, e, "Could not identify movie", filename=filename) try: output = res.stdout return parse_mplayer_info_output(output,intolerant=intolerant) except Exception as e: raise_wrapped(Exception, e, "Could not identify movie", cmd=" ".join(args), filename=filename, output=output)
def pg_video_convert(filename, out, quiet=True, container=None, vcodec=None, vcodec_params={}, timestamp=None, metadata={}): """ Converts a video file (e.g. an AVI) to another format. It makes sure to write information to preserve timestamp and the given metadata. One can then be guaranteed to access this data using the pg_info_video() function. """ logger.info('pg_video_convert:\n<- %s\n-> %s' % (filename, out)) if container is None: container = guess_container(out) assert container in CONTAINERS if vcodec is None: vcodec, vcodec_params = guess_vcodec(container) logger.info('container: %s' % container) logger.info('vcodec: %s' % vcodec) logger.info('vcodec_params: %s' % vcodec_params) no_audio = True cmds = ['ffmpeg'] # For using aac out # cmds += ['-strict', '-2'] cmds += ['-y'] cmds += ['-i', filename] if no_audio: cmds += ['-an'] cmds += VCODECS[vcodec](**vcodec_params) info = pg_video_info(filename) info['metadata'].update(metadata) if timestamp is None: timestamp = info['timestamp'] cmds += get_ffmpeg_metadata_args(metadata, timestamp) # cmds += ['-f', container] if container == CONTAINER_MP4: out1 = out + '.firstpass.mp4' cmds += [out1] else: out1 = out cmds += [out1] try: system_cmd_result('.', cmds, display_stdout=not quiet, display_stderr=not quiet, raise_on_error=True, capture_keyboard_interrupt=False) except CmdException: if os.path.exists(out1): os.unlink(out1) raise assert os.path.exists(out1) if container == CONTAINER_MP4: # do_quickstart(out1, out) warnings.warn("Not sure why quickstart does not work.") os.rename(out1, out) else: assert out1 == out if not supports_full_metadata(container): write_extra_metadata_for(out, metadata)
def pg_video_convert(filename, out, quiet=True, container=None, vcodec=None, vcodec_params={}, timestamp=None, metadata={}): """ Converts a video file (e.g. an AVI) to another format. container: one of "mkv", "mp4", "mov" vcodec : vcodec params with defaults 'prores': profile=3, qv=None 'x264': crf=18, preset='medium' It makes sure to write information to preserve timestamp and the given metadata. One can then be guaranteed to access this data using the pg_info_video() function. """ logger.info('pg_video_convert:\n<- %s\n-> %s' % (filename, out)) if container is None: container = guess_container(out) assert container in CONTAINERS if vcodec is None: vcodec, vcodec_params = guess_vcodec(container) logger.info('container: %s' % container) logger.info('vcodec: %s' % vcodec) logger.info('vcodec_params: %s' % vcodec_params) no_audio = True cmds = ['ffmpeg'] # For using aac out # cmds += ['-strict', '-2'] cmds += ['-y'] cmds += ['-i', filename] if no_audio: cmds += ['-an'] cmds += VCODECS[vcodec](**vcodec_params) info = pg_video_info(filename, intolerant=False) info['metadata'].update(metadata) if timestamp is None: timestamp = info['timestamp'] else: timestamp = float(timestamp) cmds += get_ffmpeg_metadata_args(metadata, timestamp) # cmds += ['-f', container] if container == CONTAINER_MP4: out1 = out + '.firstpass.mp4' cmds += [out1] else: out1 = out cmds += [out1] try: system_cmd_result('.', cmds, display_stdout=not quiet, display_stderr=not quiet, raise_on_error=True, capture_keyboard_interrupt=False) except CmdException: if os.path.exists(out1): os.unlink(out1) raise assert os.path.exists(out1) if container == CONTAINER_MP4: do_quickstart(out1, out) os.remove(out1) # warnings.warn("Not sure why quickstart does not work.") # os.rename(out1, out) else: assert out1 == out if not os.path.exists(out): logger.error('Something is wrong, path does not exist.\nPath: %s' % out) if not supports_full_metadata(container): write_extra_metadata_for(out, metadata)