Skip to content

Commit 61b4206

Browse files
Create _show.py
1 parent ecf17a3 commit 61b4206

1 file changed

Lines changed: 300 additions & 0 deletions

File tree

musicalgestures/_show.py

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
# import cv2
2+
# import numpy as np
3+
import os
4+
from matplotlib import pyplot as plt
5+
from IPython.display import Image, display
6+
# try:
7+
from IPython.display import Video
8+
# except:
9+
# from IPython.core.display import Video
10+
# from base64 import b64encode
11+
import musicalgestures
12+
# from musicalgestures._utils import get_widthheight
13+
14+
15+
def mg_show(self, filename=None, key=None, mode='windowed', window_width=640, window_height=480, window_title=None):
16+
# def mg_show(self, filename=None, mode='windowed', window_width=640, window_height=480, window_title=None):
17+
"""
18+
General method to show an image or video file either in a window, or inline in a jupyter notebook.
19+
20+
Args:
21+
filename (str, optional): If given, `mg_show` will show this file instead of what it inherits from its parent object. Defaults to None.
22+
key (str, optional): If given, `mg_show` will search for file names corresponding to certain processes you have previously rendered on your source. It is meant to be a shortcut, so you don't have to remember the exact name (and path) of eg. a motion video corresponding to your source in your MgVideo, but you rather just use `MgVideo('path/to/vid.mp4').show(key='motion')`. Accepted values are 'mgx', 'mgy', 'vgx', 'vgy', 'average', 'plot', 'motion', 'history', 'motionhistory', 'sparse', and 'dense'. Defaults to None.
23+
mode (str, optional): Whether to show things in a separate window or inline in the jupyter notebook. Accepted values are 'windowed' and 'notebook'. Defaults to 'windowed'.
24+
window_width (int, optional): The width of the window. Defaults to 640.
25+
window_height (int, optional): The height of the window. Defaults to 480.
26+
window_title (str, optional): The title of the window. If None, the title of the window will be the file name. Defaults to None.
27+
"""
28+
29+
def show(file, width=640, height=480, mode='windowed', title='Untitled', parent=None):
30+
"""
31+
Helper function which actually does the "showing".
32+
33+
Args:
34+
file (str): Path to the file.
35+
width (int, optional): The width of the window. Defaults to 640.
36+
height (int, optional): The height of the window. Defaults to 480.
37+
mode (str, optional): 'windowed' will use ffplay (in a separate window), while 'notebook' will use Image or Video from IPython.display. Defaults to 'windowed'.
38+
title (str, optional): The title of the window. Defaults to 'Untitled'.
39+
"""
40+
if mode.lower() == 'windowed':
41+
from musicalgestures._utils import in_colab
42+
if in_colab():
43+
mode = 'notebook'
44+
if mode.lower() == 'windowed':
45+
from musicalgestures._utils import wrap_str
46+
# cmd = f'ffplay "{file}" -x {width} -y {height} -window_title "{title}"'
47+
cmd = f'ffplay {wrap_str(file)} -window_title {wrap_str(title)} -x {width} -y {height}'
48+
# show_async(cmd)
49+
show_in_new_process(cmd)
50+
51+
elif mode.lower() == 'notebook':
52+
video_formats = ['.avi', '.mp4', '.mov', '.mkv', '.mpg',
53+
'.mpeg', '.webm', '.ogg', '.ts', '.wmv', '.3gp']
54+
image_formats = ['.jpg', '.png', '.jpeg', '.tiff', '.gif', '.bmp']
55+
file_extension = os.path.splitext(file)[1].lower()
56+
57+
if file_extension in video_formats:
58+
file_type = 'video'
59+
elif file_extension in image_formats:
60+
file_type = 'image'
61+
if file_type == 'image':
62+
display(Image(file))
63+
elif file_type == 'video':
64+
if file_extension not in ['.mp4', '.webm', '.ogg']:
65+
keys = parent.__dict__.keys()
66+
if "as_mp4" not in keys:
67+
from musicalgestures._utils import convert_to_mp4
68+
print('Only mp4, webm and ogg videos are supported in notebook mode.')
69+
video_to_display = convert_to_mp4(file)
70+
# register converted video as_mp4 for parent MgVideo
71+
parent.as_mp4 = musicalgestures.MgVideo(
72+
video_to_display)
73+
else:
74+
video_to_display = parent.as_mp4.filename
75+
else:
76+
video_to_display = file
77+
78+
# check width and height of video, if they are bigger than "appropriate", limit their dimensions
79+
video_width, video_height = musicalgestures._utils.get_widthheight(video_to_display)
80+
video_width = video_width if video_width <= width else width
81+
video_height = video_height if video_height <= height else height
82+
83+
# if the video is at the same folder as the notebook, we need to use relative path
84+
# and if it is somewhere else, we need to embed it to make it work (neither absolute nor relative paths seem to work without embedding)
85+
cwd = os.getcwd().replace('\\', '/')
86+
file_dir = os.path.dirname(video_to_display).replace('\\', '/')
87+
if file_dir == cwd:
88+
try:
89+
video_to_display = os.path.relpath(video_to_display, os.getcwd()).replace('\\', '/')
90+
display(Video(video_to_display,width=video_width, height=video_height))
91+
except ValueError:
92+
video_to_display = os.path.abspath(video_to_display, os.getcwd()).replace('\\', '/')
93+
display(Video(video_to_display, width=video_width,height=video_height))
94+
else:
95+
try:
96+
video_to_display = os.path.relpath(video_to_display, os.getcwd()).replace('\\', '/')
97+
display(Video(video_to_display, width=video_width,
98+
height=video_height))
99+
except ValueError:
100+
video_to_display = os.path.abspath(video_to_display, os.getcwd()).replace('\\', '/')
101+
display(Video(video_to_display, width=video_width,height=video_height))
102+
103+
else:
104+
print(f'Unrecognized mode: "{mode}". Try "windowed" or "notebook".')
105+
106+
if window_title == None:
107+
window_title = self.filename
108+
109+
if filename == None:
110+
keys = self.__dict__.keys()
111+
if key == None:
112+
filename = self.filename
113+
show(file=filename, width=window_width,
114+
height=window_height, mode=mode, title=window_title, parent=self)
115+
116+
elif key.lower() == 'mgx':
117+
if "motiongram_x" in keys:
118+
filename = self.motiongram_x.filename
119+
show(file=filename, width=window_width,
120+
height=window_height, mode=mode, title=f'Horizontal Motiongram | {filename}', parent=self)
121+
else:
122+
raise FileNotFoundError(
123+
"There is no known horizontal motiongram for this file.")
124+
125+
elif key.lower() == 'mgy':
126+
if "motiongram_y" in keys:
127+
filename = self.motiongram_y.filename
128+
show(file=filename, width=window_width,
129+
height=window_height, mode=mode, title=f'Vertical Motiongram | {filename}', parent=self)
130+
else:
131+
raise FileNotFoundError(
132+
"There is no known vertical motiongram for this file.")
133+
134+
elif key.lower() == 'vgx':
135+
if "videogram_x" in keys:
136+
filename = self.videogram_x.filename
137+
show(file=filename, width=window_width,
138+
height=window_height, mode=mode, title=f'Horizontal Videogram | {filename}', parent=self)
139+
else:
140+
raise FileNotFoundError(
141+
"There is no known horizontal videogram for this file.")
142+
143+
elif key.lower() == 'ssm':
144+
if "ssm" in keys:
145+
filename = self.ssm.image
146+
if len(filename) == 2:
147+
show(file=filename[0], width=window_width, height=window_height, mode=mode, title=f'Horizontal SSM | {filename}', parent=self)
148+
show(file=filename[1], width=window_width, height=window_height, mode=mode, title=f'Vertical SSM | {filename}', parent=self)
149+
else:
150+
show(file=filename, width=window_width, height=window_height, mode=mode, title=f'Self-Similarity Matrix | {filename}', parent=self)
151+
else:
152+
raise FileNotFoundError(
153+
"There is no known self-smilarity matrix for this file.")
154+
155+
elif key.lower() == 'vgy':
156+
if "videogram_y" in keys:
157+
filename = self.videogram_y.filename
158+
show(file=filename, width=window_width,
159+
height=window_height, mode=mode, title=f'Vertical Videogram | {filename}', parent=self)
160+
else:
161+
raise FileNotFoundError(
162+
"There is no known vertical videogram for this file.")
163+
164+
elif key.lower() == 'average':
165+
if "average_image" in keys:
166+
filename = self.average_image.filename
167+
show(file=filename, width=window_width,
168+
height=window_height, mode=mode, title=f'Average Image | {filename}', parent=self)
169+
else:
170+
raise FileNotFoundError(
171+
"There is no known average image for this file.")
172+
elif key.lower() == 'plot':
173+
# filename = self.of + '_motion_com_qom.png'
174+
if "motion_plot" in keys:
175+
filename = self.motion_plot.filename
176+
show(file=filename, width=window_width,
177+
height=window_height, mode=mode, title=f'Centroid and Quantity of Motion | {filename}', parent=self)
178+
else:
179+
raise FileNotFoundError(
180+
"There is no known motion plot for this file.")
181+
182+
elif key.lower() == 'motion':
183+
if "motion_video" in keys:
184+
filename = self.motion_video.filename
185+
show(file=filename, width=window_width,
186+
height=window_height, mode=mode, title=f'Motion Video | {filename}', parent=self)
187+
else:
188+
raise FileNotFoundError(
189+
"There is no known motion video for this file.")
190+
191+
elif key.lower() == 'history':
192+
if "history_video" in keys:
193+
filename = self.history_video.filename
194+
show(file=filename, width=window_width,
195+
height=window_height, mode=mode, title=f'History Video | {filename}', parent=self)
196+
else:
197+
raise FileNotFoundError(
198+
"There is no known history video for this file.")
199+
200+
elif key.lower() == 'motionhistory':
201+
if "motion_video" in keys:
202+
motion_video_keys = self.motion_video.__dict__.keys()
203+
if "history_video" in motion_video_keys:
204+
filename = self.motion_vide.history_video.filename
205+
show(file=filename, width=window_width,
206+
height=window_height, mode=mode, title=f'Motion History Video | {filename}', parent=self)
207+
else:
208+
raise FileNotFoundError(
209+
"There is no known motion history video for this file.")
210+
else:
211+
raise FileNotFoundError(
212+
"There is no known motion video for this file.")
213+
214+
elif key.lower() == 'sparse':
215+
if "flow_sparse_video" in keys:
216+
filename = self.flow_sparse_video.filename
217+
show(file=filename, width=window_width,
218+
height=window_height, mode=mode, title=f'Sparse Optical Flow Video | {filename}', parent=self)
219+
else:
220+
raise FileNotFoundError(
221+
"There is no known sparse optial flow video for this file.")
222+
223+
elif key.lower() == 'dense':
224+
if "flow_dense_video" in keys:
225+
filename = self.flow_dense_video.filename
226+
show(file=filename, width=window_width,
227+
height=window_height, mode=mode, title=f'Dense Optical Flow Video | {filename}', parent=self)
228+
else:
229+
raise FileNotFoundError(
230+
"There is no known dense optial flow video for this file.")
231+
232+
elif key.lower() == 'pose':
233+
if "pose_video" in keys:
234+
filename = self.pose_video.filename
235+
show(file=filename, width=window_width,
236+
height=window_height, mode=mode, title=f'Pose Video | {filename}', parent=self)
237+
else:
238+
raise FileNotFoundError(
239+
"There is no known pose video for this file.")
240+
241+
elif key.lower() == 'warp':
242+
if "warp_audiovisual_beats" in keys:
243+
filename = self.warp_audiovisual_beats.filename
244+
show(file=filename, width=window_width,
245+
height=window_height, mode=mode, title=f'Warp Audiovisual Video | {filename}', parent=self)
246+
else:
247+
raise FileNotFoundError(
248+
"There is no known warp audiovisual beats video for this file.")
249+
250+
elif key.lower() == 'blur':
251+
if "blur_faces" in keys:
252+
filename = self.blur_faces.filename
253+
show(file=filename, width=window_width,
254+
height=window_height, mode=mode, title=f'Blur Faces Video | {filename}', parent=self)
255+
256+
257+
elif key.lower() == 'subtract':
258+
if "subtract" in keys:
259+
filename = self.subtract.filename
260+
show(file=filename, width=window_width,
261+
height=window_height, mode=mode, title=f'Background Subtraction Video | {filename}', parent=self)
262+
else:
263+
raise FileNotFoundError("There is no known subtract video for this file.")
264+
265+
266+
267+
else:
268+
print("Unknown shorthand.\n",
269+
"For images, try 'mgx', 'mgy', 'vgx', 'vgy', 'ssmx','ssmy', 'average' or 'plot'.\n",
270+
"For videos try 'motion', 'history', 'motionhistory', 'sparse', 'dense', 'pose', 'warp', 'blur' or 'subtract'.")
271+
272+
else:
273+
show(file=filename, width=window_width,
274+
height=window_height, mode=mode, title=window_title, parent=self)
275+
# show(file=filename, width=window_width, height=window_height, mode=mode, title=window_title)
276+
277+
return self
278+
279+
280+
def show_in_new_process(command):
281+
import subprocess
282+
# import time
283+
import sys
284+
import platform
285+
from musicalgestures._utils import wrap_str
286+
module_path = os.path.realpath(os.path.dirname(
287+
musicalgestures.__file__)).replace('\\', '/')
288+
the_system = platform.system()
289+
pythonkw = "python"
290+
if the_system != "Windows":
291+
pythonkw += "3"
292+
pyfile = wrap_str(module_path + '/_show_window.py')
293+
cmd = [pythonkw, pyfile, wrap_str(command)]
294+
# print(cmd)
295+
with open(os.devnull, 'r+b', 0) as DEVNULL:
296+
process = subprocess.Popen(
297+
cmd, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL, close_fds=True)
298+
# time.sleep(1)
299+
if process.poll():
300+
sys.exit(process.returncode)

0 commit comments

Comments
 (0)