indexing description: "[ EM_VIDEO_DECODER example. Plays a video file. ]" date: "$Date$" revision: "$Revision$" class VIDEO_PLAYER_SCENE inherit EM_WIDGET_SCENE redefine initialize_scene end EM_SHARED_VIDEO_DECODER_FACTORY export {NONE} all end EM_SHARED_SCENE export {NONE} all end EM_SHARED_BITMAP_FACTORY export {NONE} all end create make_widget_scene feature {NONE} -- Initialization initialize_scene is -- initialize current scene do -- load the default movie set_running_scene (Current) video_decoder_factory.create_video_decoder_from_file (video_file_name) video_decoder := video_decoder_factory.last_video_decoder -- create the container for the movie create container.make (width, height-35) -- insert the movie in the container container.extend (video_decoder) video_decoder.set_x_y (0, 0) -- zoom the video -- extreme memory usage see em_surface draw_bitmap_stretched... container.scroll_and_zoom_to_rectangle (create {EM_RECTANGLE}.make_from_position_and_size (0, 0, video_decoder.width, video_decoder.height)) -- subscribe event when the movie stops video_decoder.on_stop.subscribe (agent on_stop) -- create the widget stuff create_widget_stuff end load_bitmaps_and_buttons is -- load all bitmaps do bitmap_factory.create_bitmap_from_image ("play.png") play_bitmap := bitmap_factory.last_bitmap bitmap_factory.create_bitmap_from_image ("pause.png") pause_bitmap := bitmap_factory.last_bitmap bitmap_factory.create_bitmap_from_image ("stop.png") stop_bitmap := bitmap_factory.last_bitmap bitmap_factory.create_bitmap_from_image ("open.png") open_bitmap := bitmap_factory.last_bitmap create play_pause_button.make_from_image (play_bitmap) play_pause_button.set_y (time_slider.y + time_slider.height) play_pause_button.set_border (create {EM_BEVEL_BORDER}.make_up) play_pause_button.set_dimension (25, 25) create stop_button.make_from_image (stop_bitmap) stop_button.set_y (play_pause_button.y) stop_button.set_border (create {EM_BEVEL_BORDER}.make_up) stop_button.set_x (play_pause_button.x + play_pause_button.width + 2) stop_button.set_dimension (25, 25) create open_button.make_from_image (open_bitmap) open_button.set_y (stop_button.y) open_button.set_border (create {EM_BEVEL_BORDER}.make_up) open_button.set_x (width - 30) open_button.set_dimension (25, 25) end create_widget_stuff is -- create the widgets used in this example local drawable_panel: EM_DRAWABLE_PANEL do -- create widget with container create drawable_panel.make_from_container (container) drawable_panel.set_background_color (create {EM_COLOR}.make_black) add_widget (drawable_panel) -- create the time bar create time_slider.make_from_range_horizontal (0, video_decoder.video_length) time_slider.set_y (drawable_panel.height) time_slider.set_dimension (width, 10) time_slider.set_border (create {EM_BEVEL_BORDER}.make_down) time_slider.set_transparent time_slider.set_mouse_sensitive (true) time_slider.mouse_button_down_event.subscribe (agent do_slide (true, ?)) time_slider.mouse_button_up_event.subscribe (agent do_slide (false, ?)) time_slider.position_changed_event.subscribe (agent set_slide_to) create progress_bar.make_from_steps (video_decoder.video_length) progress_bar.set_y (time_slider.y) progress_bar.set_x (time_slider.x+6) progress_bar.set_dimension (time_slider.width-12, time_slider.height) progress_bar.set_border (create {EM_NO_BORDER}) add_widget (progress_bar) add_widget (time_slider) -- load bitmaps and buttons load_bitmaps_and_buttons -- add events play_pause_button.clicked_event.subscribe (agent play) add_widget (play_pause_button) stop_button.clicked_event.subscribe (agent stop) stop_button.disable add_widget (stop_button) open_button.clicked_event.subscribe (agent open) add_widget (open_button) event_loop.update_event.subscribe (agent update_event) end feature {NONE} -- events play is -- start playback do if not video_decoder.is_playing then if not video_decoder.is_paused then video_decoder.play (1) stop_button.enable else video_decoder.resume end play_pause_button.set_image (pause_bitmap) else video_decoder.pause play_pause_button.set_image (play_bitmap) end end stop is -- stop playback do if video_decoder.is_playing or video_decoder.is_paused then video_decoder.stop end end open is -- open file local dialog: EM_FILE_DIALOG do create dialog.make dialog.center_on_screen dialog.set_modal (true) dialog.hide_event.subscribe (agent load_movie (dialog)) dialog.set_title ("Open movie") dialog.show end load_movie (dialog: EM_FILE_DIALOG) is -- load a new movie local retries: INTEGER has_error: BOOLEAN do if dialog.was_ok_clicked then if has_error then video_decoder_factory.create_video_decoder_from_file (video_decoder.file_name) else video_decoder_factory.create_video_decoder_from_file (dialog.absolute_filename) end container.delete (video_decoder) video_decoder := video_decoder_factory.last_video_decoder container.extend (video_decoder) container.scroll_and_zoom_to_rectangle (create {EM_RECTANGLE}.make_from_position_and_size (0, 0, video_decoder.width, video_decoder.height)) video_decoder.on_stop.subscribe (agent on_stop) end end on_stop is -- playback has stopped do play_pause_button.set_image (play_bitmap) stop_button.disable end update_event is -- update slider and progressbar -- synchronize with movie position do progress_bar.set_steps (video_decoder.video_length) progress_bar.set_current_step (video_decoder.position) if not is_sliding then -- user doesn't move the slider time_slider.set_right_value (video_decoder.video_length) time_slider.set_current_value (video_decoder.position) end end set_slide_to (to: like slide_to) is -- set `slide_to' do slide_to := to end do_slide (set_slide: BOOLEAN; ev: EM_MOUSEBUTTON_EVENT) is -- mouse click on slider do if ev.is_left_button then if is_sliding and (video_decoder.is_playing or video_decoder.is_paused) then video_decoder.go_to_position (slide_to) end is_sliding := set_slide end end feature {NONE} -- intern container: EM_ZOOMABLE_CONTAINER video_decoder: EM_VIDEO_DECODER progress_bar: EM_PROGRESS_BAR time_slider: EM_SLIDER play_pause_button, stop_button, open_button: EM_BUTTON play_bitmap, pause_bitmap, stop_bitmap, open_bitmap: EM_BITMAP feature {NONE} -- settings video_file_name: STRING is "output.mjpg" is_sliding: BOOLEAN slide_to: INTEGER end