Note
Go to the end to download the full example code
Play a video in the 3D world#
The goal of this demo is to show how to visualize a video on a rectangle by updating a texture.
/Users/skoudoro/devel/fury/docs/examples_revamped/04_demos/viz_play_video.py:91: UserWarning: We'll no longer accept the way you call the __init__ function in future versions of FURY.
Here's how to call the Function __init__: __init__(self_value, scene='value', title='value', size='value', png_magnify='value', reset_camera='value', order_transparent='value', interactor_style='value', stereo='value', multi_samples='value', max_peels='value', occlusion_ratio='value')
vp = VideoPlayer(video_url)
/opt/homebrew/Caskroom/miniforge/base/envs/py39/lib/python3.9/site-packages/sphinx_gallery/gen_rst.py:722: UserWarning: We'll no longer accept the way you call the record function in future versions of FURY.
Here's how to call the Function record: record(scene='value', cam_pos='value', cam_focal='value', cam_view='value', out_path='value', path_numbering='value', n_frames='value', az_ang='value', magnification='value', size='value', reset_camera='value', screen_clip='value', stereo='value', verbose='value')
exec(self.code, self.fake_main.__dict__)
import time
import cv2
import numpy as np
import fury
# The VideoCapturer Class
# This Class wraps OpenCV Videocapture
class VideoCapturer:
def __init__(self, video, time):
self.path = video
self.video = cv2.VideoCapture(self.path)
self.fps = int(self.video.get(cv2.CAP_PROP_FPS))
self.frames = int(self.video.get(cv2.CAP_PROP_FRAME_COUNT))
self.time = time
# A generator to yield video frames on every call
def get_frame(self):
start = time.time()
for _ in range(self.frames):
isframe, frame = self.video.read()
dur = time.time() - start
if dur > self.time:
break
if isframe:
yield cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.video.release()
yield None
class VideoPlayer:
def __init__(self, video, time=10):
# Initializes the Video object with the given Video
self.video = VideoCapturer(video, time)
self.video_generator = self.video.get_frame()
self.current_video_frame = next(self.video_generator)
# Initialize Scene
self.initialize_scene()
# Create a Show Manager and Initialize it
self.show_manager = fury.window.ShowManager(
self.scene, size=(900, 768), reset_camera=False, order_transparent=True
)
# Initialize the Scene with actors
def initialize_scene(self):
self.scene = fury.window.Scene()
# Initialize a Plane actor with the 1st video frame along with
# the actor grid which is to be updated in each iteration
self.plane_actor = fury.actor.texture(self.current_video_frame)
self.scene.add(self.plane_actor)
# The timer_callback function getting called by the show manager
def timer_callback(self, _obj, _event):
self.current_video_frame = next(self.video_generator)
if isinstance(self.current_video_frame, np.ndarray):
# update texture of the actor with the current frame image
# by updating the actor grid
fury.actor.texture_update(self.plane_actor, self.current_video_frame)
self.show_manager.scene.azimuth(1.5) # to rotate the camera
else:
self.show_manager.exit()
self.show_manager.render()
def run(self):
# Add a timer callback to show manager after with
# video frame duration as the interval
self.frame_duration = int(1000 / self.video.fps)
self.show_manager.add_timer_callback(
True, self.frame_duration, self.timer_callback
)
self.show_manager.start()
# Create VideoPlayer Object and run it
video_url = (
"http://commondatastorage.googleapis.com/"
+ "gtv-videos-bucket/sample/BigBuckBunny.mp4"
)
vp = VideoPlayer(video_url)
vp.run()
fury.window.record(
vp.show_manager.scene, out_path="viz_play_video.png", size=(600, 600)
)
Total running time of the script: (0 minutes 10.679 seconds)