File size: 7,266 Bytes
80b326d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
from scripts import cut_json
import os
import subprocess
import json

def cut(segments, project_folder="tmp", skip_video=False):

    def check_nvenc_support():
        # ... (unchanged)
        try:
            result = subprocess.run(["ffmpeg", "-encoders"], capture_output=True, text=True)
            return "h264_nvenc" in result.stdout
        except subprocess.CalledProcessError:
            return False

    def generate_segments(response, project_folder, skip_video):
        if not check_nvenc_support():
            print("NVENC is not supported on this system. Falling back to libx264.")
            video_codec = "libx264"
        else:
            video_codec = "h264_nvenc"

        # Procurar input_video.mp4 no project_folder ou tmp
        input_file = os.path.join(project_folder, "input.mp4")
        if not os.path.exists(input_file):
            # Tenta fallback legado
            input_file_legacy = os.path.join(project_folder, "input_video.mp4")
            if os.path.exists(input_file_legacy):
                input_file = input_file_legacy
            else:
                print(f"Input file not found in {project_folder}")
                return

        # Pasta de saida para os cortes
        cuts_folder = os.path.join(project_folder, "cuts")
        os.makedirs(cuts_folder, exist_ok=True)
        
        # Pasta de saida para legendas json cortadas
        subs_folder = os.path.join(project_folder, "subs")
        os.makedirs(subs_folder, exist_ok=True)

        # Input JSON (Transkription original)
        input_json_path = os.path.join(project_folder, "input.json")

        segments = response.get("segments", [])
        for i, segment in enumerate(segments):
            start_time = segment.get("start_time", "00:00:00")
            duration = segment.get("duration", 0)

            # Heurística para duration:
            if isinstance(duration, (int, float)):
                if duration < 1000:
                    duration_seconds = float(duration)
                else:
                    duration_seconds = duration / 1000.0
                duration_str = f"{duration_seconds:.3f}"
            else:
                # Tenta converter string (HH:MM:SS ou float str)
                try:
                    duration_seconds = float(duration)
                    duration_str = f"{duration_seconds:.3f}"
                except ValueError:
                    # Assumindo formato hh:mm:ss se nao for float
                     # Implementar parser se necessario, mas assumindo float por enquanto baseado no historico
                    duration_seconds = 0
                    duration_str = duration
            
            # Heurística para start_time:
            if isinstance(start_time, (int, float)):
                if start_time > 10000: # Se for milisegundos grandes? Assumindo segundos ou HHMMSS?
                   # O código original: if start_time int -> start_time/1000.0.
                   # Vamos manter a lógica original: int -> milisegundos
                   pass
            
            # Refazendo a logica original exata para seguranca e capturando o float:
            if isinstance(start_time, int):
                start_time_seconds = start_time / 1000.0
                start_time_str = f"{start_time_seconds:.3f}"
            elif isinstance(start_time, float):
                 start_time_seconds = start_time
                 start_time_str = f"{start_time_seconds:.3f}"
            else:
                # String "00:00:00" ou "12.34"
                try:
                    start_time_seconds = float(start_time)
                    start_time_str = f"{start_time_seconds:.3f}"
                except:
                    # Se for HH:MM:SS, ffmpeg aceita, mas precisamos converter para float para o json cutter
                    # Função auxiliar simples
                    h, m, s = str(start_time).split(':')
                    start_time_seconds = int(h) * 3600 + int(m) * 60 + float(s)
                    start_time_str = str(start_time)

            # Título para nome de arquivo
            title = segment.get("title", f"Segment_{i}")
            safe_title = "".join([c for c in title if c.isalnum() or c in " _-"]).strip()
            safe_title = safe_title.replace(" ", "_")[:60]
            base_name = f"{i:03d}_{safe_title}"

            output_filename = f"{base_name}_original_scale.mp4"
            output_path = os.path.join(cuts_folder, output_filename)

            print(f"Processing segment {i+1}/{len(segments)}")
            print(f"Start time: {start_time}, Duration: {duration}")
            # print(f"Executing command: {' '.join(command)}")

            # VIDEO GENERATION
            if not skip_video:
                # Comando ffmpeg
                command = [
                    "ffmpeg",
                    "-y",
                    "-loglevel", "error", "-hide_banner",
                    "-ss", start_time_str,
                    "-i", input_file,
                    "-t", duration_str,
                    "-c:v", video_codec
                ]

                if video_codec == "h264_nvenc":
                    command.extend([
                        "-preset", "p1",
                        "-b:v", "5M",
                    ])
                else:
                    command.extend([
                        "-preset", "ultrafast",
                        "-crf", "23"
                    ])

                command.extend([
                    "-c:a", "aac",
                    "-b:a", "128k",
                    output_path
                ])

                try:
                    subprocess.run(command, check=True, capture_output=True, text=True)
                    if os.path.exists(output_path):
                        file_size = os.path.getsize(output_path)
                        print(f"Generated segment: {output_filename}, Size: {file_size} bytes")
                except subprocess.CalledProcessError as e:
                    print(f"Error executing ffmpeg: {e}")
            else:
                print(f"Skipping video generation for {output_filename} (using existing). check json...")
            
            # --- JSON CUTTING (ALWAYS RUN) ---
            end_time_seconds = start_time_seconds + float(duration_seconds)
            
            # Nome do json correspondente ao vídeo FINAL com titulo
            json_output_filename = f"{base_name}_processed.json"
            json_output_path = os.path.join(subs_folder, json_output_filename)
            
            cut_json.cut_json_transcript(input_json_path, json_output_path, start_time_seconds, end_time_seconds)
            # --------------------

            print("\n" + "="*50 + "\n")

    # Reading the JSON file if segments not provided (legacy behavior)
    if segments is None:
        json_path = os.path.join(project_folder, 'viral_segments.txt')
        with open(json_path, 'r', encoding='utf-8') as file:
            response = json.load(file)
    else:
        response = segments

    generate_segments(response, project_folder, skip_video)