diff --git a/Cargo.toml b/Cargo.toml index 7382cb0..c0759af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,7 @@ libvlc-sys = { path = "libvlc-sys" } [features] default = [] use-bindgen = ["libvlc-sys/use-bindgen"] + +[dev-dependencies] +raw-window-handle = "0.4.3" +winit = "0.26.1" diff --git a/examples/winit_player.rs b/examples/winit_player.rs new file mode 100644 index 0000000..478c915 --- /dev/null +++ b/examples/winit_player.rs @@ -0,0 +1,111 @@ +use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; +use vlc::{self, EventType, Instance, Media, MediaPlayer, State}; +use winit::{ + event::{ElementState, VirtualKeyCode, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::{Fullscreen, WindowBuilder}, +}; + +#[derive(Debug)] +enum UserEvent { + MediaStopped, +} + +fn main() { + // Create window + let event_loop = EventLoop::<UserEvent>::with_user_event(); + + let window = WindowBuilder::new() + .with_title("vlc-rs sample") + .with_inner_size(winit::dpi::PhysicalSize::new(800u16, 600u16)) + .build(&event_loop) + .unwrap(); + + // Instanciate libvlc + let options = vec![String::from("-vv")]; + + let instance = Instance::with_args(Some(options)).unwrap(); + + let argv: Vec<String> = std::env::args().collect(); + + let md = Media::new_location(&instance, &argv[1]).unwrap(); + + let mdp = MediaPlayer::new(&instance).unwrap(); + + // Request libvlc to draw in the window + match window.raw_window_handle() { + RawWindowHandle::AppKit(handle) => { + mdp.set_nsobject(handle.ns_view); + } + RawWindowHandle::Xlib(handle) => { + mdp.set_xwindow(handle.window as u32); + } + RawWindowHandle::Win32(handle) => { + mdp.set_hwnd(handle.hwnd); + } + _ => { + panic!("Unknown Window handle type") + } + } + + // Link EventLoop and libvlc + let proxy = event_loop.create_proxy(); + + let em = md.event_manager(); + let _ = em.attach(EventType::MediaStateChanged, move |e, _| match e { + vlc::Event::MediaStateChanged(s) => { + println!("State : {:?}", s); + if s == State::Ended || s == State::Error || s == State::Stopped { + proxy.send_event(UserEvent::MediaStopped).unwrap(); + } + } + _ => (), + }); + + // Start + mdp.set_media(&md); + mdp.play().unwrap(); + + // Event loop + let mut fullscreen = false; + + event_loop.run(move |event, _, control_flow| { + *control_flow = ControlFlow::Wait; + + match event { + winit::event::Event::WindowEvent { + event: WindowEvent::CloseRequested, + window_id: _, + } => { + mdp.stop(); + } + winit::event::Event::UserEvent(UserEvent::MediaStopped) => { + *control_flow = ControlFlow::Exit; + } + winit::event::Event::WindowEvent { + event: WindowEvent::KeyboardInput { input, .. }, + .. + } => { + if input.state != ElementState::Pressed { + return; + } + + match input.virtual_keycode { + Some(VirtualKeyCode::F) => { + let next_fullscreen_mode = if fullscreen { + None + } else { + Some(Fullscreen::Borderless(None)) + }; + + window.set_fullscreen(next_fullscreen_mode); + + fullscreen = !fullscreen; + } + _ => {} + } + } + _ => {} + } + }); +}