File size: 5,073 Bytes
1038d6b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import cv2
import os
import shutil
import random
from tqdm import tqdm

[os.system(c) for c in ["clear", "cls", "color a"]]

DEFAULT_DYNAMIC_INTERVALS: list[list[float]] = [
  [0.00, 9.44], [9.44, 12.07], [19.54, 22.04], [29.50, 31.14],
  [39.50, 41.14], [49.57, 50.55], [59.44, 61.14],
]

POLA_INTERVAL: list[int] = [10, 10]

REAL_VIDEO_PATH = "assets/ppt_real.mp4"
REV_VIDEO_PATH = "assets/ppt_reverse.mp4"
OUTPUT_DIR = "results"

def get_video_duration(video_path: str) -> int | None:
    """
    Membaca durasi file video menggunakan OpenCV dan mengembalikannya
    sebagai integer dalam detik.
    (TQDM dihilangkan dari sini untuk mempercepat pembacaan metadata awal)
    """
    if not os.path.exists(video_path):
        print(f"Error: File video tidak ditemukan di {video_path}")
        return 0
    
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        print(f"Error: Tidak dapat membuka file video {video_path}")
        return None

    fps = cap.get(cv2.CAP_PROP_FPS)
    frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    cap.release()

    if fps == 0 or frame_count == 0:
        print("Error: Tidak dapat mengambil FPS atau jumlah frame.")
        return None

    return int(frame_count / fps)

def extract_video_segment(input_path: str, output_path: str, start_sec: float, end_sec: float):
    """
    Memotong segmen video dari input_path berdasarkan start_sec dan end_sec,
    lalu menyimpannya ke output_path dengan progress bar.
    """
    cap = cv2.VideoCapture(input_path)
    if not cap.isOpened():
        print(f"Error membuka video: {input_path}")
        return

    fps = cap.get(cv2.CAP_PROP_FPS)
    width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
    fourcc = cv2.VideoWriter_fourcc(*'avc1') # type: ignore

    writer = cv2.VideoWriter(output_path, fourcc, fps, (width, height)) # type: ignore

    start_frame = int(start_sec * fps)
    end_frame = int(end_sec * fps)
    total_frames_to_write = end_frame - start_frame

    if total_frames_to_write <= 0:
        print(f"Warning: Tidak ada frame untuk diekstrak untuk segmen {output_path}")
        cap.release()
        writer.release()
        return

    cap.set(cv2.CAP_PROP_POS_FRAMES, start_frame)

    segment_pbar_desc = os.path.basename(output_path)
    with tqdm(total=total_frames_to_write, desc=f"Mengekstrak {segment_pbar_desc}", unit="frame", leave=False) as pbar:
        current_frame = start_frame
        while current_frame < end_frame:
            ret, frame = cap.read()
            if not ret:
                break
            writer.write(frame)
            pbar.update(1)
            current_frame += 1

    cap.release()
    writer.release()

if len(os.listdir(OUTPUT_DIR)) > 0:
    exit() if "n" in input("Lanjutkan proses? [N] ").lower() else ""
    shutil.rmtree(OUTPUT_DIR)

os.makedirs(OUTPUT_DIR, exist_ok=True)
print(f"Direktori output dipastikan ada: '{OUTPUT_DIR}'")

REAL_VIDEO_DURATION = get_video_duration(REAL_VIDEO_PATH) or 0
REV_VIDEO_DURATION = get_video_duration(REV_VIDEO_PATH) or 0

LONG_DURATION = max(REAL_VIDEO_DURATION, REV_VIDEO_DURATION)
print(f"Durasi video terpanjang (LONG_DURATION): {LONG_DURATION} detik")

dynamicIntervals: list[list[float]] = DEFAULT_DYNAMIC_INTERVALS.copy()
lastSecond = dynamicIntervals[-1][1] if dynamicIntervals else 0.0

with tqdm(total=LONG_DURATION, initial=lastSecond, desc="Membuat Interval", unit="s") as pbar:
    while lastSecond < LONG_DURATION:
        previous_lastSecond = lastSecond
        lastInterval = dynamicIntervals[-1]
        
        step = random.uniform(5.0, 10.0)
        new_start_time: float = lastInterval[0] + POLA_INTERVAL[0]
        new_end_time: float = lastInterval[1] + POLA_INTERVAL[1]

        if new_start_time >= LONG_DURATION:
            break

        lastSecond = min(new_end_time, LONG_DURATION)

        dynamicIntervals.append([
            new_start_time, lastSecond
        ])
        
        increment = lastSecond - previous_lastSecond
        pbar.update(increment)

reverseDynamicIntervals: list[list[float]] = []
for start, end in dynamicIntervals:
    rev_start = round(LONG_DURATION - end, 2)
    rev_end = round(LONG_DURATION - start, 2)
    reverseDynamicIntervals.append([rev_start, rev_end])

print(f"Total {len(dynamicIntervals)}, {len(reverseDynamicIntervals)} interval dinamis dibuat.")

print("\nMemproses segmen video REAL...")
for idx, interval in enumerate(tqdm(dynamicIntervals, desc="Video REAL")):
    start_time, end_time = interval
    output_filename = os.path.join(OUTPUT_DIR, f"real_{idx}.mp4")
    extract_video_segment(REAL_VIDEO_PATH, output_filename, start_time, end_time)

print("\nMemproses segmen video REVERSE...")
for idx, interval in enumerate(tqdm(reverseDynamicIntervals, desc="Video REVERSE")):
    start_time, end_time = interval
    output_filename = os.path.join(OUTPUT_DIR, f"reverse_{idx}.mp4")
    extract_video_segment(REV_VIDEO_PATH, output_filename, start_time, end_time)

print("\n\nSemua proses ekstraksi video telah selesai.")