Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import argparse, cv2, threading, time, os
- from queue import Queue
- ASCII_FRAME_WIDTH = 80
- ASCII_MAX_FRAME_HEIGHT = 38
- INIT_BUFFER_SIZE = 200
- CLEANER_SYMBOL = "\033[F"
- cleaner_str = ""
- # the frame should be grayscaled
- def frame_to_ascii(frame):
- return "\n".join(["".join([pixel_to_ascii(c) for c in row]) for row in frame])
- def pixel_to_ascii(pixel):
- if pixel <= 12:
- return ' '
- if pixel <= 50:
- return '.'
- if pixel <= 75:
- return '*'
- if pixel <= 100:
- return '='
- if pixel <= 125:
- return '|'
- if pixel <= 150:
- return 'J'
- if pixel <= 200:
- return 'P'
- return 'B'
- def show_ascii_frame(printable_frame):
- print(printable_frame, end=cleaner_str)
- # frames consumer transforms grayscale image to ascii and prints it from frames queue
- def frames_consumer(frames_queue, frame_pause):
- while True:
- if frames_queue.empty():
- continue
- show_ascii_frame(frames_queue.get())
- frames_queue.task_done()
- time.sleep(frame_pause)
- def main():
- global cleaner_str
- parser = argparse.ArgumentParser(description="A tool to play any video as an ascii animation")
- parser.add_argument("source", type=str, help="A path to the video that's needed to be played")
- args = parser.parse_args()
- video_path = args.source
- cap = cv2.VideoCapture(video_path)
- if not cap.isOpened():
- parser.error("Cannot initialize video capture from a given file, path to a file may be incorrect")
- # calculating scaled size of frame
- init_frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
- init_frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
- scale_koef = ASCII_FRAME_WIDTH / init_frame_width
- scaled_width = ASCII_FRAME_WIDTH
- scaled_height = min(int(init_frame_height * scale_koef), ASCII_MAX_FRAME_HEIGHT)
- cleaner_str = CLEANER_SYMBOL * (scaled_height - 1)
- # initializing queue needed variables
- fps = cap.get(cv2.CAP_PROP_FPS)
- frame_pause = 1 / (fps * 2)
- frames_queue = Queue()
- total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
- frames_counter = 0
- consumer_started = False
- buffering_frames = min(INIT_BUFFER_SIZE, total_frames)
- while cap.isOpened():
- ret, frame = cap.read()
- if not ret:
- break
- frames_counter += 1
- frame = cv2.resize(frame, (scaled_width, scaled_height), interpolation=cv2.INTER_AREA)
- frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
- frames_queue.put(frame_to_ascii(frame))
- if not consumer_started and frames_counter >= buffering_frames:
- threading.Thread(target=frames_consumer, args=(frames_queue, frame_pause,), daemon=True).start()
- consumer_started = True
- elif not consumer_started:
- print(f"Initial bufferization: frame {frames_counter}/{buffering_frames}", end='\r')
- while not frames_queue.empty():
- time.sleep(.1)
- os.system("cls")
- exit()
- if __name__ == "__main__":
- main()
Advertisement
Add Comment
Please, Sign In to add comment