1use std::ptr::null;
6use std::borrow::Cow;
7use std::marker::PhantomData;
8use sys;
9use ::tools::{to_cstr, from_cstr, from_cstr_ref};
10use ::libc::{c_void, c_char, c_int};
11use ::enums::*;
12
13pub fn version() -> String {
15 unsafe{
16 from_cstr_ref(sys::libvlc_get_version()).unwrap().into_owned()
17 }
18}
19
20pub fn compiler() -> String {
22 unsafe{
23 from_cstr_ref(sys::libvlc_get_compiler()).unwrap().into_owned()
24 }
25}
26
27pub struct Instance {
28 pub(crate) ptr: *mut sys::libvlc_instance_t,
29}
30
31impl Instance {
32 pub fn new() -> Option<Instance> {
34 unsafe{
35 let p = sys::libvlc_new(0, null());
36
37 if p.is_null() {
38 return None;
39 }
40
41 Some(Instance{ptr: p})
42 }
43 }
44
45 pub fn add_intf(&self, name: &str) -> Result<(), ()> {
47 let cstr = to_cstr(name);
48
49 let result = unsafe{
50 sys::libvlc_add_intf(self.ptr, cstr.as_ptr())
51 };
52
53 if result == 0 { Ok(()) }
54 else { Err(()) }
55 }
56
57 pub fn set_user_agent(&self, name: &str, http: &str) {
60 unsafe{
61 sys::libvlc_set_user_agent(
62 self.ptr, to_cstr(name).as_ptr(), to_cstr(http).as_ptr());
63 }
64 }
65
66 pub fn wait(&self) {
68 unsafe{ sys::libvlc_wait(self.ptr) };
69 }
70
71 pub fn set_app_id(&self, id: &str, version: &str, icon: &str) {
73 unsafe{
74 sys::libvlc_set_app_id(
75 self.ptr, to_cstr(id).as_ptr(), to_cstr(version).as_ptr(), to_cstr(icon).as_ptr());
76 }
77 }
78
79 pub fn audio_filter_list_get(&self) -> Option<ModuleDescriptionList> {
81 unsafe{
82 let p = sys::libvlc_audio_filter_list_get(self.ptr);
83 if p.is_null() { None }
84 else { Some(ModuleDescriptionList{ptr: p}) }
85 }
86 }
87
88 pub fn video_filter_list_get(&self) -> Option<ModuleDescriptionList> {
90 unsafe{
91 let p = sys::libvlc_video_filter_list_get(self.ptr);
92 if p.is_null() { None }
93 else { Some(ModuleDescriptionList{ptr: p}) }
94 }
95 }
96
97 pub fn set_log<F: Fn(LogLevel, Log, Cow<str>) + Send + 'static>(&self, f: F) {
99 let cb: Box<Box<Fn(LogLevel, Log, Cow<str>) + Send + 'static>> = Box::new(Box::new(f));
100
101 unsafe{
102 sys::libvlc_log_set(self.ptr, logging_cb, Box::into_raw(cb) as *mut _);
103 }
104 }
105
106 pub fn raw(&self) -> *mut sys::libvlc_instance_t {
108 self.ptr
109 }
110}
111
112impl Drop for Instance {
113 fn drop(&mut self) {
114 unsafe{
115 sys::libvlc_release(self.ptr);
116 }
117 }
118}
119
120extern "C" {
121 fn vsnprintf(s: *mut c_char, n: usize, fmt: *const c_char, arg: sys::va_list);
122}
123const BUF_SIZE: usize = 1024; unsafe extern "C" fn logging_cb(
125 data: *mut c_void, level: c_int, ctx: *const sys::libvlc_log_t, fmt: *const c_char, args: sys::va_list) {
126
127 let f: &Box<Fn(LogLevel, Log, Cow<str>) + Send + 'static> = ::std::mem::transmute(data);
128 let mut buf: [c_char; BUF_SIZE] = [0; BUF_SIZE];
129
130 vsnprintf(buf.as_mut_ptr(), BUF_SIZE, fmt, args);
131
132 f(::std::mem::transmute(level), Log{ptr: ctx}, from_cstr_ref(buf.as_ptr()).unwrap());
133}
134
135pub struct ModuleDescriptionList {
137 ptr: *mut sys::libvlc_module_description_t,
138}
139
140impl ModuleDescriptionList {
141 pub fn raw(&self) -> *mut sys::libvlc_module_description_t {
143 self.ptr
144 }
145}
146
147impl Drop for ModuleDescriptionList {
148 fn drop(&mut self) {
149 unsafe{ sys::libvlc_module_description_list_release(self.ptr) };
150 }
151}
152
153impl<'a> IntoIterator for &'a ModuleDescriptionList {
154 type Item = ModuleDescriptionRef<'a>;
155 type IntoIter = ModuleDescriptionListIter<'a>;
156
157 fn into_iter(self) -> Self::IntoIter {
158 ModuleDescriptionListIter{ptr: self.ptr, _phantomdata: PhantomData}
159 }
160}
161
162pub struct ModuleDescriptionListIter<'a> {
163 ptr: *mut sys::libvlc_module_description_t,
164 _phantomdata: PhantomData<&'a sys::libvlc_module_description_t>,
165}
166
167#[derive(Clone, PartialEq, Eq, Hash, Debug)]
170pub struct ModuleDescription {
171 pub name: Option<String>,
172 pub shortname: Option<String>,
173 pub longname: Option<String>,
174 pub help: Option<String>,
175}
176
177#[derive(Clone, PartialEq, Eq, Hash, Debug)]
179pub struct ModuleDescriptionRef<'a> {
180 pub name: Option<Cow<'a, str>>,
181 pub shortname: Option<Cow<'a, str>>,
182 pub longname: Option<Cow<'a, str>>,
183 pub help: Option<Cow<'a, str>>,
184}
185
186impl<'a> Iterator for ModuleDescriptionListIter<'a> {
187 type Item = ModuleDescriptionRef<'a>;
188
189 fn next(&mut self) -> Option<Self::Item> {
190 unsafe{
191 if self.ptr.is_null() {
192 return None;
193 }
194 let p = self.ptr;
195 self.ptr = (*p).p_next;
196 Some(ModuleDescriptionRef{
197 name: from_cstr_ref((*p).psz_name),
198 shortname: from_cstr_ref((*p).psz_shortname),
199 longname: from_cstr_ref((*p).psz_longname),
200 help: from_cstr_ref((*p).psz_help),
201 })
202 }
203 }
204}
205
206impl<'a> ModuleDescriptionRef<'a> {
207 pub fn into_owned(&'a self) -> ModuleDescription {
209 ModuleDescription {
210 name: self.name .as_ref().map(|s| s.clone().into_owned()),
211 shortname: self.shortname.as_ref().map(|s| s.clone().into_owned()),
212 longname: self.name .as_ref().map(|s| s.clone().into_owned()),
213 help: self.shortname.as_ref().map(|s| s.clone().into_owned()),
214 }
215 }
216}
217
218pub fn errmsg() -> Option<String> {
219 unsafe{ from_cstr(sys::libvlc_errmsg()) }
220}
221
222pub fn clearerr() {
223 unsafe{ sys::libvlc_clearerr() };
224}
225
226#[derive(Clone, Debug)]
227pub enum Event {
228 MediaMetaChanged(Meta),
229 MediaSubItemAdded,
230 MediaDurationChanged(i64),
231 MediaParsedChanged(i32),
232 MediaFreed,
233 MediaStateChanged(State),
234 MediaSubItemTreeAdded,
235
236 MediaPlayerMediaChanged,
237 MediaPlayerNothingSpecial,
238 MediaPlayerOpening,
239 MediaPlayerBuffering(f32),
240 MediaPlayerPlaying,
241 MediaPlayerPaused,
242 MediaPlayerStopped,
243 MediaPlayerForward,
244 MediaPlayerBackward,
245 MediaPlayerEndReached,
246 MediaPlayerEncounteredError,
247 MediaPlayerTimeChanged,
248 MediaPlayerPositionChanged(f32),
249 MediaPlayerSeekableChanged,
250 MediaPlayerPausableChanged,
251 MediaPlayerTitleChanged,
252 MediaPlayerSnapshotTaken,
253 MediaPlayerLengthChanged,
254 MediaPlayerVout,
255 MediaPlayerScrambledChanged,
256
257 MediaListItemAdded,
258 MediaListWillAddItem,
259 MediaListItemDeleted,
260 MediaListWillDeleteItem,
261
262 MediaListViewItemAdded,
263 MediaListViewWillAddItem,
264 MediaListViewItemDeleted,
265 MediaListViewWillDeleteItem,
266
267 MediaListPlayerPlayed,
268 MediaListPlayerNextItemSet,
269 MediaListPlayerStopped,
270
271 MediaDiscovererStarted,
272 MediaDiscovererEnded,
273
274 VlmMediaAdded,
275 VlmMediaRemoved,
276 VlmMediaChanged,
277 VlmMediaInstanceStarted,
278 VlmMediaInstanceStopped,
279 VlmMediaInstanceStatusInit,
280 VlmMediaInstanceStatusOpening,
281 VlmMediaInstanceStatusPlaying,
282 VlmMediaInstanceStatusPause,
283 VlmMediaInstanceStatusEnd,
284 VlmMediaInstanceStatusError
285}
286
287pub struct EventManager<'a> {
288 pub(crate) ptr: *mut sys::libvlc_event_manager_t,
289 pub(crate) _phantomdata: ::std::marker::PhantomData<&'a sys::libvlc_event_manager_t>,
290}
291
292impl<'a> EventManager<'a> {
293 pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<(), ()>
294 where F: Fn(Event, VLCObject) + Send + 'static
295 {
296 let callback: Box<Box<Fn(Event, VLCObject) + Send + 'static>> =
298 Box::new(Box::new(callback));
299
300 let result = unsafe{
301 sys::libvlc_event_attach(
302 self.ptr, event_type as i32, event_manager_callback,
303 Box::into_raw(callback) as *mut c_void)
304 };
305
306 if result == 0 {
307 Ok(())
308 }else{
309 Err(())
310 }
311 }
312
313 pub fn raw(&self) -> *mut sys::libvlc_event_manager_t {
315 self.ptr
316 }
317}
318
319unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data: *mut c_void) {
320 let f: &Box<Fn(Event, VLCObject) + Send + 'static> = ::std::mem::transmute(data);
321
322 f(conv_event(pe), VLCObject{ ptr: (*pe).p_obj });
323}
324
325fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
327 let event_type: EventType = unsafe{ ::std::mem::transmute((*pe)._type) };
328
329 match event_type {
330 EventType::MediaMetaChanged => {
331 unsafe{
332 Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type)
333 }
334 },
335 EventType::MediaSubItemAdded => {
336 Event::MediaSubItemAdded
337 },
338 EventType::MediaDurationChanged => {
339 unsafe{
340 Event::MediaDurationChanged((*pe).u.media_duration_changed.new_duration)
341 }
342 },
343 EventType::MediaParsedChanged => {
344 unsafe{
345 Event::MediaParsedChanged((*pe).u.media_parsed_changed.new_status)
346 }
347 },
348 EventType::MediaFreed => {
349 Event::MediaFreed
350 },
351 EventType::MediaStateChanged => {
352 unsafe{
353 Event::MediaStateChanged((*pe).u.media_state_changed.new_state)
354 }
355 },
356 EventType::MediaSubItemTreeAdded => {
357 Event::MediaSubItemTreeAdded
358 },
359 EventType::MediaPlayerMediaChanged => {
360 Event::MediaPlayerMediaChanged
361 },
362 EventType::MediaPlayerNothingSpecial => {
363 Event::MediaPlayerNothingSpecial
364 },
365 EventType::MediaPlayerOpening => {
366 Event::MediaPlayerOpening
367 },
368 EventType::MediaPlayerBuffering => {
369 unsafe{
370 Event::MediaPlayerBuffering((*pe).u.media_player_buffering.new_cache)
371 }
372 },
373 EventType::MediaPlayerPlaying => {
374 Event::MediaPlayerPlaying
375 },
376 EventType::MediaPlayerPaused => {
377 Event::MediaPlayerPaused
378 },
379 EventType::MediaPlayerStopped => {
380 Event::MediaPlayerStopped
381 },
382 EventType::MediaPlayerForward => {
383 Event::MediaPlayerForward
384 },
385 EventType::MediaPlayerBackward => {
386 Event::MediaPlayerBackward
387 },
388 EventType::MediaPlayerEndReached => {
389 Event::MediaPlayerEndReached
390 },
391 EventType::MediaPlayerEncounteredError => {
392 Event::MediaPlayerEncounteredError
393 },
394 EventType::MediaPlayerTimeChanged => {
395 Event::MediaPlayerTimeChanged
396 },
397 EventType::MediaPlayerPositionChanged => {
398 unsafe{
399 Event::MediaPlayerPositionChanged((*pe).u.media_player_position_changed.new_position)
400 }
401 },
402 EventType::MediaPlayerSeekableChanged => {
403 Event::MediaPlayerSeekableChanged
404 },
405 EventType::MediaPlayerPausableChanged => {
406 Event::MediaPlayerPausableChanged
407 },
408 EventType::MediaPlayerTitleChanged => {
409 Event::MediaPlayerTitleChanged
410 },
411 EventType::MediaPlayerSnapshotTaken => {
412 Event::MediaPlayerSnapshotTaken
413 },
414 EventType::MediaPlayerLengthChanged => {
415 Event::MediaPlayerLengthChanged
416 },
417 EventType::MediaPlayerVout => {
418 Event::MediaPlayerVout
419 },
420 EventType::MediaPlayerScrambledChanged => {
421 Event::MediaPlayerScrambledChanged
422 },
423 EventType::MediaListItemAdded => {
424 Event::MediaListItemAdded
425 },
426 EventType::MediaListWillAddItem => {
427 Event::MediaListWillAddItem
428 },
429 EventType::MediaListItemDeleted => {
430 Event::MediaListItemDeleted
431 },
432 EventType::MediaListWillDeleteItem => {
433 Event::MediaListWillDeleteItem
434 },
435 EventType::MediaListViewItemAdded => {
436 Event::MediaListViewItemAdded
437 },
438 EventType::MediaListViewWillAddItem => {
439 Event::MediaListViewWillAddItem
440 },
441 EventType::MediaListViewItemDeleted => {
442 Event::MediaListViewItemDeleted
443 },
444 EventType::MediaListViewWillDeleteItem => {
445 Event::MediaListViewWillDeleteItem
446 },
447 EventType::MediaListPlayerPlayed => {
448 Event::MediaListPlayerPlayed
449 },
450 EventType::MediaListPlayerNextItemSet => {
451 Event::MediaListPlayerNextItemSet
452 },
453 EventType::MediaListPlayerStopped => {
454 Event::MediaListPlayerStopped
455 },
456 EventType::MediaDiscovererStarted => {
457 Event::MediaDiscovererStarted
458 },
459 EventType::MediaDiscovererEnded => {
460 Event::MediaDiscovererEnded
461 },
462 EventType::VlmMediaAdded => {
463 Event::VlmMediaAdded
464 },
465 EventType::VlmMediaRemoved => {
466 Event::VlmMediaRemoved
467 },
468 EventType::VlmMediaChanged => {
469 Event::VlmMediaChanged
470 },
471 EventType::VlmMediaInstanceStarted => {
472 Event::VlmMediaInstanceStarted
473 },
474 EventType::VlmMediaInstanceStopped => {
475 Event::VlmMediaInstanceStopped
476 },
477 EventType::VlmMediaInstanceStatusInit => {
478 Event::VlmMediaInstanceStatusInit
479 },
480 EventType::VlmMediaInstanceStatusOpening => {
481 Event::VlmMediaInstanceStatusOpening
482 },
483 EventType::VlmMediaInstanceStatusPlaying => {
484 Event::VlmMediaInstanceStatusPlaying
485 },
486 EventType::VlmMediaInstanceStatusPause => {
487 Event::VlmMediaInstanceStatusPause
488 },
489 EventType::VlmMediaInstanceStatusEnd => {
490 Event::VlmMediaInstanceStatusEnd
491 },
492 EventType::VlmMediaInstanceStatusError => {
493 Event::VlmMediaInstanceStatusError
494 },
495 }
496}
497
498pub struct VLCObject {
499 ptr: *mut c_void,
500}
501
502impl VLCObject {
503 pub fn raw(&self) -> *mut c_void {
505 self.ptr
506 }
507}
508
509pub struct Log {
510 pub(crate) ptr: *const sys::libvlc_log_t
511}
512
513impl Log {
514 pub fn raw(&self) -> *const sys::libvlc_log_t {
516 self.ptr
517 }
518}
519