extern crate mpv ;
extern crate sdl2;
extern crate sdl2_sys;
#[macro_use]
extern crate log;
use std::env;
use std::path::Path;
use std::os::raw::{c_void,c_char};
use std::ffi::CStr;
use sdl2::event::Event as SdlEvent;
use sdl2::keyboard::Keycode;
unsafe extern "C" fn get_proc_address(arg: *mut c_void,
name: *const c_char) -> *mut c_void {
let arg: &sdl2::VideoSubsystem = &*(arg as *mut sdl2::VideoSubsystem);
let name = CStr::from_ptr(name).to_str().unwrap();
arg.gl_get_proc_address(name) as *mut c_void
}
fn sdl_example(video_path: &Path) {
let mut opengl_driver : Option<i32> = None ;
info!("Detecting drivers ...");
let mut driver_index = -1 ;
for item in sdl2::render::drivers() {
driver_index = driver_index + 1 ;
info!("* Found driver '{}'",item.name);
if item.name == "opengl"{
opengl_driver = Some(driver_index);
}
}
if let Some(opengl_driver) = opengl_driver {
let opengl_driver = opengl_driver as u32;
let sdl_context = sdl2::init().unwrap();
let mut video_subsystem = sdl_context.video().unwrap();
let window = video_subsystem.window("MPV-RS SDL2 EXAMPLE", 960, 540)
.resizable()
.position_centered()
.opengl()
.build()
.unwrap();
let renderer = window.renderer()
.present_vsync()
.index(opengl_driver)
.build()
.expect("Failed to create renderer with given parameters");
renderer.window()
.expect("Failed to extract window from displayer")
.gl_set_context_to_current()
.unwrap();
let ptr = &mut video_subsystem as *mut _ as *mut c_void;
let mut mpv_builder = mpv::MpvHandlerBuilder::new().expect("Error while creating MPV builder");
mpv_builder.try_hardware_decoding();
let mut mpv : Box<mpv::MpvHandlerWithGl> = mpv_builder.build_with_gl(Some(get_proc_address), ptr).expect("Error while initializing MPV with opengl");
mpv.observe_property::<bool>("pause",5).unwrap();
let video_path = video_path.to_str().expect("Expected a string for Path, got None");
mpv.command(&["loadfile", video_path as &str])
.expect("Error loading file");
let mut event_pump = sdl_context.event_pump().expect("Failed to create event_pump");
'main: loop {
for event in event_pump.poll_iter() {
match event {
SdlEvent::Quit {..} | SdlEvent::KeyDown { keycode: Some(Keycode::Escape), .. } => {
break 'main
},
SdlEvent::KeyDown { keycode: Some(Keycode::Space),repeat: false, .. } => {
match mpv.get_property("pause").unwrap() {
true => {mpv.set_property_async("pause",false,1).expect("Failed to pause player");},
false => {mpv.set_property_async("pause",true,1).expect("Failed to unpause player");}
}
},
SdlEvent::KeyDown { keycode: Some(Keycode::O),repeat: false, .. } => {
mpv.get_property_async::<&str>("speed",5).unwrap();
},
_ => {}
}
}
while let Some(event) = mpv.wait_event(0.0) {
println!("RECEIVED EVENT : {:?}", event);
match event {
mpv::Event::Shutdown | mpv::Event::EndFile(_) => {
break 'main;
}
_ => {}
};
}
let (width, height) = renderer.window().unwrap().size();
mpv.draw(0, width as i32, -(height as i32)).expect("Failed to draw on SDL2 window");
renderer.window().unwrap().gl_swap_window();
}
}else{
error!("OpenGL driver not found, aborting");
}
}
fn main() {
let args: Vec<_> = env::args().collect();
if args.len() < 2 {
println!("Usage: ./sdl [any mp4, avi, mkv, ... file]");
} else {
let path: &Path = Path::new(&args[1]);
if path.is_file() {
sdl_example(path);
} else {
println!("A file is required; {} is not a valid file",
path.to_str().unwrap());
}
}
}