Beispiel #1
0
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)
Beispiel #2
0
 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
Beispiel #3
0
 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
Beispiel #4
0
 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
Beispiel #5
0
 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
Beispiel #6
0
 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
Beispiel #7
0
    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
Beispiel #8
0
    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