#!/bin/env python import re import sys import subprocess from subprocess import PIPE, STDOUT from collections import deque from multiprocessing.managers import BaseManager from tqdm import tqdm from utils.utils import terminate def Manager(): m = BaseManager() m.start() return m class Counter(): def __init__(self, total, initial): self.first_update = True self.initial = initial self.left = total - initial self.tqdm_bar = tqdm(total=self.left, initial=0, dynamic_ncols=True, unit="fr", leave=True, smoothing=0.2) def update(self, value): if self.first_update: self.tqdm_bar.reset(self.left) self.first_update = False self.tqdm_bar.update(value) BaseManager.register('Counter', Counter) def tqdm_bar(i, encoder, counter, frame_probe_source, passes): try: encoder_history = deque(maxlen=20) f, e = i.split('|') f = " ffmpeg -y -hide_banner -loglevel error " + f f, e = f.split(), e.split() frame = 0 ffmpeg_pipe = subprocess.Popen(f, stdout=PIPE, stderr=STDOUT) pipe = subprocess.Popen(e, stdin=ffmpeg_pipe.stdout, stdout=PIPE, stderr=STDOUT, universal_newlines=True) while True: line = pipe.stdout.readline().strip() if line: encoder_history.append(line) if len(line) == 0 and pipe.poll() is not None: break if len(line) == 0: continue if encoder in ('aom', 'vpx', 'rav1e'): match = None if encoder in ('aom', 'vpx'): if 'fatal' in line.lower(): print('\n\nERROR IN ENCODING PROCESS\n\n', line) terminate() if 'Pass 2/2' in line or 'Pass 1/1' in line: match = re.search(r"frame.*?\/([^ ]+?) ", line) elif encoder == 'rav1e': if 'error' in line.lower(): print('\n\nERROR IN ENCODING PROCESS\n\n', line) terminate() match = re.search(r"encoded.*? ([^ ]+?) ", line) if match: new = int(match.group(1)) if new > frame: counter.update(new - frame) frame = new if encoder == 'svt_av1': counter.update(frame_probe_source // passes) if pipe.returncode != 0 and pipe.returncode != -2: # -2 is Ctrl+C for aom print(f"\nEncoder encountered an error: {pipe.returncode}") print('\n'.join(encoder_history)) except Exception as e: _, _, exc_tb = sys.exc_info() print(f'Error at encode {e}\nAt line {exc_tb.tb_lineno}')