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.")