1use sys;
6use ::Instance;
7use ::Media;
8use ::EventManager;
9use ::libc::{c_void, c_uint};
10use ::enums::{State, Position};
11use std::mem::transmute;
12
13pub struct MediaPlayer {
15 pub(crate) ptr: *mut sys::libvlc_media_player_t,
16}
17
18impl MediaPlayer {
19 pub fn new(instance: &Instance) -> Option<MediaPlayer> {
21 unsafe{
22 let p = sys::libvlc_media_player_new(instance.ptr);
23
24 if p.is_null() {
25 return None;
26 }
27 Some(MediaPlayer{ptr: p})
28 }
29 }
30
31 pub fn set_media(&self, md: &Media) {
33 unsafe{ sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
34 }
35
36 pub fn get_media(&self) -> Option<Media> {
38 let p = unsafe{ sys::libvlc_media_player_get_media(self.ptr) };
39 if p.is_null() {
40 None
41 }else{
42 Some(Media{ptr: p})
43 }
44 }
45
46 pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
48 unsafe{
49 let p = sys::libvlc_media_player_event_manager(self.ptr);
50 assert!(!p.is_null());
51 EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
52 }
53 }
54
55 pub fn is_playing(&self) -> bool {
57 if unsafe{ sys::libvlc_media_player_is_playing(self.ptr) } == 0 {
58 false
59 }else{
60 true
61 }
62 }
63
64 pub fn play(&self) -> Result<(), ()> {
66 if unsafe{ sys::libvlc_media_player_play(self.ptr) } == 0 {
67 Ok(())
68 }else{
69 Err(())
70 }
71 }
72
73 pub fn set_pause(&self, do_pause: bool) {
75 unsafe{ sys::libvlc_media_player_set_pause(self.ptr, if do_pause {1} else {0}) };
76 }
77
78 pub fn pause(&self) {
80 unsafe{ sys::libvlc_media_player_pause(self.ptr) };
81 }
82
83 pub fn stop(&self) {
85 unsafe{ sys::libvlc_media_player_stop(self.ptr) };
86 }
87
88 pub fn set_callbacks<F>(
89 &self,
90 play: F,
91 pause: Option<Box<Fn(i64) + Send + 'static>>,
92 resume: Option<Box<Fn(i64) + Send + 'static>>,
93 flush: Option<Box<Fn(i64) + Send + 'static>>,
94 drain: Option<Box<Fn() + Send + 'static>>)
95 where F: Fn(*const c_void, u32, i64) + Send + 'static,
96 {
97 let flag_pause = pause.is_some();
98 let flag_resume = resume.is_some();
99 let flag_flush = flush.is_some();
100 let flag_drain = drain.is_some();
101
102 let data = AudioCallbacksData {
103 play: Box::new(play), pause: pause, resume: resume,
104 flush: flush, drain: drain,
105 };
106 let data = Box::into_raw(Box::new(data));
107
108 unsafe{
109 sys::libvlc_audio_set_callbacks(
110 self.ptr,
111 Some(audio_cb_play),
112 if flag_pause {Some(audio_cb_pause)} else {None},
113 if flag_resume {Some(audio_cb_resume)} else {None},
114 if flag_flush {Some(audio_cb_flush)} else {None},
115 if flag_drain {Some(audio_cb_drain)} else {None},
116 data as *mut c_void);
117 }
118 }
119
120 pub fn set_nsobject(&self, drawable: *mut c_void) {
122 unsafe{ sys::libvlc_media_player_set_nsobject(self.ptr, drawable) };
123 }
124
125 pub fn get_nsobject(&self) -> Option<*mut c_void> {
127 let nso = unsafe{ sys::libvlc_media_player_get_nsobject(self.ptr) };
128 if nso.is_null() { None }else{ Some(nso) }
129 }
130
131 pub fn set_xwindow(&self, drawable: u32) {
133 unsafe{ sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
134 }
135
136 pub fn get_xwindow(&self) -> Option<u32> {
138 let id = unsafe{ sys::libvlc_media_player_get_xwindow(self.ptr) };
139 if id == 0 { None }else{ Some(id) }
140 }
141
142 pub fn set_hwnd(&self, drawable: *mut c_void) {
145 unsafe{ sys::libvlc_media_player_set_hwnd(self.ptr, drawable) };
146 }
147
148 pub fn get_hwnd(&self) -> Option<*mut c_void> {
150 let hwnd = unsafe{ sys::libvlc_media_player_get_hwnd(self.ptr) };
151 if hwnd.is_null() { None }else{ Some(hwnd) }
152 }
153
154 pub fn get_time(&self) -> Option<i64> {
156 unsafe{
157 let t = sys::libvlc_media_player_get_time(self.ptr);
158 if t == -1 { None }else{ Some(t) }
159 }
160 }
161
162 pub fn set_time(&self, time: i64) {
165 unsafe{ sys::libvlc_media_player_set_time(self.ptr, time); }
166 }
167
168 pub fn get_position(&self) -> Option<f32> {
170 unsafe{
171 let pos = sys::libvlc_media_player_get_position(self.ptr);
172 if pos == -1f32 { None }else{ Some(pos) }
173 }
174 }
175
176 pub fn set_position(&self, pos: f32) {
179 unsafe{ sys::libvlc_media_player_set_position(self.ptr, pos); }
180 }
181
182 pub fn set_chapter(&self, chapter: i32) {
184 unsafe{ sys::libvlc_media_player_set_chapter(self.ptr, chapter); }
185 }
186
187 pub fn get_chapter(&self) -> Option<i32> {
189 unsafe{
190 let c = sys::libvlc_media_player_get_chapter(self.ptr);
191 if c == -1 { None }else{ Some(c) }
192 }
193 }
194
195 pub fn chapter_count(&self) -> Option<i32> {
197 unsafe{
198 let c = sys::libvlc_media_player_get_chapter_count(self.ptr);
199 if c == -1 { None }else{ Some(c) }
200 }
201 }
202
203 pub fn will_play(&self) -> bool {
205 unsafe{
206 let b = sys::libvlc_media_player_will_play(self.ptr);
207 if b == 0 { false }else{ true }
208 }
209 }
210
211 pub fn chapter_count_for_title(&self, title: i32) -> Option<i32> {
213 unsafe{
214 let c = sys::libvlc_media_player_get_chapter_count_for_title(self.ptr, title);
215 if c == -1 { None }else{ Some(c) }
216 }
217 }
218
219 pub fn set_title(&self, title: i32) {
221 unsafe{ sys::libvlc_media_player_set_title(self.ptr, title); }
222 }
223
224 pub fn get_title(&self) -> Option<i32> {
226 unsafe{
227 let t = sys::libvlc_media_player_get_title(self.ptr);
228 if t == -1 { None }else{ Some(t) }
229 }
230 }
231
232 pub fn title_count(&self) -> Option<i32> {
234 unsafe{
235 let t = sys::libvlc_media_player_get_title_count(self.ptr);
236 if t == -1 { Some(t) } else { None }
237 }
238 }
239
240 pub fn previous_chapter(&self) {
242 unsafe{ sys::libvlc_media_player_previous_chapter(self.ptr); }
243 }
244
245 pub fn next_chapter(&self) {
247 unsafe{ sys::libvlc_media_player_next_chapter(self.ptr); }
248 }
249
250 pub fn get_rate(&self) -> f32 {
252 unsafe{ sys::libvlc_media_player_get_rate(self.ptr) }
253 }
254
255 pub fn set_rate(&self, rate: f32) -> Result<(),()> {
257 unsafe{
258 if sys::libvlc_media_player_set_rate(self.ptr, rate) == -1 {
259 Err(())
260 }else{
261 Ok(())
262 }
263 }
264 }
265
266 pub fn state(&self) -> State {
268 unsafe{ sys::libvlc_media_player_get_state(self.ptr) }
269 }
270
271 pub fn has_vout(&self) -> u32 {
273 unsafe{ sys::libvlc_media_player_has_vout(self.ptr) }
274 }
275
276 pub fn is_seekable(&self) -> bool {
278 unsafe{
279 let b = sys::libvlc_media_player_is_seekable(self.ptr);
280 if b == 0 { false }else{ true }
281 }
282 }
283
284 pub fn can_pause(&self) -> bool {
286 unsafe{
287 let b = sys::libvlc_media_player_can_pause(self.ptr);
288 if b == 0 { false }else{ true }
289 }
290 }
291
292 pub fn program_scrambled(&self) -> bool {
294 unsafe{
295 let b = sys::libvlc_media_player_program_scrambled(self.ptr);
296 if b == 0 { false }else{ true }
297 }
298 }
299
300 pub fn next_frame(&self) {
302 unsafe{ sys::libvlc_media_player_next_frame(self.ptr); }
303 }
304
305 pub fn navigate(&self, navigate: u32) {
307 unsafe{ sys::libvlc_media_player_navigate(self.ptr, navigate); }
308 }
309
310 pub fn set_video_title_display(&self, position: Position, timeout: u32) {
312 unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position, timeout); }
313 }
314
315 pub fn raw(&self) -> *mut sys::libvlc_media_player_t {
317 self.ptr
318 }
319}
320
321impl Drop for MediaPlayer {
322 fn drop(&mut self) {
323 unsafe{ sys::libvlc_media_player_release(self.ptr) };
324 }
325}
326
327struct AudioCallbacksData {
329 play: Box<Fn(*const c_void, u32, i64) + Send + 'static>,
330 pause: Option<Box<Fn(i64) + Send + 'static>>,
331 resume: Option<Box<Fn(i64) + Send + 'static>>,
332 flush: Option<Box<Fn(i64) + Send + 'static>>,
333 drain: Option<Box<Fn() + Send + 'static>>,
334}
335
336unsafe extern "C" fn audio_cb_play(
337 data: *mut c_void, samples: *const c_void, count: c_uint, pts: i64) {
338 let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
339 (data.play)(samples, count, pts);
340
341}
342
343unsafe extern "C" fn audio_cb_pause(data: *mut c_void, pts: i64) {
344 let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
345 (data.pause.as_ref().unwrap())(pts);
346}
347
348unsafe extern "C" fn audio_cb_resume(data: *mut c_void, pts: i64) {
349 let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
350 (data.resume.as_ref().unwrap())(pts);
351}
352
353unsafe extern "C" fn audio_cb_flush(data: *mut c_void, pts: i64) {
354 let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
355 (data.flush.as_ref().unwrap())(pts);
356}
357
358unsafe extern "C" fn audio_cb_drain(data: *mut c_void) {
359 let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
360 (data.drain.as_ref().unwrap())();
361}
362
363#[derive(Clone, PartialEq, Eq, Hash, Debug)]
364pub struct TrackDescription {
365 pub id: i32,
366 pub name: Option<String>,
367}
368