Add winit integration example
parent
90729e2bd4
commit
34d69083e8
File diff suppressed because it is too large
Load Diff
|
|
@ -26,3 +26,7 @@ libvlc-sys = { path = "libvlc-sys" }
|
|||
# builds never compile it.
|
||||
[workspace]
|
||||
exclude = ["xtask"]
|
||||
|
||||
[dev-dependencies]
|
||||
raw-window-handle = "0.6"
|
||||
winit = { version = "0.30", default-features = false, features = ["x11", "rwh_06"] }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,152 @@
|
|||
use raw_window_handle::{HasWindowHandle, RawWindowHandle};
|
||||
use vlc::{self, EventType, Instance, Media, MediaPlayer, State};
|
||||
use winit::{
|
||||
application::ApplicationHandler,
|
||||
event::{ElementState, WindowEvent},
|
||||
event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy},
|
||||
keyboard::{Key, NamedKey},
|
||||
window::{Fullscreen, Window, WindowId},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum UserEvent {
|
||||
MediaStopped,
|
||||
}
|
||||
|
||||
struct App {
|
||||
md: Media,
|
||||
mdp: MediaPlayer,
|
||||
proxy: EventLoopProxy<UserEvent>,
|
||||
window: Option<Window>,
|
||||
fullscreen: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn new(md: Media, mdp: MediaPlayer, proxy: EventLoopProxy<UserEvent>) -> Self {
|
||||
Self {
|
||||
md,
|
||||
mdp,
|
||||
proxy,
|
||||
window: None,
|
||||
fullscreen: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ApplicationHandler<UserEvent> for App {
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
if self.window.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create window
|
||||
let window_attributes = Window::default_attributes()
|
||||
.with_title("vlc-rs sample")
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(800u16, 600u16));
|
||||
let window = event_loop.create_window(window_attributes).unwrap();
|
||||
|
||||
// Request libvlc to draw in the window
|
||||
let handle = window.window_handle().unwrap();
|
||||
match handle.as_raw() {
|
||||
RawWindowHandle::AppKit(handle) => {
|
||||
self.mdp.set_nsobject(handle.ns_view.as_ptr());
|
||||
}
|
||||
RawWindowHandle::Xlib(handle) => {
|
||||
self.mdp.set_xwindow(handle.window as u32);
|
||||
}
|
||||
RawWindowHandle::Win32(handle) => {
|
||||
self.mdp.set_hwnd(isize::from(handle.hwnd) as *mut _);
|
||||
}
|
||||
_ => {
|
||||
panic!("Unknown Window handle type")
|
||||
}
|
||||
}
|
||||
|
||||
// Link EventLoop and libvlc
|
||||
let proxy = self.proxy.clone();
|
||||
let em = self.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
|
||||
self.mdp.set_media(&self.md);
|
||||
self.mdp.play().unwrap();
|
||||
|
||||
self.window = Some(window);
|
||||
}
|
||||
|
||||
fn user_event(&mut self, event_loop: &ActiveEventLoop, event: UserEvent) {
|
||||
match event {
|
||||
UserEvent::MediaStopped => event_loop.exit(),
|
||||
}
|
||||
}
|
||||
|
||||
fn window_event(
|
||||
&mut self,
|
||||
_event_loop: &ActiveEventLoop,
|
||||
_window_id: WindowId,
|
||||
event: WindowEvent,
|
||||
) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => {
|
||||
self.mdp.stop();
|
||||
}
|
||||
WindowEvent::KeyboardInput { event, .. } => {
|
||||
if event.state != ElementState::Pressed {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Key::Character(ref c) = event.logical_key {
|
||||
if c.as_str() == "f" || c.as_str() == "F" {
|
||||
let next_fullscreen_mode = if self.fullscreen {
|
||||
None
|
||||
} else {
|
||||
Some(Fullscreen::Borderless(None))
|
||||
};
|
||||
|
||||
if let Some(window) = &self.window {
|
||||
window.set_fullscreen(next_fullscreen_mode);
|
||||
}
|
||||
|
||||
self.fullscreen = !self.fullscreen;
|
||||
}
|
||||
} else if event.logical_key == Key::Named(NamedKey::Escape) && self.fullscreen {
|
||||
if let Some(window) = &self.window {
|
||||
window.set_fullscreen(None);
|
||||
}
|
||||
self.fullscreen = false;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let path = match args.get(1) {
|
||||
Some(s) => s.clone(),
|
||||
None => {
|
||||
println!("Usage: winit_player path_to_a_media_file");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// Instanciate libvlc
|
||||
let instance = Instance::new().unwrap();
|
||||
let md = Media::new_path(&instance, &path).unwrap();
|
||||
let mdp = MediaPlayer::new(&instance).unwrap();
|
||||
|
||||
let event_loop = EventLoop::<UserEvent>::with_user_event().build().unwrap();
|
||||
let proxy = event_loop.create_proxy();
|
||||
|
||||
let mut app = App::new(md, mdp, proxy);
|
||||
event_loop.run_app(&mut app).unwrap();
|
||||
}
|
||||
Loading…
Reference in New Issue