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;
+                    }
+                    _ => {}
+                }
+            }
+            _ => {}
+        }
+    });
+}