slhck / ffmpeg-progress-yield

Run an ffmpeg command with progress
MIT License
56 stars 5 forks source link

HOW TO HIDE UNNECESSARY OUTPUT OF FFMPEG? #10

Closed botbahlul closed 1 year ago

botbahlul commented 1 year ago

Hi, I just tried your module in my project with these code :

    command = ["ffmpeg", "-y", "-i", filename, "-ac", str(channels), "-ar", str(rate), "-loglevel", "error", "-hide_banner", temp.name]
    ff = FfmpegProgress(command)
    widgets = ["Convert to WAV                          : ", Percentage(), ' ', Bar(), ' ', ETA()]
    pbar = ProgressBar(widgets=widgets, maxval=100).start()
    for progress in ff.run_command_with_progress():
        #print(f"{progress}/100")
        pbar.update(progress)
    pbar.finish()

Is there any way to hide unnecessary output of ffmpeg (those output in red box)?

image

slhck commented 1 year ago

You can use -loglevel error to prevent most output.

Uf that does not work: Can you please provide sample code? How are you using this library?

botbahlul commented 1 year ago
    command = ["ffmpeg", "-y", "-i", filename, "-ac", str(channels), "-ar", str(rate), "-loglevel", "error", "-hide_banner", temp.name]
    ff = FfmpegProgress(command)
    widgets = ["Convert to WAV                          : ", Percentage(), ' ', Bar(), ' ', ETA()]
    pbar = ProgressBar(widgets=widgets, maxval=100).start()
    for progress in ff.run_command_with_progress():
        #print(f"{progress}/100")
        pbar.update(progress)
    pbar.finish()
slhck commented 1 year ago

ffmpeg-progress-yield does not print ffmpeg output on its own. I assume that your program must be doing it somehow.

The code you showed does not contain a print statement either — so I don't know where the screenshot you are showing comes from.

botbahlul commented 1 year ago

I'M USING YOUR MODULE AT def extract_audio(filename, channels=1, rate=48000) FUNCTION

COPY AND NAME THIS SCRIPT AS autosrt.py

RUN IT ON A MP4 FILE, FOR EXAMPLE :

python autosrt.py -S en -D id "harry.mp4"
# autosrt.py
from __future__ import absolute_import, print_function, unicode_literals
import argparse
import audioop
import math
import multiprocessing
import os
import subprocess
import sys
import tempfile
import wave
import json
import requests
try:
    from json.decoder import JSONDecodeError
except ImportError:
    JSONDecodeError = ValueError
from progressbar import ProgressBar, Percentage, Bar, ETA
import pysrt
import six
# ADDITIONAL IMPORT FOR GoogleTranslate()
import httpx
from glob import glob
#import warnings
#warnings.filterwarnings("ignore", category=DeprecationWarning)
from ffmpeg_progress_yield import FfmpegProgress

GOOGLE_SPEECH_API_KEY = "AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw"
GOOGLE_SPEECH_API_URL = "http://www.google.com/speech-api/v2/recognize?client=chromium&lang={lang}&key={key}"

arraylist_language_code = []
arraylist_language_code.append("af")
arraylist_language_code.append("sq")
arraylist_language_code.append("am")
arraylist_language_code.append("ar")
arraylist_language_code.append("hy")
arraylist_language_code.append("as")
arraylist_language_code.append("ay")
arraylist_language_code.append("az")
arraylist_language_code.append("bm")
arraylist_language_code.append("eu")
arraylist_language_code.append("be")
arraylist_language_code.append("bn")
arraylist_language_code.append("bho")
arraylist_language_code.append("bs")
arraylist_language_code.append("bg")
arraylist_language_code.append("ca")
arraylist_language_code.append("ceb")
arraylist_language_code.append("ny")
arraylist_language_code.append("zh-CN")
arraylist_language_code.append("zh-TW")
arraylist_language_code.append("co")
arraylist_language_code.append("hr")
arraylist_language_code.append("cs")
arraylist_language_code.append("da")
arraylist_language_code.append("dv")
arraylist_language_code.append("doi")
arraylist_language_code.append("nl")
arraylist_language_code.append("en")
arraylist_language_code.append("eo")
arraylist_language_code.append("et")
arraylist_language_code.append("ee")
arraylist_language_code.append("fil")
arraylist_language_code.append("fi")
arraylist_language_code.append("fr")
arraylist_language_code.append("fy")
arraylist_language_code.append("gl")
arraylist_language_code.append("ka")
arraylist_language_code.append("de")
arraylist_language_code.append("el")
arraylist_language_code.append("gn")
arraylist_language_code.append("gu")
arraylist_language_code.append("ht")
arraylist_language_code.append("ha")
arraylist_language_code.append("haw")
arraylist_language_code.append("he")
arraylist_language_code.append("hi")
arraylist_language_code.append("hmn")
arraylist_language_code.append("hu")
arraylist_language_code.append("is")
arraylist_language_code.append("ig")
arraylist_language_code.append("ilo")
arraylist_language_code.append("id")
arraylist_language_code.append("ga")
arraylist_language_code.append("it")
arraylist_language_code.append("ja")
arraylist_language_code.append("jv")
arraylist_language_code.append("kn")
arraylist_language_code.append("kk")
arraylist_language_code.append("km")
arraylist_language_code.append("rw")
arraylist_language_code.append("gom")
arraylist_language_code.append("ko")
arraylist_language_code.append("kri")
arraylist_language_code.append("kmr")
arraylist_language_code.append("ckb")
arraylist_language_code.append("ky")
arraylist_language_code.append("lo")
arraylist_language_code.append("la")
arraylist_language_code.append("lv")
arraylist_language_code.append("ln")
arraylist_language_code.append("lt")
arraylist_language_code.append("lg")
arraylist_language_code.append("lb")
arraylist_language_code.append("mk")
arraylist_language_code.append("mg")
arraylist_language_code.append("ms")
arraylist_language_code.append("ml")
arraylist_language_code.append("mt")
arraylist_language_code.append("mi")
arraylist_language_code.append("mr")
arraylist_language_code.append("mni-Mtei")
arraylist_language_code.append("lus")
arraylist_language_code.append("mn")
arraylist_language_code.append("my")
arraylist_language_code.append("ne")
arraylist_language_code.append("no")
arraylist_language_code.append("or")
arraylist_language_code.append("om")
arraylist_language_code.append("ps")
arraylist_language_code.append("fa")
arraylist_language_code.append("pl")
arraylist_language_code.append("pt")
arraylist_language_code.append("pa")
arraylist_language_code.append("qu")
arraylist_language_code.append("ro")
arraylist_language_code.append("ru")
arraylist_language_code.append("sm")
arraylist_language_code.append("sa")
arraylist_language_code.append("gd")
arraylist_language_code.append("nso")
arraylist_language_code.append("sr")
arraylist_language_code.append("st")
arraylist_language_code.append("sn")
arraylist_language_code.append("sd")
arraylist_language_code.append("si")
arraylist_language_code.append("sk")
arraylist_language_code.append("sl")
arraylist_language_code.append("so")
arraylist_language_code.append("es")
arraylist_language_code.append("su")
arraylist_language_code.append("sw")
arraylist_language_code.append("sv")
arraylist_language_code.append("tg")
arraylist_language_code.append("ta")
arraylist_language_code.append("tt")
arraylist_language_code.append("te")
arraylist_language_code.append("th")
arraylist_language_code.append("ti")
arraylist_language_code.append("ts")
arraylist_language_code.append("tr")
arraylist_language_code.append("tk")
arraylist_language_code.append("tw")
arraylist_language_code.append("uk")
arraylist_language_code.append("ur")
arraylist_language_code.append("ug")
arraylist_language_code.append("uz")
arraylist_language_code.append("vi")
arraylist_language_code.append("cy")
arraylist_language_code.append("xh")
arraylist_language_code.append("yi")
arraylist_language_code.append("yo")
arraylist_language_code.append("zu")

arraylist_language = []
arraylist_language.append("Afrikaans");
arraylist_language.append("Albanian");
arraylist_language.append("Amharic");
arraylist_language.append("Arabic");
arraylist_language.append("Armenian");
arraylist_language.append("Assamese");
arraylist_language.append("Aymara");
arraylist_language.append("Azerbaijani");
arraylist_language.append("Bambara");
arraylist_language.append("Basque");
arraylist_language.append("Belarusian");
arraylist_language.append("Bengali");
arraylist_language.append("Bhojpuri");
arraylist_language.append("Bosnian");
arraylist_language.append("Bulgarian");
arraylist_language.append("Catalan");
arraylist_language.append("Cebuano");
arraylist_language.append("Chichewa");
arraylist_language.append("Chinese (Simplified)");
arraylist_language.append("Chinese (Traditional)");
arraylist_language.append("Corsican");
arraylist_language.append("Croatian");
arraylist_language.append("Czech");
arraylist_language.append("Danish");
arraylist_language.append("Dhivehi");
arraylist_language.append("Dogri");
arraylist_language.append("Dutch");
arraylist_language.append("English");
arraylist_language.append("Esperanto");
arraylist_language.append("Estonian");
arraylist_language.append("Ewe");
arraylist_language.append("Filipino");
arraylist_language.append("Finnish");
arraylist_language.append("French");
arraylist_language.append("Frisian");
arraylist_language.append("Galician");
arraylist_language.append("Georgian");
arraylist_language.append("German");
arraylist_language.append("Greek");
arraylist_language.append("Guarani");
arraylist_language.append("Gujarati");
arraylist_language.append("Haitian Creole");
arraylist_language.append("Hausa");
arraylist_language.append("Hawaiian");
arraylist_language.append("Hebrew");
arraylist_language.append("Hindi");
arraylist_language.append("Hmong");
arraylist_language.append("Hungarian");
arraylist_language.append("Icelandic");
arraylist_language.append("Igbo");
arraylist_language.append("Ilocano");
arraylist_language.append("Indonesian");
arraylist_language.append("Irish");
arraylist_language.append("Italian");
arraylist_language.append("Japanese");
arraylist_language.append("Javanese");
arraylist_language.append("Kannada");
arraylist_language.append("Kazakh");
arraylist_language.append("Khmer");
arraylist_language.append("Kinyarwanda");
arraylist_language.append("Konkani");
arraylist_language.append("Korean");
arraylist_language.append("Krio");
arraylist_language.append("Kurdish (Kurmanji)");
arraylist_language.append("Kurdish (Sorani)");
arraylist_language.append("Kyrgyz");
arraylist_language.append("Lao");
arraylist_language.append("Latin");
arraylist_language.append("Latvian");
arraylist_language.append("Lingala");
arraylist_language.append("Lithuanian");
arraylist_language.append("Luganda");
arraylist_language.append("Luxembourgish");
arraylist_language.append("Macedonian");
arraylist_language.append("Malagasy");
arraylist_language.append("Malay");
arraylist_language.append("Malayalam");
arraylist_language.append("Maltese");
arraylist_language.append("Maori");
arraylist_language.append("Marathi");
arraylist_language.append("Meiteilon (Manipuri)");
arraylist_language.append("Mizo");
arraylist_language.append("Mongolian");
arraylist_language.append("Myanmar (Burmese)");
arraylist_language.append("Nepali");
arraylist_language.append("Norwegian");
arraylist_language.append("Odiya (Oriya)");
arraylist_language.append("Oromo");
arraylist_language.append("Pashto");
arraylist_language.append("Persian");
arraylist_language.append("Polish");
arraylist_language.append("Portuguese");
arraylist_language.append("Punjabi");
arraylist_language.append("Quechua");
arraylist_language.append("Romanian");
arraylist_language.append("Russian");
arraylist_language.append("Samoan");
arraylist_language.append("Sanskrit");
arraylist_language.append("Scots Gaelic");
arraylist_language.append("Sepedi");
arraylist_language.append("Serbian");
arraylist_language.append("Sesotho");
arraylist_language.append("Shona");
arraylist_language.append("Sindhi");
arraylist_language.append("Sinhala");
arraylist_language.append("Slovak");
arraylist_language.append("Slovenian");
arraylist_language.append("Somali");
arraylist_language.append("Spanish");
arraylist_language.append("Sundanese");
arraylist_language.append("Swahili");
arraylist_language.append("Swedish");
arraylist_language.append("Tajik");
arraylist_language.append("Tamil");
arraylist_language.append("Tatar");
arraylist_language.append("Telugu");
arraylist_language.append("Thai");
arraylist_language.append("Tigrinya");
arraylist_language.append("Tsonga");
arraylist_language.append("Turkish");
arraylist_language.append("Turkmen");
arraylist_language.append("Twi (Akan)");
arraylist_language.append("Ukrainian");
arraylist_language.append("Urdu");
arraylist_language.append("Uyghur");
arraylist_language.append("Uzbek");
arraylist_language.append("Vietnamese");
arraylist_language.append("Welsh");
arraylist_language.append("Xhosa");
arraylist_language.append("Yiddish");
arraylist_language.append("Yoruba");
arraylist_language.append("Zulu");

map_code_of_language = dict(zip(arraylist_language, arraylist_language_code))
map_language_of_code = dict(zip(arraylist_language_code, arraylist_language))

LANGUAGE_CODES = map_language_of_code

def srt_formatter(subtitles, padding_before=0, padding_after=0):
    sub_rip_file = pysrt.SubRipFile()
    for i, ((start, end), text) in enumerate(subtitles, start=1):
        item = pysrt.SubRipItem()
        item.index = i
        item.text = six.text_type(text)
        item.start.seconds = max(0, start - padding_before)
        item.end.seconds = end + padding_after
        sub_rip_file.append(item)
    return '\n'.join(six.text_type(item) for item in sub_rip_file)

def vtt_formatter(subtitles, padding_before=0, padding_after=0):
    text = srt_formatter(subtitles, padding_before, padding_after)
    text = 'WEBVTT\n\n' + text.replace(',', '.')
    return text

def json_formatter(subtitles):
    subtitle_dicts = [
        {
            'start': start,
            'end': end,
            'content': text,
        }
        for ((start, end), text)
        in subtitles
    ]
    return json.dumps(subtitle_dicts)

def raw_formatter(subtitles):
    return ' '.join(text for (_rng, text) in subtitles)

FORMATTERS = {
    'srt': srt_formatter,
    'vtt': vtt_formatter,
    'json': json_formatter,
    'raw': raw_formatter,
}

def percentile(arr, percent):
    arr = sorted(arr)
    k = (len(arr) - 1) * percent
    f = math.floor(k)
    c = math.ceil(k)
    if f == c: return arr[int(k)]
    d0 = arr[int(f)] * (c - k)
    d1 = arr[int(c)] * (k - f)
    return d0 + d1

def is_same_language(lang1, lang2):
    return lang1.split("-")[0] == lang2.split("-")[0]

class FLACConverter(object):
    def __init__(self, source_path, include_before=0.25, include_after=0.25):
        self.source_path = source_path
        self.include_before = include_before
        self.include_after = include_after

    def __call__(self, region):
        try:
            start, end = region
            start = max(0, start - self.include_before)
            end += self.include_after
            temp = tempfile.NamedTemporaryFile(suffix='.flac', delete=False)
            command = ["ffmpeg","-ss", str(start), "-t", str(end - start), "-y", "-i", self.source_path, "-loglevel", "error", temp.name]
            subprocess.check_output(command, stdin=open(os.devnull))
            return temp.read()

        except KeyboardInterrupt:
            return

class SpeechRecognizer(object):
    def __init__(self, language="en", rate=44100, retries=3, api_key=GOOGLE_SPEECH_API_KEY):
        self.language = language
        self.rate = rate
        self.api_key = api_key
        self.retries = retries

    def __call__(self, data):
        try:
            for i in range(self.retries):
                url = GOOGLE_SPEECH_API_URL.format(lang=self.language, key=self.api_key)
                headers = {"Content-Type": "audio/x-flac; rate=%d" % self.rate}

                try:
                    resp = requests.post(url, data=data, headers=headers)
                except requests.exceptions.ConnectionError:
                    continue

                for line in resp.content.decode('utf-8').split("\n"):
                    try:
                        line = json.loads(line)
                        line = line['result'][0]['alternative'][0]['transcript']
                        return line[:1].upper() + line[1:]
                    except:
                        continue

        except KeyboardInterrupt:
            return

def GoogleTranslate(text, src, dst):
    url = 'https://translate.googleapis.com/translate_a/'
    params = 'single?client=gtx&sl='+src+'&tl='+dst+'&dt=t&q='+text;
    with httpx.Client(http2=True) as client:
        client.headers.update({'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)', 'Referer': 'https://translate.google.com',})
        response = client.get(url+params)
        if response.status_code == 200:
            response_json = response.json()[0]
            length = len(response_json)
            translation = ""
            for i in range(length):
                translation = translation + response_json[i][0]
            return translation
        return

class SentenceTranslator(object):
    def __init__(self, src, dest, patience=-1):
        self.src = src
        self.dest = dest
        self.patience = patience

    def __call__(self, sentence):
        translated_sentence = []
        if not sentence:
            return None

        translated_sentence = GoogleTranslate(sentence, src=self.src, dst=self.dest)

        fail_to_translate = translated_sentence[-1] == '\n'
        while fail_to_translate and patience:
            translated_sentence = translator.translate(translated_sentence, src=self.src, dest=self.dest).text
            if translated_sentence[-1] == '\n':
                if patience == -1:
                    continue
                patience -= 1
            else:
                fail_to_translate = False
        return translated_sentence

def which(program):
    def is_exe(file_path):
        return os.path.isfile(file_path) and os.access(file_path, os.X_OK)

    fpath, _ = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            path = path.strip('"')
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file
    return None

def ffmpeg_check():
    if which("ffmpeg"):
        return "ffmpeg"
    if which("ffmpeg.exe"):
        return "ffmpeg.exe"
    return None

def extract_audio(filename, channels=1, rate=48000):
    temp = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
    if not os.path.isfile(filename):
        print("The given file does not exist: {0}".format(filename))
        raise Exception("Invalid filepath: {0}".format(filename))
    if not ffmpeg_check():
        print("ffmpeg: Executable not found on machine.")
        raise Exception("Dependency not found: ffmpeg")
    command = ["ffmpeg", "-y", "-i", filename, "-ac", str(channels), "-ar", str(rate), "-loglevel", "error", "-hide_banner", temp.name]

    # --------------------------------- YOUR MODULE THAT I'M USING ----------------------------------
    #ff = FfmpegProgress(command)
    #widgets = ["Convert to WAV                          : ", Percentage(), ' ', Bar(), ' ', ETA()]
    #pbar = ProgressBar(widgets=widgets, maxval=100).start()
    #for progress in ff.run_command_with_progress():
        #print(f"{progress}/100")
        #pbar.update(progress)
    #pbar.finish()
    # ----------------------------------------------------------------------------------------------

    subprocess.check_output(command, stdin=open(os.devnull))
    return temp.name, rate

def executeShellCommand(cmd):
    p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
    out, err = p.communicate()
    return out.rstrip(), err.rstrip(), p.returncode

def getFFmpegFileDurationInSeconds(filename):
    cmd = "ffmpeg -i "+ filename +" 2>&1 | grep 'Duration' | cut -d ' ' -f 4 | sed s/,//"
    time = executeShellCommand(cmd)[0]
    h = int(time[0:2])
    m = int(time[3:5])
    s = int(time[6:8])
    ms = int(time[9:11])
    ts = (h * 60 * 60) + (m * 60) + s + (ms/60)
    return ts

def estimateFFmpegMp4toMp3NewFileSizeInBytes(duration, kbps):
    return ((kbps * duration) / 8)

def find_speech_regions(filename, frame_width=4096, min_region_size=0.5, max_region_size=6):
    reader = wave.open(filename)
    sample_width = reader.getsampwidth()
    rate = reader.getframerate()
    n_channels = reader.getnchannels()

    total_duration = reader.getnframes() / rate
    chunk_duration = float(frame_width) / rate

    n_chunks = int(total_duration / chunk_duration)
    energies = []

    for i in range(n_chunks):
        chunk = reader.readframes(frame_width)
        energies.append(audioop.rms(chunk, sample_width * n_channels))

    threshold = percentile(energies, 0.2)
    elapsed_time = 0
    regions = []
    region_start = None

    for energy in energies:
        is_silence = energy <= threshold
        max_exceeded = region_start and elapsed_time - region_start >= max_region_size
        if (max_exceeded or is_silence) and region_start:
            if elapsed_time - region_start >= min_region_size:
                regions.append((region_start, elapsed_time))
                region_start = None
        elif (not region_start) and (not is_silence):
            region_start = elapsed_time
        elapsed_time += chunk_duration
    return regions

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('source_path', help="Path to the video or audio files to generate subtitle (use wildcard for multiple files)", nargs='*')
    parser.add_argument('-C', '--concurrency', help="Number of concurrent API requests to make", type=int, default=10)
    parser.add_argument('-o', '--output', help="Output path for subtitles (by default, subtitles are saved in the same directory and name as the source path)")
    parser.add_argument('-F', '--format', help="Destination subtitle format", default="srt")
    parser.add_argument('-S', '--src-language', help="Language spoken in source file", default="en")
    parser.add_argument('-D', '--dst-language', help="Desired language for the subtitles")
    parser.add_argument('-v', '--version', action='version', version='1.1.0')
    parser.add_argument('-lf', '--list-formats', help="List all available subtitle formats", action='store_true')
    parser.add_argument('-ll', '--list-languages', help="List all available source/destination languages", action='store_true')

    args = parser.parse_args()

    if args.list_formats:
        print("List of formats:")
        for subtitle_format in FORMATTERS.keys():
            print("{format}".format(format=subtitle_format))
        return 0

    if args.list_languages:
        print("List of all languages:")
        for code, language in sorted(LANGUAGE_CODES.items()):
            print("{code}\t{language}".format(code=code, language=language))
        return 0

    if args.format not in FORMATTERS.keys():
        print("Subtitle format not supported. Run with --list-formats to see all supported formats.")
        return 1

    if args.src_language not in LANGUAGE_CODES.keys():
        print("Source language not supported. Run with --list-languages to see all supported languages.")
        return 1

    if args.dst_language:
        if not args.dst_language in LANGUAGE_CODES.keys():
            print("Destination language not supported. Run with --list-languages to see all supported languages.")
            return 1
        if not is_same_language(args.src_language, args.dst_language):
            do_translate = True
        else:
            do_translate = False

    if not args.dst_language:
        do_translate = False

    if not args.source_path:
        parser.print_help(sys.stderr)
        return 1

    file_names = []
    for arg in args.source_path:
        file_names += glob(arg)

    for file in file_names:
        print("Processing {} :".format(file))
        audio_filename, audio_rate = extract_audio(file)
        regions = find_speech_regions(audio_filename)
        pool = multiprocessing.Pool(args.concurrency)
        converter = FLACConverter(source_path=audio_filename)
        recognizer = SpeechRecognizer(language=args.src_language, rate=audio_rate, api_key=GOOGLE_SPEECH_API_KEY)

        transcripts = []
        if regions:
            try:
                widgets = ["Converting speech regions to FLAC files : ", Percentage(), ' ', Bar(), ' ', ETA()]
                pbar = ProgressBar(widgets=widgets, maxval=len(regions)).start()
                extracted_regions = []
                for i, extracted_region in enumerate(pool.imap(converter, regions)):
                    extracted_regions.append(extracted_region)
                    pbar.update(i)
                pbar.finish()

                widgets = ["Performing speech recognition           : ", Percentage(), ' ', Bar(), ' ', ETA()]
                pbar = ProgressBar(widgets=widgets, maxval=len(regions)).start()

                for i, transcript in enumerate(pool.imap(recognizer, extracted_regions)):
                    transcripts.append(transcript)
                    pbar.update(i)
                pbar.finish()

            except KeyboardInterrupt:
                pbar.finish()
                pool.terminate()
                pool.close()
                pool.join()
                print("Cancelling transcription")
                return 1

        timed_subtitles = [(r, t) for r, t in zip(regions, transcripts) if t]
        formatter = FORMATTERS.get(args.format)
        formatted_subtitles = formatter(timed_subtitles)

        subtitle_file = args.output

        if not subtitle_file:
            base, ext = os.path.splitext(file)
            subtitle_file = "{base}.{format}".format(base=base, format=args.format)

        with open(subtitle_file, 'wb') as f:
            f.write(formatted_subtitles.encode("utf-8"))

        with open(subtitle_file, 'a') as f:
            f.write("\n")

        if do_translate:
            translated_subtitle_file = subtitle_file[ :-4] + '.translated.' + args.format

            created_regions = []
            created_subtitles = []
            for entry in timed_subtitles:
                created_regions.append(entry[0])
                created_subtitles.append(entry[1])

            prompt = "Translating from %5s to %5s         : " %(args.src_language, args.dst_language)
            widgets = [prompt, Percentage(), ' ', Bar(), ' ', ETA()]
            pbar = ProgressBar(widgets=widgets, maxval=len(timed_subtitles)).start()
            transcript_translator = SentenceTranslator(src=args.src_language, dest=args.dst_language)
            translated_subtitles = []
            for i, translated_subtitle in enumerate(pool.imap(transcript_translator, created_subtitles)):
                translated_subtitles.append(translated_subtitle)
                pbar.update(i)
            pbar.finish()

            timed_translated_subtitles = [(r, t) for r, t in zip(created_regions, translated_subtitles) if t]
            formatter = FORMATTERS.get(args.format)
            formatted_translated_subtitles = formatter(timed_translated_subtitles)

            with open(translated_subtitle_file, 'wb') as tf:
                tf.write(formatted_translated_subtitles.encode("utf-8"))

            with open(translated_subtitle_file, 'a') as tf:
                tf.write("\n")

        os.remove(audio_filename)

        print('Done.')
        if do_translate:
            print("Original subtitles file created at      : {}".format(subtitle_file))
            print('Translated subtitles file created at    : {}' .format(translated_subtitle_file))
        else:
            print("Subtitles file created at      : {}".format(subtitle_file))

        pool.close()
        pool.join()

if __name__ == '__main__':
    multiprocessing.freeze_support()
    sys.exit(main())
botbahlul commented 1 year ago

well...? can you give me some clues?

If I commented out your module to these :

def extract_audio(filename, channels=1, rate=48000):
    temp = tempfile.NamedTemporaryFile(suffix='.wav', delete=False)
    if not os.path.isfile(filename):
        print("The given file does not exist: {0}".format(filename))
        raise Exception("Invalid filepath: {0}".format(filename))
    if not ffmpeg_check():
        print("ffmpeg: Executable not found on machine.")
        raise Exception("Dependency not found: ffmpeg")
    command = ["ffmpeg", "-y", "-i", filename, "-ac", str(channels), "-ar", str(rate), "-loglevel", "error", "-hide_banner", temp.name]

    # --------------------------------- YOUR MODULE THAT I'M USING ----------------------------------
    #ff = FfmpegProgress(command)
    #widgets = ["Convert to WAV                          : ", Percentage(), ' ', Bar(), ' ', ETA()]
    #pbar = ProgressBar(widgets=widgets, maxval=100).start()
    #for progress in ff.run_command_with_progress():
        #print(f"{progress}/100")
        #pbar.update(progress)
    #pbar.finish()
    # ----------------------------------------------------------------------------------------------

    subprocess.check_output(command, stdin=open(os.devnull))
    return temp.name, rate

the output won't show any ffmpeg output image

slhck commented 1 year ago

When I run a simplified example:

def extract_audio(filename, channels=1, rate=48000):
    command = [
        "ffmpeg",
        "-y",
        "-i",
        filename,
        "-ac",
        str(channels),
        "-ar",
        str(rate),
        "-f",
        "null",
        "/dev/null",
    ]

    ff = FfmpegProgress(command)
    for progress in ff.run_command_with_progress():
        print(f"{progress}/100")

Nothing is printed. Does this also work for you?

When you add -loglevel error to the command, it prints the input information. This is a bug that I just fixed.

That said, you should not get any output whatsoever if you do not include -loglevel error. So please just remove this and run the function I posted above.

Note: You've posted your secret Google API key. Please revoke it.

botbahlul commented 1 year ago

I think I've found the culprit. It's turned out that the problem is on ffprobe command arguments in your module

Adding these arguments solved my problem

                 "-loglevel",
                "-1",
def _probe_duration(cmd: List[str]) -> Optional[int]:

    def _get_file_name(cmd: List[str]) -> Optional[str]:
        try:
            idx = cmd.index("-i")
            return cmd[idx + 1]
        except ValueError:
            return None

    file_name = _get_file_name(cmd)
    if file_name is None:
        return None

    try:
        output = subprocess.check_output(
            [
                "ffprobe",
                "-loglevel",
                "-1",
                "-hide_banner",
                "-show_entries",
                "format=duration",
                "-of",
                "default=noprint_wrappers=1:nokey=1",
                file_name,
            ],
            universal_newlines=True,
        )
        return int(float(output.strip()) * 1000)
    except Exception:
        # TODO: add logging
        return None

Thanks for your good module :)

slhck commented 1 year ago

Have you tried the latest version that I pushed? It should allow you to run the command without the workaround you just mentioned. That said there isn't any need to set the log level to begin with, I think.

botbahlul commented 1 year ago

I've installed version 0.7.1 Is that not the latest?

slhck commented 1 year ago

I released 0.7.2 with a fix for loglevel error.

botbahlul commented 1 year ago

OK, let me try it

botbahlul commented 1 year ago

I see.. you just added on ffprobe

                "-loglevel",
                "error",

I think it's just the same as that I've added "loglevel", "-1"

It's working fine now, thanks.

slhck commented 1 year ago

Glad you got it solved!