-
Notifications
You must be signed in to change notification settings - Fork 3
/
player.py
80 lines (68 loc) · 2.55 KB
/
player.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
import os
import cv2
import curses
import argparse
import time
from functools import lru_cache
parser = argparse.ArgumentParser(description='ASCII Player')
parser.add_argument("--width", type=int, default = 120, help="width of the terminal window")
parser.add_argument("--fps", type=int, default = 30, help="width of the terminal window")
parser.add_argument("--show", type=bool, default = False, help="show the original video in an opencv window")
parser.add_argument("--inv", type=bool, default = False, help="invert the shades")
parser.add_argument("video", type=str, help="path to video or webcam index")
args = parser.parse_args()
video = args.video
try:
video = int(video)
except ValueError:
pass
width = args.width
characters = [' ', '.', ',', '-', '~', ':', ';', '=', '!', '*', '#', '$', '@']
if args.inv:
characters = characters[::-1]
char_range = int(255 / len(characters))
@lru_cache
def get_char(val):
return characters[min(int(val/char_range), len(characters)-1)]
try:
if type(video) is str and not os.path.isfile(video):
print("failed to find video at:", args.video)
video = cv2.VideoCapture(video)
ok, frame = video.read()
if not ok:
print("could not extract frame from video")
ratio = width/frame.shape[1]
height = int(frame.shape[0]*ratio) // 2 # charachter height is 2 times character width
print(frame.shape)
print(width, height, ratio)
curses.initscr()
window = curses.newwin(height, width, 0, 0)
frame_count = 0
frames_per_ms = args.fps/1000
start = time.perf_counter_ns()//1000000
while True:
ok, orig_frame = video.read()
if not ok:
break
frame = cv2.resize(orig_frame, (width, height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
if args.show:
cv2.imshow("frame", orig_frame)
cv2.waitKey(1)
for y in range(0, frame.shape[0]):
for x in range(0, frame.shape[1]):
try:
window.addch(y, x, get_char(frame[y, x]))
except (curses.error):
pass
elapsed = (time.perf_counter_ns()//1000000) - start
supposed_frame_count = frames_per_ms * elapsed
if frame_count > supposed_frame_count:
time.sleep((frame_count-supposed_frame_count)*(1/frames_per_ms)/1000)
window.refresh()
frame_count += 1
finally:
cv2.destroyAllWindows()
curses.endwin()
fps = frame_count / (((time.perf_counter_ns()//1000000) - start) / 1000)
print("played on average at %d fps" % fps)