import cv2 import sys import time BLACK = "⬛" WHITE = "⬜" def frame_to_emoji(frame, threshold=128): gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) lines = [] for row in gray: line = "".join( WHITE if pixel > threshold else BLACK for pixel in row ) lines.append(line) return "\n".join(lines) def main(video_path, width=80): cap = cv2.VideoCapture(video_path) if not cap.isOpened(): print(f"Could not open {video_path}") return fps = cap.get(cv2.CAP_PROP_FPS) if fps <= 0: fps = 24 frame_delay = 1.0 / fps while True: start = time.time() ret, frame = cap.read() if not ret: break h, w = frame.shape[:2] # terminal characters are taller than wide aspect = h / w height = max(1, int(width * aspect * 0.5)) frame = cv2.resize( frame, (width, height), interpolation=cv2.INTER_AREA ) emoji_frame = frame_to_emoji(frame) # clear screen, move cursor to home pos sys.stdout.write("\033[H\033[J") sys.stdout.write(emoji_frame) sys.stdout.flush() elapsed = time.time() - start sleep_time = frame_delay - elapsed if sleep_time > 0: time.sleep(sleep_time) cap.release() if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python pyvid2term.py video.mp4 [width]") sys.exit(1) video = sys.argv[1] width = int(sys.argv[2]) if len(sys.argv) > 2 else 80 main(video, width)