File size: 4,852 Bytes
cf72e88
 
 
b9adb22
 
cf72e88
 
 
 
 
 
 
 
 
 
 
b9adb22
 
 
cf72e88
 
b9adb22
 
 
 
 
 
 
 
cf72e88
 
b9adb22
 
cf72e88
b9adb22
 
 
cf72e88
 
b9adb22
cf72e88
b9adb22
cf72e88
 
b9adb22
cf72e88
 
b9adb22
cf72e88
 
 
b9adb22
 
 
 
 
cf72e88
 
 
b9adb22
cf72e88
 
b9adb22
cf72e88
 
 
 
b9adb22
 
cf72e88
b9adb22
cf72e88
b9adb22
 
cf72e88
b9adb22
 
 
cf72e88
 
b9adb22
cf72e88
 
 
b9adb22
 
cf72e88
b9adb22
 
 
 
 
 
 
 
 
 
 
 
 
 
cf72e88
 
 
b9adb22
 
 
cf72e88
 
b9adb22
cf72e88
 
 
b9adb22
 
 
cf72e88
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from pathlib import Path

import stable_whisper as whisper

# Local imports
from .subtitle_creator import srt_create
from .text_to_speech import tts
from .tiktok import upload_tiktok
from .video_prepare import prepare_background
from .video_downloader import download_video as youtube_download
from utils import *

HOME = Path.cwd()
media_folder = HOME / 'media'


class ClipMaker:
    def __init__(self, clip: dict, args):
        self.clip = clip
        self.args = args

        # Fetch clip data or set default values
        self.series = clip.get('series', 'Crazy facts that you did not know')
        self.part = clip.get('part', '1')
        self.text = clip.get('text', 'The first person to survive going over Niagara Falls in a barrel was a 63-year-old school teacher')
        self.tags = clip.get('tags', ['survive', 'Niagara Falls', 'facts'])
        self.outro = clip.get('outro', 'I hope you enjoyed this video. If you did, please give it a thumbs up and subscribe to my channel. I will see you in the next video.')

        # Set media folder path
        self.path = Path(media_folder).absolute()

    def download_background_video(self, folder='background') -> None:
        # Download background video for the clip
        youtube_download(url=self.args.url, folder=folder)

        console.log(f"{msg.OK}Video downloaded from {self.args.url} to {folder}")
        return None

    def load_model(self):
        # Load Whisper model
        model = self.args.model
        
        if self.args.model != "large" and not self.args.non_english:
            model = self.args.model + ".en"

        whisper_model = whisper.load_model(model)

        # Set model to class attribute
        self.model = whisper_model
        return whisper_model

    def merge_clip_text(self) -> tuple:
        # Merge clip series, part, text and outro to create a single text for the clip
        req_text = f"{self.series} - Part {self.part}.\n{self.text}\n{self.outro}" # TODO: allow user to customize this

        # Remove whitespaces from series name and create a folder for the series
        series = self.series.replace(' ', '_')
        filename = f"{self.path}{os.sep}{series}{os.sep}{series}_{self.part}.mp3"

        # Create series folder if it does not exist
        Path(f"{self.path}{os.sep}{series}").mkdir(parents=True, exist_ok=True)

        # Set class attributes for text and mp3 (audio) file
        self.req_text = req_text
        self.mp3_file = filename
        return req_text, filename

    async def text_to_speech(self) -> None:
        # Convert text to speech using the selected TTS voice
        await tts(self.req_text, outfile=self.mp3_file, voice=self.args.tts, args=self.args)
        return None

    def generate_transcription(self) -> Path:
        # Generate subtitles for the clip using the Whisper model
        ass_filename = srt_create(self.model,
                                  self.path, self.series, self.part, self.mp3_file, **vars(self.args))

        # Get the absolute path of .ass file
        ass_filename = Path(ass_filename).absolute()

        # Set class attribute for .ass style file of subtitles
        self.ass_file = ass_filename
        return ass_filename

    def select_background(self, random: bool = True) -> Path:
        # Select which background video to use for the clip
        try:
            # Background video selected with WebUI for Streamlit
            # Add to the path the parent folder (background)
            background_file = self.args.mp4_background
            background_mp4 = Path(HOME / 'background' / background_file) # Concat path
            background_mp4 = background_mp4.absolute()

        except AttributeError: # Local CLI execution
            if random:
                background_mp4 = random_background()
                
            else: # TODO: allow the user to select which background video to use
                pass

        # Set class attribute for mp4 background file
        self.mp4_background = background_mp4
        return background_mp4

    def integrate_subtitles(self) -> Path:
        # Use FFMPEG to integrate subtitles into background video and trim everything with fixed length of the audio file
        final_video = prepare_background(str(self.mp4_background), filename_mp3=self.mp3_file, filename_srt=str(self.ass_file), verbose=self.args.verbose)
        final_video = Path(final_video).absolute()

        # Set class attribute for mp4 final clip file
        self.mp4_final_video = final_video
        return final_video

    def upload_to_tiktok(self) -> bool: # TODO: check if still working with Cookie
        # Automatic upload on TikTok
        uploaded = upload_tiktok(str(self.mp4_final_video), title=f"{self.series} - {self.part}", tags=self.tags, headless=not self.args.verbose)
        return uploaded