def ffprobe(input_file, verbose=False): """Runs ffprobe on file and returns python dict with result""" if isinstance(input_file, FileObject): exists = input_file.exists path = input_file.path elif type(input_file) in string_types: exists = os.path.exists(input_file) path = input_file else: raise TypeError("input_path must be of string or FileObject type") if not exists: logging.error("ffprobe: file does not exist ({})".format(input_file)) return False cmd = [ "ffprobe", "-show_format", "-show_streams", "-print_format", "json", path ] FNULL = open(os.devnull, "w") if verbose: logging.debug("Executing {}".format(" ".join(cmd))) proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) res = decode_if_py3(proc.stdout.read()) proc.wait() if proc.returncode: if verbose: logging.error("Unable to read media file {}\n\n{}\n\n".format(input_file, indent(proc.stderr.read()))) else: logging.warning("Unable to read media file {}".format(input_file)) return False return json.loads(res)
def wait(self, progress_handler=None): interrupted = False try: while True: if not self.process(progress_handler=progress_handler): break except KeyboardInterrupt: self.stop() interrupted = True self.proc.wait() self.error_log += decode_if_py3(self.stderr.read()) if interrupted: raise KeyboardInterrupt
def process(self, progress_handler=None): ch = self.proc.stderr.read(1) if not ch: return False if ch in ["\n", "\r", b"\n", b"\r"]: if progress_handler: position_match = re_position.search(decode_if_py3(self.buff)) if position_match: position = time2sec(position_match) progress_handler(position) else: try: self.error_log += decode_if_py3(self.buff) + "\n" except: pass if FFMPEG_DEBUG: print (self.buff.rstrip()) if PYTHON_VERSION < 3: self.buff = "" else: self.buff = b"" else: self.buff += ch return True
def process(self, progress_handler=None): ch = decode_if_py3(self.proc.stderr.read(1)) if not ch: return False if ch in ["\n", "\r"]: if progress_handler: position_match = re_position.search(self.buff) if position_match: position = time2sec(position_match) progress_handler(position) else: self.error_log += self.buff + "\n" if FFMPEG_DEBUG: print(self.buff.rstrip()) self.buff = "" else: self.buff += ch return True
def work(self, progress_handler=None): self.reset_stderr() result = {} tags = [ ("mean_volume:", "gain/mean"), ("max_volume:", "gain/peak"), ("I:", "r128/i"), ("Threshold:", "r128/t"), ("LRA:", "r128/lra"), ("Threshold:", "r128/lra/t"), ("LRA low:", "r128/lra/l"), ("LRA high:", "r128/lra/r"), ] logging.debug("Executing", " ".join(self.cmd)) self.proc = subprocess.Popen(self.cmd, stderr=subprocess.PIPE) silences = [] buff = "" exp_tag = tags.pop(0) last_idet = "" while True: ch = self.proc.stderr.read(1) if not ch: break ch = decode_if_py3(ch) if ch in ["\n", "\r"]: line = buff.strip() if line.startswith("[Parsed_ebur128"): pass elif line.startswith("frame="): m = re.match(r".*frame=\s*(\d+)\s*fps.*", line) if m and progress_handler: progress_handler(int(m.group(1))) elif line.find("silence_end") > -1: m = re.match(r".*silence_end:\s*(\d+\.?\d*).*silence_duration:\s*(\d+\.?\d*).*", line) if m: e = float(m.group(1)) s = max(0, e - float(m.group(2))) silences.append([s, e]) elif line.find("Repeated Fields") > -1: last_idet = line elif line.find(exp_tag[0]) > -1: value = float(line.split()[-2]) result[exp_tag[1]] = value try: exp_tag = tags.pop(0) except IndexError: break else: self.error_log += buff + "\n" if FFMPEG_DEBUG: print(buff.rstrip()) buff = "" else: buff += ch if silences: result["silence"] = silences if last_idet: exp = r".*Repeated Fields: Neither:\s*(\d+)\s*Top:\s*(\d+)\s*Bottom:\s*(\d+).*" m = re.match(exp, last_idet) if m: n = int(m.group(1)) t = int(m.group(2)) b = int(m.group(3)) tot = n + t + b if n / float(tot) < .9: result["is_interlaced"] = True return result
def work(self, progress_handler=None): self.reset_stderr() result = {} tags = [ ("mean_volume:", "gain/mean"), ("max_volume:", "gain/peak"), ("I:", "r128/i"), ("Threshold:", "r128/t"), ("LRA:", "r128/lra"), ("Threshold:", "r128/lra/t"), ("LRA low:", "r128/lra/l"), ("LRA high:", "r128/lra/r"), ] logging.debug("Executing", " ".join(self.cmd)) self.proc = subprocess.Popen(self.cmd, stderr=subprocess.PIPE) silences = [] if PYTHON_VERSION < 3: buff = "" else: buff = b"" exp_tag = tags.pop(0) last_idet = "" while True: ch = self.proc.stderr.read(1) if not ch: break if ch in ["\n", "\r", b"\r", b"\n"]: line = decode_if_py3(buff).strip() if line.startswith("[Parsed_ebur128"): pass elif line.startswith("frame="): m = re.match(r".*frame=\s*(\d+)\s*fps.*", line) if m and progress_handler: progress_handler(int(m.group(1))) elif line.find("silence_end") > -1: m = re.match(r".*silence_end:\s*(\d+\.?\d*).*silence_duration:\s*(\d+\.?\d*).*", line) if m: e = float(m.group(1)) s = max(0, e - float(m.group(2))) silences.append([s, e]) elif line.find("Repeated Fields") > -1: last_idet = line elif line.find(exp_tag[0]) > -1: value = float(line.split()[-2]) result[exp_tag[1]] = value try: exp_tag = tags.pop(0) except IndexError: break else: self.error_log += line + "\n" if self.debug: print(line.rstrip()) if PYTHON_VERSION < 3: buff = "" else: buff = b"" else: buff += ch if silences: result["silence"] = silences if last_idet: exp = r".*Repeated Fields: Neither:\s*(\d+)\s*Top:\s*(\d+)\s*Bottom:\s*(\d+).*" m = re.match(exp, last_idet) if m: n = int(m.group(1)) t = int(m.group(2)) b = int(m.group(3)) tot = n + t + b if n / float(tot) < .9: result["is_interlaced"] = True return result