Adibrino's picture
Start
1038d6b
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.")