From 4f68b276f8a65a14a0510c03b8f33c0e3e18e3a1 Mon Sep 17 00:00:00 2001 From: anthony lloyd Date: Sat, 9 Jul 2022 16:56:38 +1000 Subject: [PATCH] ffmpeg version 2 may require ffmpeg being located in main folder removed additional ffmpeg dependency, now uses OS to call ffmpeg created a loop to write list of files for concatenating ffmpeg runs based off that text file, removing many lines of redundant code fixed incorrect spelling of default max length added comment sorting option into config, not implemented into config generator, choose hot or top added silence to end of audio clips, uses user defined varialbe in config, not implemented into config generator added filter to not do threads with 0 comments changed max length tts of tiktok, reduced to 270 as 300 was causing errors, not completing the mp3 --- TTS/TikTok.py | 2 +- TTS/engine_wrapper.py | 179 ++++-------------------------------------- reddit/subreddit.py | 10 ++- requirements.txt | 1 - utils/subreddit.py | 3 + 5 files changed, 27 insertions(+), 168 deletions(-) diff --git a/TTS/TikTok.py b/TTS/TikTok.py index 743118c..8b2e487 100644 --- a/TTS/TikTok.py +++ b/TTS/TikTok.py @@ -65,7 +65,7 @@ class TikTok: # TikTok Text-to-Speech Wrapper self.URI_BASE = ( "https://api16-normal-useast5.us.tiktokv.com/media/api/text/speech/invoke/?text_speaker=" ) - self.max_chars = 300 + self.max_chars = 270 self.voices = {"human": human, "nonhuman": nonhuman, "noneng": noneng} def run(self, text, filepath, random_voice: bool = False): diff --git a/TTS/engine_wrapper.py b/TTS/engine_wrapper.py index 9f52ec0..936f9c4 100644 --- a/TTS/engine_wrapper.py +++ b/TTS/engine_wrapper.py @@ -2,21 +2,15 @@ from pathlib import Path from typing import Tuple import re -<<<<<<< Updated upstream # import sox # from mutagen import MutagenError # from mutagen.mp3 import MP3, HeaderNotFoundError -======= import os -from os import getenv import numpy as np -import ffmpeg from moviepy.audio.AudioClip import AudioClip from moviepy.audio.fx.volumex import volumex -from mutagen.mp3 import MP3 ->>>>>>> Stashed changes import translators as ts from rich.progress import track from moviepy.editor import AudioFileClip, CompositeAudioClip, concatenate_audioclips @@ -24,7 +18,7 @@ from utils.console import print_step, print_substep from utils.voice import sanitize_text from utils import settings -DEFUALT_MAX_LENGTH: int = 50 # video length variable +DEFAULT_MAX_LENGTH: int = 50 # video length variable class TTSEngine: @@ -46,7 +40,7 @@ class TTSEngine: tts_module, reddit_object: dict, path: str = "assets/temp/mp3", - max_length: int = DEFUALT_MAX_LENGTH, + max_length: int = DEFAULT_MAX_LENGTH, ): self.tts_module = tts_module() self.reddit_object = reddit_object @@ -87,177 +81,34 @@ class TTSEngine: return self.length, idx def split_post(self, text: str, idx: int): - split_files = [] split_text = [ x.group().strip() for x in re.finditer(rf" *((.{{0,{self.tts_module.max_chars}}})(\.|.$))", text) ] + silence_duration = settings.config["settings"]["tts"]["silence_duration"] - silence_long = AudioClip(make_frame=lambda t: np.sin(440 * 2 * np.pi * t), duration=int(getenv("COMMENT_GAP")), fps=44100) + silence_long = AudioClip(make_frame=lambda t: np.sin(440 * 2 * np.pi * t), duration=silence_duration, fps=44100) silence_long_new = volumex(silence_long, 0) silence_long_new.write_audiofile(f"{self.path}/long_silence.mp3", fps=44100, verbose=False, logger=None) - bruz = [] idy = None for idy, text_cut in enumerate(split_text): - # print(f"{idx}-{idy}: {text_cut}\n") + # print(f"{idx}-{idy}: {text_cut}\n") self.call_tts(f"{idx}-{idy}.part", text_cut) - split_files.append(AudioFileClip(f"{self.path}/{idx}-{idy}.part.mp3")) -<<<<<<< Updated upstream - CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( - f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None - ) - for i in split_files: - name = i.filename - i.close() - Path(name).unlink() + with open(f"{self.path}/list.txt", 'w') as f: + for newy in range(0, len(split_text)): + f.write("file " + f"'{idx}-{newy}.part.mp3'"+"\n") + f.write("file " + f"'long_silence.mp3'"+"\n") - # for i in range(0, idy + 1): - # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") + os.system("ffmpeg -f concat -y -hide_banner -loglevel panic -safe 0 " + + "-i " + f"{self.path}/list.txt " + + "-c copy " + f"{self.path}/{idx}.mp3") - # Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() -======= - bruz.append(ffmpeg.input(f"{self.path}/{idx}-{idy}.part.mp3")) - if idy == len(split_text)-1: - split_files.append(AudioFileClip(f"{self.path}/long_silence.mp3")) - # print("long silence added") - bruz.append(ffmpeg.input(f"{self.path}/long_silence.mp3")) - # with open(f"{self.path}/list.txt", 'w') as f: - # for newy in range(0, len(split_text)): - # f.write(f"{self.path}/{idx}-{newy}.part.mp3"+"\n") - # f.write(f"{self.path}/long_silence.mp3") - - if len(bruz) == 1: - stupid0 = bruz[0] - if len(bruz) == 2: - stupid0 = bruz[0] - stupid1 = bruz[1] - if len(bruz) == 3: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - if len(bruz) == 4: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - stupid3 = bruz[3] - if len(bruz) == 5: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - stupid3 = bruz[3] - stupid4 = bruz[4] - if len(bruz) == 5: - stupid0 = bruz[0] - stupid1 = bruz[1] - stupid2 = bruz[2] - stupid3 = bruz[3] - stupid4 = bruz[4] - stupid5 = bruz[5] - - if len(bruz) == 1: - try: - ffmpeg\ - .concat( - stupid0, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 2: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 3: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 4: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - stupid3, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 5: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - stupid3, - stupid4, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - elif len(bruz) == 6: - try: - ffmpeg\ - .concat( - stupid0, - stupid1, - stupid2, - stupid3, - stupid4, - stupid5, - v=0, a=1 - )\ - .output(f"{self.path}/{idx}.m4a")\ - .run(capture_stdout=True, capture_stderr=True) - except ffmpeg.Error as e: - print('stdout:', e.stdout.decode('utf8')) - print('stderr:', e.stderr.decode('utf8')) - raise e - # CompositeAudioClip([concatenate_audioclips(split_files)]).write_audiofile( - # f"{self.path}/{idx}.mp3", fps=44100, verbose=False, logger=None - # ) - - # for i in range(0, idy + 1): - # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") - # Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() ->>>>>>> Stashed changes + for i in range(0, idy + 1): + # print(f"Cleaning up {self.path}/{idx}-{i}.part.mp3") + Path(f"{self.path}/{idx}-{i}.part.mp3").unlink() def call_tts(self, filename: str, text: str): self.tts_module.run(text=process_text(text), filepath=f"{self.path}/{filename}.mp3") diff --git a/reddit/subreddit.py b/reddit/subreddit.py index b64a52a..44ef55a 100644 --- a/reddit/subreddit.py +++ b/reddit/subreddit.py @@ -67,11 +67,17 @@ def get_subreddit_threads(POST_ID: str): and len(settings.config["reddit"]["thread"]["post_id"].split("+")) == 1 ): submission = reddit.submission(id=settings.config["reddit"]["thread"]["post_id"]) - else: + comment_type = settings.config["reddit"]["thread"]["sort"] + + if str(comment_type) == "top": + threads = subreddit.top(limit=25) + else: threads = subreddit.hot(limit=25) - submission = get_subreddit_undone(threads, subreddit) + + submission = get_subreddit_undone(threads, subreddit) submission = check_done(submission) # double-checking + if submission is None or not submission.num_comments: return get_subreddit_threads(POST_ID) # submission already done. rerun upvotes = submission.score diff --git a/requirements.txt b/requirements.txt index 1fb4672..1a1a33b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,5 +9,4 @@ requests==2.28.1 rich==12.4.4 toml==0.10.2 translators==5.3.1 -ffmpeg-python~= 0.2.0 numpy~=1.23.0 \ No newline at end of file diff --git a/utils/subreddit.py b/utils/subreddit.py index 48dceba..ac3a275 100644 --- a/utils/subreddit.py +++ b/utils/subreddit.py @@ -34,6 +34,9 @@ def get_subreddit_undone(submissions: list, subreddit): if submission.stickied: print_substep("This post was pinned by moderators. Skipping...") continue + if submission.num_comments == 0: + print_substep("This post has 0 comments. Skipping...") + continue return submission print("all submissions have been done going by top submission order") return get_subreddit_undone(