Download python/cut_video.py from Adibrino/PPT-BUDAYA-INDONESIA-HTML-CONTROL-LOGIC: direct link, hf CLI and curl.
- Browser
- Download file 5.07 kB
-
https://huggingface.co/spaces/Adibrino/PPT-BUDAYA-INDONESIA-HTML-CONTROL-LOGIC/resolve/main/python/cut_video.py
- Command line
-
hf download hf://spaces/Adibrino/PPT-BUDAYA-INDONESIA-HTML-CONTROL-LOGIC/python/cut_video.py
-
curl -L -o cut_video.py https://huggingface.co/spaces/Adibrino/PPT-BUDAYA-INDONESIA-HTML-CONTROL-LOGIC/resolve/main/python/cut_video.py
5.07 kB
| 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.") |