Fix most clippy errors and warnings, applied rustfmt
parent
f3534654d7
commit
1c04065056
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// This file is an example for vlc-rs, licensed under CC0.
|
// This file is an example for vlc-rs, licensed under CC0.
|
||||||
// https://creativecommons.org/publicdomain/zero/1.0/deed
|
// https://creativecommons.org/publicdomain/zero/1.0/deed
|
||||||
|
|
||||||
|
@ -6,7 +5,7 @@ extern crate vlc;
|
||||||
|
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
|
||||||
use vlc::{Instance, Media, MediaPlayer, Event, EventType, State};
|
use vlc::{Event, EventType, Instance, Media, MediaPlayer, State};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
|
@ -19,32 +18,28 @@ fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let instance = Instance::new().unwrap();
|
let instance = Instance::new().unwrap();
|
||||||
|
|
||||||
let md = Media::new_path(&instance, path).unwrap();
|
let md = Media::new_path(&instance, path).unwrap();
|
||||||
let mdp = MediaPlayer::new(&instance).unwrap();
|
let mdp = MediaPlayer::new(&instance).unwrap();
|
||||||
|
|
||||||
let (tx, rx) = channel::<()>();
|
let (tx, rx) = channel::<()>();
|
||||||
|
|
||||||
let em = md.event_manager();
|
let em = md.event_manager();
|
||||||
let _ = em.attach(EventType::MediaStateChanged, move |e, _| {
|
let _ = em.attach(EventType::MediaStateChanged, move |e, _| match e {
|
||||||
match e {
|
Event::MediaStateChanged(s) => {
|
||||||
Event::MediaStateChanged(s) => {
|
println!("State : {:?}", s);
|
||||||
println!("State : {:?}", s);
|
if s == State::Ended || s == State::Error {
|
||||||
if s == State::Ended || s == State::Error {
|
tx.send(()).unwrap();
|
||||||
tx.send(()).unwrap();
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
_ => (),
|
||||||
});
|
});
|
||||||
|
|
||||||
mdp.set_media(&md);
|
mdp.set_media(&md);
|
||||||
|
|
||||||
// Start playing
|
// Start playing
|
||||||
mdp.play().unwrap();
|
mdp.play().unwrap();
|
||||||
|
|
||||||
// Wait for end state
|
// Wait for end state
|
||||||
rx.recv().unwrap();
|
rx.recv().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
// This file is an example for vlc-rs, licensed under CC0.
|
// This file is an example for vlc-rs, licensed under CC0.
|
||||||
// https://creativecommons.org/publicdomain/zero/1.0/deed
|
// https://creativecommons.org/publicdomain/zero/1.0/deed
|
||||||
|
|
||||||
|
|
39
src/audio.rs
39
src/audio.rs
|
@ -2,58 +2,67 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
use vlc_sys as sys;
|
use crate::tools::from_cstr;
|
||||||
|
use crate::InternalError;
|
||||||
use crate::MediaPlayer;
|
use crate::MediaPlayer;
|
||||||
use crate::TrackDescription;
|
use crate::TrackDescription;
|
||||||
use crate::tools::from_cstr;
|
use vlc_sys as sys;
|
||||||
|
|
||||||
pub trait MediaPlayerAudioEx {
|
pub trait MediaPlayerAudioEx {
|
||||||
fn get_mute(&self) -> Option<bool>;
|
fn get_mute(&self) -> Option<bool>;
|
||||||
fn set_mute(&self, muted: bool);
|
fn set_mute(&self, muted: bool);
|
||||||
fn get_volume(&self) -> i32;
|
fn get_volume(&self) -> i32;
|
||||||
fn set_volume(&self, volume: i32) -> Result<(), ()>;
|
fn set_volume(&self, volume: i32) -> Result<(), InternalError>;
|
||||||
fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>>;
|
fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MediaPlayerAudioEx for MediaPlayer {
|
impl MediaPlayerAudioEx for MediaPlayer {
|
||||||
fn get_mute(&self) -> Option<bool> {
|
fn get_mute(&self) -> Option<bool> {
|
||||||
let r = unsafe{ sys::libvlc_audio_get_mute(self.ptr) };
|
let r = unsafe { sys::libvlc_audio_get_mute(self.ptr) };
|
||||||
|
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
Some(false)
|
Some(false)
|
||||||
}else if r == -1 {
|
} else if r == -1 {
|
||||||
None
|
None
|
||||||
}else{
|
} else {
|
||||||
Some(true)
|
Some(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_mute(&self, status: bool) {
|
fn set_mute(&self, status: bool) {
|
||||||
unsafe{ sys::libvlc_audio_set_mute(self.ptr, if status { 1 }else{ 0 }) };
|
unsafe { sys::libvlc_audio_set_mute(self.ptr, if status { 1 } else { 0 }) };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_volume(&self) -> i32 {
|
fn get_volume(&self) -> i32 {
|
||||||
unsafe{ sys::libvlc_audio_get_volume(self.ptr) }
|
unsafe { sys::libvlc_audio_get_volume(self.ptr) }
|
||||||
}
|
}
|
||||||
fn set_volume(&self, volume: i32) -> Result<(), ()> {
|
fn set_volume(&self, volume: i32) -> Result<(), InternalError> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if sys::libvlc_audio_set_volume(self.ptr, volume) == 0 { Ok(()) }else{ Err(()) }
|
if sys::libvlc_audio_set_volume(self.ptr, volume) == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>> {
|
fn get_audio_track_description(&self) -> Option<Vec<TrackDescription>> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p0 = sys::libvlc_audio_get_track_description(self.ptr);
|
let p0 = sys::libvlc_audio_get_track_description(self.ptr);
|
||||||
if p0.is_null() { return None; }
|
if p0.is_null() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let mut td = Vec::new();
|
let mut td = Vec::new();
|
||||||
let mut p = p0;
|
let mut p = p0;
|
||||||
|
|
||||||
while !(*p).p_next.is_null() {
|
while !(*p).p_next.is_null() {
|
||||||
td.push(TrackDescription{ id: (*p).i_id, name: from_cstr((*p).psz_name) });
|
td.push(TrackDescription {
|
||||||
|
id: (*p).i_id,
|
||||||
|
name: from_cstr((*p).psz_name),
|
||||||
|
});
|
||||||
p = (*p).p_next;
|
p = (*p).p_next;
|
||||||
}
|
}
|
||||||
sys::libvlc_track_description_list_release(p0);
|
sys::libvlc_track_description_list_release(p0);
|
||||||
Some(td)
|
Some(td)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
467
src/core.rs
467
src/core.rs
|
@ -2,34 +2,49 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
use std::ptr;
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::ffi::CString;
|
|
||||||
use std::i32;
|
|
||||||
use std::convert::TryInto;
|
|
||||||
use libc::{c_void, c_char, c_int};
|
|
||||||
use vlc_sys as sys;
|
|
||||||
use crate::tools::{to_cstr, from_cstr, from_cstr_ref};
|
|
||||||
use crate::enums::*;
|
use crate::enums::*;
|
||||||
|
use crate::tools::{from_cstr, from_cstr_ref, to_cstr};
|
||||||
|
use libc::{c_char, c_int, c_void};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use std::ffi::CString;
|
||||||
|
use std::fmt;
|
||||||
|
use std::i32;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::ptr;
|
||||||
|
use vlc_sys as sys;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct InternalError;
|
||||||
|
|
||||||
|
impl fmt::Display for InternalError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "libvlc internal error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for InternalError {}
|
||||||
|
|
||||||
/// Retrieve libvlc version.
|
/// Retrieve libvlc version.
|
||||||
pub fn version() -> String {
|
pub fn version() -> String {
|
||||||
unsafe{
|
unsafe {
|
||||||
from_cstr_ref(sys::libvlc_get_version()).unwrap().into_owned()
|
from_cstr_ref(sys::libvlc_get_version())
|
||||||
|
.unwrap()
|
||||||
|
.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieve libvlc compiler version.
|
/// Retrieve libvlc compiler version.
|
||||||
pub fn compiler() -> String {
|
pub fn compiler() -> String {
|
||||||
unsafe{
|
unsafe {
|
||||||
from_cstr_ref(sys::libvlc_get_compiler()).unwrap().into_owned()
|
from_cstr_ref(sys::libvlc_get_compiler())
|
||||||
|
.unwrap()
|
||||||
|
.into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
pub(crate) ptr: *mut sys::libvlc_instance_t,
|
pub(crate) ptr: *mut sys::libvlc_instance_t,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Instance {}
|
unsafe impl Send for Instance {}
|
||||||
|
@ -39,18 +54,19 @@ impl Instance {
|
||||||
/// Note: args.len() has to be less or equal to i32::MAX
|
/// Note: args.len() has to be less or equal to i32::MAX
|
||||||
/// Note: libvlc discourages using arguments as these are not guaranteed to be stable between different versions of libvlc
|
/// Note: libvlc discourages using arguments as these are not guaranteed to be stable between different versions of libvlc
|
||||||
pub fn with_args(args: Option<Vec<String>>) -> Option<Instance> {
|
pub fn with_args(args: Option<Vec<String>>) -> Option<Instance> {
|
||||||
let args_c_ptr: Vec<*const c_char> ;
|
let args_c_ptr: Vec<*const c_char>;
|
||||||
let args_c: Vec<CString>;
|
let args_c: Vec<CString>;
|
||||||
if let Some(argv) = args {
|
if let Some(argv) = args {
|
||||||
args_c = argv.into_iter()
|
args_c = argv
|
||||||
.map(|x| CString::new(x).expect("Error: Unexpected null byte")).collect();
|
.into_iter()
|
||||||
|
.map(|x| CString::new(x).expect("Error: Unexpected null byte"))
|
||||||
|
.collect();
|
||||||
args_c_ptr = args_c.iter().map(|x| x.as_ptr()).collect();
|
args_c_ptr = args_c.iter().map(|x| x.as_ptr()).collect();
|
||||||
} else {
|
} else {
|
||||||
args_c_ptr = Vec::new();
|
args_c_ptr = Vec::new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
unsafe{
|
|
||||||
let p = if args_c_ptr.is_empty() {
|
let p = if args_c_ptr.is_empty() {
|
||||||
sys::libvlc_new(0, ptr::null())
|
sys::libvlc_new(0, ptr::null())
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,7 +77,7 @@ impl Instance {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Instance{ptr: p})
|
Some(Instance { ptr: p })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,63 +87,76 @@ impl Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to start a user interface for the libvlc instance.
|
/// Try to start a user interface for the libvlc instance.
|
||||||
pub fn add_intf(&self, name: &str) -> Result<(), ()> {
|
pub fn add_intf(&self, name: &str) -> Result<(), InternalError> {
|
||||||
let cstr = to_cstr(name);
|
let cstr = to_cstr(name);
|
||||||
|
|
||||||
let result = unsafe{
|
let result = unsafe { sys::libvlc_add_intf(self.ptr, cstr.as_ptr()) };
|
||||||
sys::libvlc_add_intf(self.ptr, cstr.as_ptr())
|
|
||||||
};
|
|
||||||
|
|
||||||
if result == 0 { Ok(()) }
|
if result == 0 {
|
||||||
else { Err(()) }
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the application name.
|
/// Sets the application name.
|
||||||
/// LibVLC passes this as the user agent string when a protocol requires it.
|
/// LibVLC passes this as the user agent string when a protocol requires it.
|
||||||
pub fn set_user_agent(&self, name: &str, http: &str) {
|
pub fn set_user_agent(&self, name: &str, http: &str) {
|
||||||
unsafe{
|
unsafe {
|
||||||
sys::libvlc_set_user_agent(
|
sys::libvlc_set_user_agent(self.ptr, to_cstr(name).as_ptr(), to_cstr(http).as_ptr());
|
||||||
self.ptr, to_cstr(name).as_ptr(), to_cstr(http).as_ptr());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until an interface causes the instance to exit.
|
/// Waits until an interface causes the instance to exit.
|
||||||
pub fn wait(&self) {
|
pub fn wait(&self) {
|
||||||
unsafe{ sys::libvlc_wait(self.ptr) };
|
unsafe { sys::libvlc_wait(self.ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets some meta-information about the application.
|
/// Sets some meta-information about the application.
|
||||||
pub fn set_app_id(&self, id: &str, version: &str, icon: &str) {
|
pub fn set_app_id(&self, id: &str, version: &str, icon: &str) {
|
||||||
unsafe{
|
unsafe {
|
||||||
sys::libvlc_set_app_id(
|
sys::libvlc_set_app_id(
|
||||||
self.ptr, to_cstr(id).as_ptr(), to_cstr(version).as_ptr(), to_cstr(icon).as_ptr());
|
self.ptr,
|
||||||
|
to_cstr(id).as_ptr(),
|
||||||
|
to_cstr(version).as_ptr(),
|
||||||
|
to_cstr(icon).as_ptr(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of audio filters that are available.
|
/// Returns a list of audio filters that are available.
|
||||||
pub fn audio_filter_list_get(&self) -> Option<ModuleDescriptionList> {
|
pub fn audio_filter_list_get(&self) -> Option<ModuleDescriptionList> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_audio_filter_list_get(self.ptr);
|
let p = sys::libvlc_audio_filter_list_get(self.ptr);
|
||||||
if p.is_null() { None }
|
if p.is_null() {
|
||||||
else { Some(ModuleDescriptionList{ptr: p}) }
|
None
|
||||||
|
} else {
|
||||||
|
Some(ModuleDescriptionList { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of video filters that are available.
|
/// Returns a list of video filters that are available.
|
||||||
pub fn video_filter_list_get(&self) -> Option<ModuleDescriptionList> {
|
pub fn video_filter_list_get(&self) -> Option<ModuleDescriptionList> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_video_filter_list_get(self.ptr);
|
let p = sys::libvlc_video_filter_list_get(self.ptr);
|
||||||
if p.is_null() { None }
|
if p.is_null() {
|
||||||
else { Some(ModuleDescriptionList{ptr: p}) }
|
None
|
||||||
|
} else {
|
||||||
|
Some(ModuleDescriptionList { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the VLM event manager
|
/// Returns the VLM event manager
|
||||||
pub fn vlm_event_manager<'a>(&'a self) -> EventManager<'a> {
|
pub fn vlm_event_manager<'a>(&'a self) -> EventManager<'a> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_vlm_get_event_manager(self.ptr);
|
let p = sys::libvlc_vlm_get_event_manager(self.ptr);
|
||||||
assert!(!p.is_null());
|
assert!(!p.is_null());
|
||||||
EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
|
EventManager {
|
||||||
|
ptr: p,
|
||||||
|
_phantomdata: ::std::marker::PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,7 +164,7 @@ impl Instance {
|
||||||
pub fn set_log<F: Fn(LogLevel, Log, Cow<str>) + Send + 'static>(&self, f: F) {
|
pub fn set_log<F: Fn(LogLevel, Log, Cow<str>) + Send + 'static>(&self, f: F) {
|
||||||
let cb: Box<Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static>> = Box::new(Box::new(f));
|
let cb: Box<Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static>> = Box::new(Box::new(f));
|
||||||
|
|
||||||
unsafe{
|
unsafe {
|
||||||
sys::libvlc_log_set(self.ptr, Some(logging_cb), Box::into_raw(cb) as *mut _);
|
sys::libvlc_log_set(self.ptr, Some(logging_cb), Box::into_raw(cb) as *mut _);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,7 +177,7 @@ impl Instance {
|
||||||
|
|
||||||
impl Drop for Instance {
|
impl Drop for Instance {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe{
|
unsafe {
|
||||||
sys::libvlc_release(self.ptr);
|
sys::libvlc_release(self.ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,14 +185,22 @@ impl Drop for Instance {
|
||||||
|
|
||||||
const BUF_SIZE: usize = 1024; // Write log message to the buffer by vsnprintf.
|
const BUF_SIZE: usize = 1024; // Write log message to the buffer by vsnprintf.
|
||||||
unsafe extern "C" fn logging_cb(
|
unsafe extern "C" fn logging_cb(
|
||||||
data: *mut c_void, level: c_int, ctx: *const sys::libvlc_log_t, fmt: *const c_char, args: *mut sys::__va_list_tag) {
|
data: *mut c_void,
|
||||||
|
level: c_int,
|
||||||
|
ctx: *const sys::libvlc_log_t,
|
||||||
|
fmt: *const c_char,
|
||||||
|
args: *mut sys::__va_list_tag,
|
||||||
|
) {
|
||||||
let f: &Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static> = ::std::mem::transmute(data);
|
let f: &Box<dyn Fn(LogLevel, Log, Cow<str>) + Send + 'static> = ::std::mem::transmute(data);
|
||||||
let mut buf: [c_char; BUF_SIZE] = [0; BUF_SIZE];
|
let mut buf: [c_char; BUF_SIZE] = [0; BUF_SIZE];
|
||||||
|
|
||||||
sys::vsnprintf(buf.as_mut_ptr(), BUF_SIZE.try_into().unwrap(), fmt, args);
|
sys::vsnprintf(buf.as_mut_ptr(), BUF_SIZE.try_into().unwrap(), fmt, args);
|
||||||
|
|
||||||
f((level as u32).into(), Log{ptr: ctx}, from_cstr_ref(buf.as_ptr()).unwrap());
|
f(
|
||||||
|
(level as u32).into(),
|
||||||
|
Log { ptr: ctx },
|
||||||
|
from_cstr_ref(buf.as_ptr()).unwrap(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List of module description.
|
/// List of module description.
|
||||||
|
@ -180,7 +217,7 @@ impl ModuleDescriptionList {
|
||||||
|
|
||||||
impl Drop for ModuleDescriptionList {
|
impl Drop for ModuleDescriptionList {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe{ sys::libvlc_module_description_list_release(self.ptr) };
|
unsafe { sys::libvlc_module_description_list_release(self.ptr) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +226,10 @@ impl<'a> IntoIterator for &'a ModuleDescriptionList {
|
||||||
type IntoIter = ModuleDescriptionListIter<'a>;
|
type IntoIter = ModuleDescriptionListIter<'a>;
|
||||||
|
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
ModuleDescriptionListIter{ptr: self.ptr, _phantomdata: PhantomData}
|
ModuleDescriptionListIter {
|
||||||
|
ptr: self.ptr,
|
||||||
|
_phantomdata: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,36 +242,36 @@ pub struct ModuleDescriptionListIter<'a> {
|
||||||
/// The strings are owned.
|
/// The strings are owned.
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct ModuleDescription {
|
pub struct ModuleDescription {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub shortname: Option<String>,
|
pub shortname: Option<String>,
|
||||||
pub longname: Option<String>,
|
pub longname: Option<String>,
|
||||||
pub help: Option<String>,
|
pub help: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Description of a module.
|
/// Description of a module.
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub struct ModuleDescriptionRef<'a> {
|
pub struct ModuleDescriptionRef<'a> {
|
||||||
pub name: Option<Cow<'a, str>>,
|
pub name: Option<Cow<'a, str>>,
|
||||||
pub shortname: Option<Cow<'a, str>>,
|
pub shortname: Option<Cow<'a, str>>,
|
||||||
pub longname: Option<Cow<'a, str>>,
|
pub longname: Option<Cow<'a, str>>,
|
||||||
pub help: Option<Cow<'a, str>>,
|
pub help: Option<Cow<'a, str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for ModuleDescriptionListIter<'a> {
|
impl<'a> Iterator for ModuleDescriptionListIter<'a> {
|
||||||
type Item = ModuleDescriptionRef<'a>;
|
type Item = ModuleDescriptionRef<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if self.ptr.is_null() {
|
if self.ptr.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let p = self.ptr;
|
let p = self.ptr;
|
||||||
self.ptr = (*p).p_next;
|
self.ptr = (*p).p_next;
|
||||||
Some(ModuleDescriptionRef{
|
Some(ModuleDescriptionRef {
|
||||||
name: from_cstr_ref((*p).psz_name),
|
name: from_cstr_ref((*p).psz_name),
|
||||||
shortname: from_cstr_ref((*p).psz_shortname),
|
shortname: from_cstr_ref((*p).psz_shortname),
|
||||||
longname: from_cstr_ref((*p).psz_longname),
|
longname: from_cstr_ref((*p).psz_longname),
|
||||||
help: from_cstr_ref((*p).psz_help),
|
help: from_cstr_ref((*p).psz_help),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,20 +281,20 @@ impl<'a> ModuleDescriptionRef<'a> {
|
||||||
/// Convert to owned strings.
|
/// Convert to owned strings.
|
||||||
pub fn into_owned(&'a self) -> ModuleDescription {
|
pub fn into_owned(&'a self) -> ModuleDescription {
|
||||||
ModuleDescription {
|
ModuleDescription {
|
||||||
name: self.name .as_ref().map(|s| s.clone().into_owned()),
|
name: self.name.as_ref().map(|s| s.clone().into_owned()),
|
||||||
shortname: self.shortname.as_ref().map(|s| s.clone().into_owned()),
|
shortname: self.shortname.as_ref().map(|s| s.clone().into_owned()),
|
||||||
longname: self.name .as_ref().map(|s| s.clone().into_owned()),
|
longname: self.name.as_ref().map(|s| s.clone().into_owned()),
|
||||||
help: self.shortname.as_ref().map(|s| s.clone().into_owned()),
|
help: self.shortname.as_ref().map(|s| s.clone().into_owned()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn errmsg() -> Option<String> {
|
pub fn errmsg() -> Option<String> {
|
||||||
unsafe{ from_cstr(sys::libvlc_errmsg()) }
|
unsafe { from_cstr(sys::libvlc_errmsg()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clearerr() {
|
pub fn clearerr() {
|
||||||
unsafe{ sys::libvlc_clearerr() };
|
unsafe { sys::libvlc_clearerr() };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -315,7 +355,7 @@ pub enum Event {
|
||||||
VlmMediaInstanceStatusPlaying(Option<String>, Option<String>),
|
VlmMediaInstanceStatusPlaying(Option<String>, Option<String>),
|
||||||
VlmMediaInstanceStatusPause(Option<String>, Option<String>),
|
VlmMediaInstanceStatusPause(Option<String>, Option<String>),
|
||||||
VlmMediaInstanceStatusEnd(Option<String>, Option<String>),
|
VlmMediaInstanceStatusEnd(Option<String>, Option<String>),
|
||||||
VlmMediaInstanceStatusError(Option<String>, Option<String>)
|
VlmMediaInstanceStatusError(Option<String>, Option<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventManager<'a> {
|
pub struct EventManager<'a> {
|
||||||
|
@ -324,23 +364,27 @@ pub struct EventManager<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> EventManager<'a> {
|
impl<'a> EventManager<'a> {
|
||||||
pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<(), ()>
|
pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<(), InternalError>
|
||||||
where F: Fn(Event, VLCObject) + Send + 'static
|
where
|
||||||
|
F: Fn(Event, VLCObject) + Send + 'static,
|
||||||
{
|
{
|
||||||
// Explicit type annotation is needed
|
// Explicit type annotation is needed
|
||||||
let callback: Box<Box<dyn Fn(Event, VLCObject) + Send + 'static>> =
|
let callback: Box<Box<dyn Fn(Event, VLCObject) + Send + 'static>> =
|
||||||
Box::new(Box::new(callback));
|
Box::new(Box::new(callback));
|
||||||
|
|
||||||
let result = unsafe{
|
let result = unsafe {
|
||||||
sys::libvlc_event_attach(
|
sys::libvlc_event_attach(
|
||||||
self.ptr, event_type as i32, Some(event_manager_callback),
|
self.ptr,
|
||||||
Box::into_raw(callback) as *mut c_void)
|
event_type as i32,
|
||||||
|
Some(event_manager_callback),
|
||||||
|
Box::into_raw(callback) as *mut c_void,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if result == 0 {
|
if result == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
}else{
|
} else {
|
||||||
Err(())
|
Err(InternalError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,201 +397,133 @@ impl<'a> EventManager<'a> {
|
||||||
unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data: *mut c_void) {
|
unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data: *mut c_void) {
|
||||||
let f: &Box<dyn Fn(Event, VLCObject) + Send + 'static> = ::std::mem::transmute(data);
|
let f: &Box<dyn Fn(Event, VLCObject) + Send + 'static> = ::std::mem::transmute(data);
|
||||||
|
|
||||||
f(conv_event(pe), VLCObject{ ptr: (*pe).p_obj });
|
f(conv_event(pe), VLCObject { ptr: (*pe).p_obj });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert c-style libvlc_event_t to Event
|
// Convert c-style libvlc_event_t to Event
|
||||||
fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
|
fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
|
||||||
let event_type: EventType = (unsafe{ (*pe).type_ } as u32).into();
|
let event_type: EventType = (unsafe { (*pe).type_ } as u32).into();
|
||||||
|
|
||||||
match event_type {
|
match event_type {
|
||||||
EventType::MediaMetaChanged => {
|
EventType::MediaMetaChanged => unsafe {
|
||||||
unsafe{
|
Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type.into())
|
||||||
Event::MediaMetaChanged((*pe).u.media_meta_changed.meta_type.into())
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
EventType::MediaSubItemAdded => {
|
EventType::MediaSubItemAdded => Event::MediaSubItemAdded,
|
||||||
Event::MediaSubItemAdded
|
EventType::MediaDurationChanged => unsafe {
|
||||||
|
Event::MediaDurationChanged((*pe).u.media_duration_changed.new_duration)
|
||||||
},
|
},
|
||||||
EventType::MediaDurationChanged => {
|
EventType::MediaParsedChanged => unsafe {
|
||||||
unsafe{
|
Event::MediaParsedChanged((*pe).u.media_parsed_changed.new_status)
|
||||||
Event::MediaDurationChanged((*pe).u.media_duration_changed.new_duration)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
EventType::MediaParsedChanged => {
|
EventType::MediaFreed => Event::MediaFreed,
|
||||||
unsafe{
|
EventType::MediaStateChanged => unsafe {
|
||||||
Event::MediaParsedChanged((*pe).u.media_parsed_changed.new_status)
|
let new_state: sys::libvlc_state_t =
|
||||||
}
|
(*pe).u.media_state_changed.new_state.try_into().unwrap();
|
||||||
|
Event::MediaStateChanged(new_state.into())
|
||||||
},
|
},
|
||||||
EventType::MediaFreed => {
|
EventType::MediaSubItemTreeAdded => Event::MediaSubItemTreeAdded,
|
||||||
Event::MediaFreed
|
EventType::MediaPlayerMediaChanged => Event::MediaPlayerMediaChanged,
|
||||||
|
EventType::MediaPlayerNothingSpecial => Event::MediaPlayerNothingSpecial,
|
||||||
|
EventType::MediaPlayerOpening => Event::MediaPlayerOpening,
|
||||||
|
EventType::MediaPlayerBuffering => unsafe {
|
||||||
|
Event::MediaPlayerBuffering((*pe).u.media_player_buffering.new_cache)
|
||||||
},
|
},
|
||||||
EventType::MediaStateChanged => {
|
EventType::MediaPlayerPlaying => Event::MediaPlayerPlaying,
|
||||||
unsafe{
|
EventType::MediaPlayerPaused => Event::MediaPlayerPaused,
|
||||||
let new_state: sys::libvlc_state_t = (*pe).u.media_state_changed.new_state.try_into().unwrap();
|
EventType::MediaPlayerStopped => Event::MediaPlayerStopped,
|
||||||
Event::MediaStateChanged(new_state.into())
|
EventType::MediaPlayerForward => Event::MediaPlayerForward,
|
||||||
}
|
EventType::MediaPlayerBackward => Event::MediaPlayerBackward,
|
||||||
|
EventType::MediaPlayerEndReached => Event::MediaPlayerEndReached,
|
||||||
|
EventType::MediaPlayerEncounteredError => Event::MediaPlayerEncounteredError,
|
||||||
|
EventType::MediaPlayerTimeChanged => Event::MediaPlayerTimeChanged,
|
||||||
|
EventType::MediaPlayerPositionChanged => unsafe {
|
||||||
|
Event::MediaPlayerPositionChanged((*pe).u.media_player_position_changed.new_position)
|
||||||
},
|
},
|
||||||
EventType::MediaSubItemTreeAdded => {
|
EventType::MediaPlayerSeekableChanged => Event::MediaPlayerSeekableChanged,
|
||||||
Event::MediaSubItemTreeAdded
|
EventType::MediaPlayerPausableChanged => Event::MediaPlayerPausableChanged,
|
||||||
|
EventType::MediaPlayerTitleChanged => Event::MediaPlayerTitleChanged,
|
||||||
|
EventType::MediaPlayerSnapshotTaken => Event::MediaPlayerSnapshotTaken,
|
||||||
|
EventType::MediaPlayerLengthChanged => Event::MediaPlayerLengthChanged,
|
||||||
|
EventType::MediaPlayerVout => Event::MediaPlayerVout,
|
||||||
|
EventType::MediaPlayerScrambledChanged => Event::MediaPlayerScrambledChanged,
|
||||||
|
EventType::MediaListItemAdded => Event::MediaListItemAdded,
|
||||||
|
EventType::MediaListWillAddItem => Event::MediaListWillAddItem,
|
||||||
|
EventType::MediaListItemDeleted => Event::MediaListItemDeleted,
|
||||||
|
EventType::MediaListWillDeleteItem => Event::MediaListWillDeleteItem,
|
||||||
|
EventType::MediaListViewItemAdded => Event::MediaListViewItemAdded,
|
||||||
|
EventType::MediaListViewWillAddItem => Event::MediaListViewWillAddItem,
|
||||||
|
EventType::MediaListViewItemDeleted => Event::MediaListViewItemDeleted,
|
||||||
|
EventType::MediaListViewWillDeleteItem => Event::MediaListViewWillDeleteItem,
|
||||||
|
EventType::MediaListPlayerPlayed => Event::MediaListPlayerPlayed,
|
||||||
|
EventType::MediaListPlayerNextItemSet => Event::MediaListPlayerNextItemSet,
|
||||||
|
EventType::MediaListPlayerStopped => Event::MediaListPlayerStopped,
|
||||||
|
EventType::MediaDiscovererStarted => Event::MediaDiscovererStarted,
|
||||||
|
EventType::MediaDiscovererEnded => Event::MediaDiscovererEnded,
|
||||||
|
EventType::VlmMediaAdded => unsafe {
|
||||||
|
Event::VlmMediaAdded(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerMediaChanged => {
|
EventType::VlmMediaRemoved => unsafe {
|
||||||
Event::MediaPlayerMediaChanged
|
Event::VlmMediaRemoved(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerNothingSpecial => {
|
EventType::VlmMediaChanged => unsafe {
|
||||||
Event::MediaPlayerNothingSpecial
|
Event::VlmMediaChanged(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerOpening => {
|
EventType::VlmMediaInstanceStarted => unsafe {
|
||||||
Event::MediaPlayerOpening
|
Event::VlmMediaInstanceStarted(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerBuffering => {
|
EventType::VlmMediaInstanceStopped => unsafe {
|
||||||
unsafe{
|
Event::VlmMediaInstanceStopped(
|
||||||
Event::MediaPlayerBuffering((*pe).u.media_player_buffering.new_cache)
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
}
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerPlaying => {
|
EventType::VlmMediaInstanceStatusInit => unsafe {
|
||||||
Event::MediaPlayerPlaying
|
Event::VlmMediaInstanceStatusInit(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerPaused => {
|
EventType::VlmMediaInstanceStatusOpening => unsafe {
|
||||||
Event::MediaPlayerPaused
|
Event::VlmMediaInstanceStatusOpening(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerStopped => {
|
EventType::VlmMediaInstanceStatusPlaying => unsafe {
|
||||||
Event::MediaPlayerStopped
|
Event::VlmMediaInstanceStatusPlaying(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerForward => {
|
EventType::VlmMediaInstanceStatusPause => unsafe {
|
||||||
Event::MediaPlayerForward
|
Event::VlmMediaInstanceStatusPause(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerBackward => {
|
EventType::VlmMediaInstanceStatusEnd => unsafe {
|
||||||
Event::MediaPlayerBackward
|
Event::VlmMediaInstanceStatusEnd(
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
EventType::MediaPlayerEndReached => {
|
EventType::VlmMediaInstanceStatusError => unsafe {
|
||||||
Event::MediaPlayerEndReached
|
Event::VlmMediaInstanceStatusError(
|
||||||
},
|
from_cstr((*pe).u.vlm_media_event.psz_instance_name),
|
||||||
EventType::MediaPlayerEncounteredError => {
|
from_cstr((*pe).u.vlm_media_event.psz_media_name),
|
||||||
Event::MediaPlayerEncounteredError
|
)
|
||||||
},
|
|
||||||
EventType::MediaPlayerTimeChanged => {
|
|
||||||
Event::MediaPlayerTimeChanged
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerPositionChanged => {
|
|
||||||
unsafe{
|
|
||||||
Event::MediaPlayerPositionChanged((*pe).u.media_player_position_changed.new_position)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerSeekableChanged => {
|
|
||||||
Event::MediaPlayerSeekableChanged
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerPausableChanged => {
|
|
||||||
Event::MediaPlayerPausableChanged
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerTitleChanged => {
|
|
||||||
Event::MediaPlayerTitleChanged
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerSnapshotTaken => {
|
|
||||||
Event::MediaPlayerSnapshotTaken
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerLengthChanged => {
|
|
||||||
Event::MediaPlayerLengthChanged
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerVout => {
|
|
||||||
Event::MediaPlayerVout
|
|
||||||
},
|
|
||||||
EventType::MediaPlayerScrambledChanged => {
|
|
||||||
Event::MediaPlayerScrambledChanged
|
|
||||||
},
|
|
||||||
EventType::MediaListItemAdded => {
|
|
||||||
Event::MediaListItemAdded
|
|
||||||
},
|
|
||||||
EventType::MediaListWillAddItem => {
|
|
||||||
Event::MediaListWillAddItem
|
|
||||||
},
|
|
||||||
EventType::MediaListItemDeleted => {
|
|
||||||
Event::MediaListItemDeleted
|
|
||||||
},
|
|
||||||
EventType::MediaListWillDeleteItem => {
|
|
||||||
Event::MediaListWillDeleteItem
|
|
||||||
},
|
|
||||||
EventType::MediaListViewItemAdded => {
|
|
||||||
Event::MediaListViewItemAdded
|
|
||||||
},
|
|
||||||
EventType::MediaListViewWillAddItem => {
|
|
||||||
Event::MediaListViewWillAddItem
|
|
||||||
},
|
|
||||||
EventType::MediaListViewItemDeleted => {
|
|
||||||
Event::MediaListViewItemDeleted
|
|
||||||
},
|
|
||||||
EventType::MediaListViewWillDeleteItem => {
|
|
||||||
Event::MediaListViewWillDeleteItem
|
|
||||||
},
|
|
||||||
EventType::MediaListPlayerPlayed => {
|
|
||||||
Event::MediaListPlayerPlayed
|
|
||||||
},
|
|
||||||
EventType::MediaListPlayerNextItemSet => {
|
|
||||||
Event::MediaListPlayerNextItemSet
|
|
||||||
},
|
|
||||||
EventType::MediaListPlayerStopped => {
|
|
||||||
Event::MediaListPlayerStopped
|
|
||||||
},
|
|
||||||
EventType::MediaDiscovererStarted => {
|
|
||||||
Event::MediaDiscovererStarted
|
|
||||||
},
|
|
||||||
EventType::MediaDiscovererEnded => {
|
|
||||||
Event::MediaDiscovererEnded
|
|
||||||
},
|
|
||||||
EventType::VlmMediaAdded => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaAdded(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaRemoved => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaRemoved(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaChanged => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaChanged(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStarted => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStarted(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStopped => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStopped(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStatusInit => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStatusInit(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStatusOpening => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStatusOpening(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStatusPlaying => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStatusPlaying(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStatusPause => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStatusPause(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStatusEnd => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStatusEnd(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
EventType::VlmMediaInstanceStatusError => {
|
|
||||||
unsafe {
|
|
||||||
Event::VlmMediaInstanceStatusError(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,7 +540,7 @@ impl VLCObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Log {
|
pub struct Log {
|
||||||
pub(crate) ptr: *const sys::libvlc_log_t
|
pub(crate) ptr: *const sys::libvlc_log_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Log {
|
impl Log {
|
||||||
|
@ -573,4 +549,3 @@ impl Log {
|
||||||
self.ptr
|
self.ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
30
src/lib.rs
30
src/lib.rs
|
@ -4,23 +4,23 @@
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
mod tools;
|
|
||||||
mod core;
|
|
||||||
mod media;
|
|
||||||
mod media_player;
|
|
||||||
mod media_list;
|
|
||||||
mod media_library;
|
|
||||||
mod enums;
|
|
||||||
mod video;
|
|
||||||
mod audio;
|
mod audio;
|
||||||
|
mod core;
|
||||||
|
mod enums;
|
||||||
|
mod media;
|
||||||
|
mod media_library;
|
||||||
|
mod media_list;
|
||||||
|
mod media_player;
|
||||||
|
mod tools;
|
||||||
|
mod video;
|
||||||
mod vlm;
|
mod vlm;
|
||||||
|
|
||||||
pub use crate::enums::*;
|
|
||||||
pub use crate::core::*;
|
|
||||||
pub use crate::media::*;
|
|
||||||
pub use crate::media_player::*;
|
|
||||||
pub use crate::media_list::*;
|
|
||||||
pub use crate::media_library::*;
|
|
||||||
pub use crate::video::*;
|
|
||||||
pub use crate::audio::*;
|
pub use crate::audio::*;
|
||||||
|
pub use crate::core::*;
|
||||||
|
pub use crate::enums::*;
|
||||||
|
pub use crate::media::*;
|
||||||
|
pub use crate::media_library::*;
|
||||||
|
pub use crate::media_list::*;
|
||||||
|
pub use crate::media_player::*;
|
||||||
|
pub use crate::video::*;
|
||||||
pub use crate::vlm::*;
|
pub use crate::vlm::*;
|
||||||
|
|
113
src/media.rs
113
src/media.rs
|
@ -2,11 +2,11 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
use vlc_sys as sys;
|
use crate::enums::{Meta, State, TrackType};
|
||||||
use crate::{Instance, EventManager};
|
use crate::tools::{from_cstr, path_to_cstr, to_cstr};
|
||||||
use crate::enums::{State, Meta, TrackType};
|
use crate::{EventManager, Instance};
|
||||||
use crate::tools::{to_cstr, from_cstr, path_to_cstr};
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use vlc_sys as sys;
|
||||||
|
|
||||||
pub struct Media {
|
pub struct Media {
|
||||||
pub(crate) ptr: *mut sys::libvlc_media_t,
|
pub(crate) ptr: *mut sys::libvlc_media_t,
|
||||||
|
@ -19,13 +19,13 @@ impl Media {
|
||||||
pub fn new_location(instance: &Instance, mrl: &str) -> Option<Media> {
|
pub fn new_location(instance: &Instance, mrl: &str) -> Option<Media> {
|
||||||
let cstr = to_cstr(mrl);
|
let cstr = to_cstr(mrl);
|
||||||
|
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_new_location(instance.ptr, cstr.as_ptr());
|
let p = sys::libvlc_media_new_location(instance.ptr, cstr.as_ptr());
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Media{ptr: p})
|
Some(Media { ptr: p })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,32 +33,34 @@ impl Media {
|
||||||
pub fn new_path<T: AsRef<Path>>(instance: &Instance, path: T) -> Option<Media> {
|
pub fn new_path<T: AsRef<Path>>(instance: &Instance, path: T) -> Option<Media> {
|
||||||
let cstr = match path_to_cstr(path.as_ref()) {
|
let cstr = match path_to_cstr(path.as_ref()) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(_) => { return None; },
|
Err(_) => {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_new_path(instance.ptr, cstr.as_ptr());
|
let p = sys::libvlc_media_new_path(instance.ptr, cstr.as_ptr());
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Media{ptr: p})
|
Some(Media { ptr: p })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_fd(instance: &Instance, fd: i32) -> Option<Media> {
|
pub fn new_fd(instance: &Instance, fd: i32) -> Option<Media> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_new_fd(instance.ptr, fd);
|
let p = sys::libvlc_media_new_fd(instance.ptr, fd);
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Media{ptr: p})
|
Some(Media { ptr: p })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mrl(&self) -> Option<String> {
|
pub fn mrl(&self) -> Option<String> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p_str = sys::libvlc_media_get_mrl(self.ptr);
|
let p_str = sys::libvlc_media_get_mrl(self.ptr);
|
||||||
let s = from_cstr(p_str);
|
let s = from_cstr(p_str);
|
||||||
sys::libvlc_free(p_str as *mut ::libc::c_void);
|
sys::libvlc_free(p_str as *mut ::libc::c_void);
|
||||||
|
@ -67,17 +69,20 @@ impl Media {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
|
pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_event_manager(self.ptr);
|
let p = sys::libvlc_media_event_manager(self.ptr);
|
||||||
assert!(!p.is_null());
|
assert!(!p.is_null());
|
||||||
EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
|
EventManager {
|
||||||
|
ptr: p,
|
||||||
|
_phantomdata: ::std::marker::PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read the meta of the media.
|
/// Read the meta of the media.
|
||||||
/// If the media has not yet been parsed this will return None.
|
/// If the media has not yet been parsed this will return None.
|
||||||
pub fn get_meta(&self, meta: Meta) -> Option<String> {
|
pub fn get_meta(&self, meta: Meta) -> Option<String> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p_str = sys::libvlc_media_get_meta(self.ptr, meta as u32);
|
let p_str = sys::libvlc_media_get_meta(self.ptr, meta as u32);
|
||||||
let s = from_cstr(p_str);
|
let s = from_cstr(p_str);
|
||||||
sys::libvlc_free(p_str as *mut ::libc::c_void);
|
sys::libvlc_free(p_str as *mut ::libc::c_void);
|
||||||
|
@ -88,46 +93,48 @@ impl Media {
|
||||||
/// Set the meta of the media.
|
/// Set the meta of the media.
|
||||||
/// (This function will not save the meta, call save_meta in order to save the meta)
|
/// (This function will not save the meta, call save_meta in order to save the meta)
|
||||||
pub fn set_meta(&self, meta: Meta, value: &str) {
|
pub fn set_meta(&self, meta: Meta, value: &str) {
|
||||||
unsafe{
|
unsafe {
|
||||||
sys::libvlc_media_set_meta(self.ptr, meta as u32, to_cstr(value).as_ptr());
|
sys::libvlc_media_set_meta(self.ptr, meta as u32, to_cstr(value).as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save the meta previously set.
|
/// Save the meta previously set.
|
||||||
pub fn save_meta(&self) -> bool {
|
pub fn save_meta(&self) -> bool {
|
||||||
if unsafe{ sys::libvlc_media_save_meta(self.ptr) } == 0 { false }else{ true }
|
(unsafe { sys::libvlc_media_save_meta(self.ptr) } != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current state of media descriptor object.
|
/// Get current state of media descriptor object.
|
||||||
pub fn state(&self) -> State {
|
pub fn state(&self) -> State {
|
||||||
unsafe{ sys::libvlc_media_get_state(self.ptr).into() }
|
unsafe { sys::libvlc_media_get_state(self.ptr).into() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get duration (in ms) of media descriptor object item.
|
/// Get duration (in ms) of media descriptor object item.
|
||||||
pub fn duration(&self) -> Option<i64> {
|
pub fn duration(&self) -> Option<i64> {
|
||||||
let time = unsafe{
|
let time = unsafe { sys::libvlc_media_get_duration(self.ptr) };
|
||||||
sys::libvlc_media_get_duration(self.ptr)
|
if time != -1 {
|
||||||
};
|
Some(time)
|
||||||
if time != -1 { Some(time) }else{ None }
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a media.
|
/// Parse a media.
|
||||||
pub fn parse(&self) {
|
pub fn parse(&self) {
|
||||||
unsafe{ sys::libvlc_media_parse(self.ptr) };
|
unsafe { sys::libvlc_media_parse(self.ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a media.
|
/// Parse a media.
|
||||||
pub fn parse_async(&self) {
|
pub fn parse_async(&self) {
|
||||||
unsafe{ sys::libvlc_media_parse_async(self.ptr) };
|
unsafe { sys::libvlc_media_parse_async(self.ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get Parsed status for media descriptor object.
|
/// Get Parsed status for media descriptor object.
|
||||||
pub fn is_parsed(&self) -> bool {
|
pub fn is_parsed(&self) -> bool {
|
||||||
if unsafe{ sys::libvlc_media_is_parsed(self.ptr) } == 0 { false }else{ true }
|
(unsafe { sys::libvlc_media_is_parsed(self.ptr) } != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tracks(&self) -> Option<Vec<MediaTrack>> {
|
pub fn tracks(&self) -> Option<Vec<MediaTrack>> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let mut p_track: *mut *mut sys::libvlc_media_track_t = ::std::ptr::null_mut();
|
let mut p_track: *mut *mut sys::libvlc_media_track_t = ::std::ptr::null_mut();
|
||||||
let n = sys::libvlc_media_tracks_get(self.ptr, &mut p_track);
|
let n = sys::libvlc_media_tracks_get(self.ptr, &mut p_track);
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
|
@ -142,41 +149,41 @@ impl Media {
|
||||||
let type_specific_data = match i_type {
|
let type_specific_data = match i_type {
|
||||||
TrackType::Audio => {
|
TrackType::Audio => {
|
||||||
let audio = (**p).__bindgen_anon_1.audio;
|
let audio = (**p).__bindgen_anon_1.audio;
|
||||||
MediaTrackUnion::Audio(AudioTrack{
|
MediaTrackUnion::Audio(AudioTrack {
|
||||||
channels: (*audio).i_channels,
|
channels: (*audio).i_channels,
|
||||||
rate: (*audio).i_rate,
|
rate: (*audio).i_rate,
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
TrackType::Video => {
|
TrackType::Video => {
|
||||||
let video = (**p).__bindgen_anon_1.video;
|
let video = (**p).__bindgen_anon_1.video;
|
||||||
MediaTrackUnion::Video(VideoTrack{
|
MediaTrackUnion::Video(VideoTrack {
|
||||||
height: (*video).i_height,
|
height: (*video).i_height,
|
||||||
width: (*video).i_width,
|
width: (*video).i_width,
|
||||||
sar_num: (*video).i_sar_num,
|
sar_num: (*video).i_sar_num,
|
||||||
sar_den: (*video).i_sar_den,
|
sar_den: (*video).i_sar_den,
|
||||||
frame_rate_num: (*video).i_frame_rate_num,
|
frame_rate_num: (*video).i_frame_rate_num,
|
||||||
frame_rate_den: (*video).i_frame_rate_den,
|
frame_rate_den: (*video).i_frame_rate_den,
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
TrackType::Text => {
|
TrackType::Text => {
|
||||||
let subtitle = (**p).__bindgen_anon_1.subtitle;
|
let subtitle = (**p).__bindgen_anon_1.subtitle;
|
||||||
MediaTrackUnion::Subtitle(SubtitleTrack{
|
MediaTrackUnion::Subtitle(SubtitleTrack {
|
||||||
encoding: from_cstr((*subtitle).psz_encoding)
|
encoding: from_cstr((*subtitle).psz_encoding),
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
TrackType::Unknown => MediaTrackUnion::None,
|
TrackType::Unknown => MediaTrackUnion::None,
|
||||||
};
|
};
|
||||||
track.push(MediaTrack{
|
track.push(MediaTrack {
|
||||||
codec: (**p).i_codec,
|
codec: (**p).i_codec,
|
||||||
original_fourcc: (**p).i_original_fourcc,
|
original_fourcc: (**p).i_original_fourcc,
|
||||||
id: (**p).i_id,
|
id: (**p).i_id,
|
||||||
track_type: (**p).i_type.into(),
|
track_type: (**p).i_type.into(),
|
||||||
profile: (**p).i_profile,
|
profile: (**p).i_profile,
|
||||||
level: (**p).i_level,
|
level: (**p).i_level,
|
||||||
bitrate: (**p).i_bitrate,
|
bitrate: (**p).i_bitrate,
|
||||||
language: from_cstr((**p).psz_language),
|
language: from_cstr((**p).psz_language),
|
||||||
description: from_cstr((**p).psz_description),
|
description: from_cstr((**p).psz_description),
|
||||||
type_specific_data: type_specific_data,
|
type_specific_data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +200,7 @@ impl Media {
|
||||||
|
|
||||||
impl Drop for Media {
|
impl Drop for Media {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe{ sys::libvlc_media_release(self.ptr) };
|
unsafe { sys::libvlc_media_release(self.ptr) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +220,10 @@ pub struct MediaTrack {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub enum MediaTrackUnion {
|
pub enum MediaTrackUnion {
|
||||||
Audio(AudioTrack), Video(VideoTrack), Subtitle(SubtitleTrack), None,
|
Audio(AudioTrack),
|
||||||
|
Video(VideoTrack),
|
||||||
|
Subtitle(SubtitleTrack),
|
||||||
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||||
|
@ -236,4 +246,3 @@ pub struct VideoTrack {
|
||||||
pub struct SubtitleTrack {
|
pub struct SubtitleTrack {
|
||||||
pub encoding: Option<String>,
|
pub encoding: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
|
use crate::{Instance, InternalError, MediaList};
|
||||||
use vlc_sys as sys;
|
use vlc_sys as sys;
|
||||||
use crate::{Instance, MediaList};
|
|
||||||
|
|
||||||
pub struct MediaLibrary {
|
pub struct MediaLibrary {
|
||||||
pub(crate) ptr: *mut sys::libvlc_media_library_t,
|
pub(crate) ptr: *mut sys::libvlc_media_library_t,
|
||||||
|
@ -12,24 +12,36 @@ pub struct MediaLibrary {
|
||||||
impl MediaLibrary {
|
impl MediaLibrary {
|
||||||
/// Create an new Media Library object.
|
/// Create an new Media Library object.
|
||||||
pub fn new(instance: &Instance) -> Option<MediaLibrary> {
|
pub fn new(instance: &Instance) -> Option<MediaLibrary> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_library_new(instance.ptr);
|
let p = sys::libvlc_media_library_new(instance.ptr);
|
||||||
if p.is_null() { None }else{ Some(MediaLibrary{ptr: p}) }
|
if p.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(MediaLibrary { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Load media library.
|
/// Load media library.
|
||||||
pub fn load(&self) -> Result<(), ()> {
|
pub fn load(&self) -> Result<(), InternalError> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if sys::libvlc_media_library_load(self.ptr) == 0 { Ok(()) }else{ Err(()) }
|
if sys::libvlc_media_library_load(self.ptr) == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get media library subitems.
|
/// Get media library subitems.
|
||||||
pub fn media_list(&self) -> Option<MediaList> {
|
pub fn media_list(&self) -> Option<MediaList> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_library_media_list(self.ptr);
|
let p = sys::libvlc_media_library_media_list(self.ptr);
|
||||||
if p.is_null() { None }else{ Some(MediaList{ptr: p}) }
|
if p.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(MediaList { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +53,6 @@ impl MediaLibrary {
|
||||||
|
|
||||||
impl Drop for MediaLibrary {
|
impl Drop for MediaLibrary {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe{ sys::libvlc_media_library_release(self.ptr) };
|
unsafe { sys::libvlc_media_library_release(self.ptr) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
|
use crate::{EventManager, Instance, InternalError, Media};
|
||||||
use vlc_sys as sys;
|
use vlc_sys as sys;
|
||||||
use crate::{Instance, Media, EventManager};
|
|
||||||
|
|
||||||
pub struct MediaList {
|
pub struct MediaList {
|
||||||
pub(crate) ptr: *mut sys::libvlc_media_list_t,
|
pub(crate) ptr: *mut sys::libvlc_media_list_t,
|
||||||
|
@ -12,96 +12,133 @@ pub struct MediaList {
|
||||||
impl MediaList {
|
impl MediaList {
|
||||||
/// Create an empty media list.
|
/// Create an empty media list.
|
||||||
pub fn new(instance: &Instance) -> Option<MediaList> {
|
pub fn new(instance: &Instance) -> Option<MediaList> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_list_new(instance.ptr);
|
let p = sys::libvlc_media_list_new(instance.ptr);
|
||||||
if p.is_null() { None }else{ Some(MediaList{ptr: p}) }
|
if p.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(MediaList { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Associate media instance with this media list instance.
|
/// Associate media instance with this media list instance.
|
||||||
/// If another media instance was present it will be released. The libvlc_media_list_lock should NOT be held upon entering this function.
|
/// If another media instance was present it will be released. The libvlc_media_list_lock should NOT be held upon entering this function.
|
||||||
pub fn set_media(&self, md: &Media) {
|
pub fn set_media(&self, md: &Media) {
|
||||||
unsafe{ sys::libvlc_media_list_set_media(self.ptr, md.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_media_list_set_media(self.ptr, md.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get media instance from this media list instance.
|
/// Get media instance from this media list instance.
|
||||||
/// The MediaList::lock should NOT be held upon entering this function.
|
/// The MediaList::lock should NOT be held upon entering this function.
|
||||||
pub fn media(&self) -> Option<Media> {
|
pub fn media(&self) -> Option<Media> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_list_media(self.ptr);
|
let p = sys::libvlc_media_list_media(self.ptr);
|
||||||
if p.is_null() { None }else{ Some(Media{ptr: p}) }
|
if p.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Media { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add media instance to media list.
|
/// Add media instance to media list.
|
||||||
/// The MediaList::lock should be held upon entering this function.
|
/// The MediaList::lock should be held upon entering this function.
|
||||||
pub fn add_media(&self, md: &Media) -> Result<(), ()> {
|
pub fn add_media(&self, md: &Media) -> Result<(), InternalError> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if sys::libvlc_media_list_add_media(self.ptr, md.ptr) == 0 { Ok(()) }else{ Err(()) }
|
if sys::libvlc_media_list_add_media(self.ptr, md.ptr) == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert media instance in media list on a position.
|
/// Insert media instance in media list on a position.
|
||||||
/// The MediaList::lock should be held upon entering this function.
|
/// The MediaList::lock should be held upon entering this function.
|
||||||
pub fn insert_media(&self, md: &Media, pos: i32) -> Result<(), ()> {
|
pub fn insert_media(&self, md: &Media, pos: i32) -> Result<(), InternalError> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if sys::libvlc_media_list_insert_media(self.ptr, md.ptr, pos) == 0 { Ok(()) }else{ Err(()) }
|
if sys::libvlc_media_list_insert_media(self.ptr, md.ptr, pos) == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove media instance from media list on a position.
|
/// Remove media instance from media list on a position.
|
||||||
/// The MediaList::lock should be held upon entering this function.
|
/// The MediaList::lock should be held upon entering this function.
|
||||||
pub fn remove_index(&self, pos: i32) -> Result<(), ()> {
|
pub fn remove_index(&self, pos: i32) -> Result<(), InternalError> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if sys::libvlc_media_list_remove_index(self.ptr, pos) == 0 { Ok(()) }else{ Err(()) }
|
if sys::libvlc_media_list_remove_index(self.ptr, pos) == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get count on media list items.
|
/// Get count on media list items.
|
||||||
/// The MediaList::lock should be held upon entering this function.
|
/// The MediaList::lock should be held upon entering this function.
|
||||||
pub fn count(&self) -> i32 {
|
pub fn count(&self) -> i32 {
|
||||||
unsafe{ sys::libvlc_media_list_count(self.ptr) }
|
unsafe { sys::libvlc_media_list_count(self.ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List media instance in media list at a position.
|
/// List media instance in media list at a position.
|
||||||
/// The MediaList::lock should be held upon entering this function.
|
/// The MediaList::lock should be held upon entering this function.
|
||||||
pub fn item_at_index(&self, pos: i32) -> Option<Media> {
|
pub fn item_at_index(&self, pos: i32) -> Option<Media> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_list_item_at_index(self.ptr, pos);
|
let p = sys::libvlc_media_list_item_at_index(self.ptr, pos);
|
||||||
if p.is_null() { None }else{ Some(Media{ptr: p}) }
|
if p.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(Media { ptr: p })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find index position of List media instance in media list.
|
/// Find index position of List media instance in media list.
|
||||||
pub fn index_of_item(&self, md: &Media) -> Option<i32> {
|
pub fn index_of_item(&self, md: &Media) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let i = sys::libvlc_media_list_index_of_item(self.ptr, md.ptr);
|
let i = sys::libvlc_media_list_index_of_item(self.ptr, md.ptr);
|
||||||
if i == -1 { None }else{ Some(i) }
|
if i == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(i)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This indicates if this media list is read-only from a user point of view.
|
/// This indicates if this media list is read-only from a user point of view.
|
||||||
pub fn is_readonly(&self) -> bool {
|
pub fn is_readonly(&self) -> bool {
|
||||||
unsafe{ if sys::libvlc_media_list_is_readonly(self.ptr) == 0 { false }else{ true } }
|
unsafe { sys::libvlc_media_list_is_readonly(self.ptr) != 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get lock on media list items
|
/// Get lock on media list items
|
||||||
pub fn lock(&self) {
|
pub fn lock(&self) {
|
||||||
unsafe{ sys::libvlc_media_list_lock(self.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_media_list_lock(self.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Release lock on media list items
|
/// Release lock on media list items
|
||||||
/// The libvlc_media_list_lock should be held upon entering this function.
|
/// The libvlc_media_list_lock should be held upon entering this function.
|
||||||
pub fn unlock(&self) {
|
pub fn unlock(&self) {
|
||||||
unsafe{ sys::libvlc_media_list_unlock(self.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_media_list_unlock(self.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get EventManager from this media list instance.
|
/// Get EventManager from this media list instance.
|
||||||
pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
|
pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_list_event_manager(self.ptr);
|
let p = sys::libvlc_media_list_event_manager(self.ptr);
|
||||||
assert!(!p.is_null());
|
assert!(!p.is_null());
|
||||||
EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
|
EventManager {
|
||||||
|
ptr: p,
|
||||||
|
_phantomdata: ::std::marker::PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +150,6 @@ impl MediaList {
|
||||||
|
|
||||||
impl Drop for MediaList {
|
impl Drop for MediaList {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe{ sys::libvlc_media_list_release(self.ptr) };
|
unsafe { sys::libvlc_media_list_release(self.ptr) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
use vlc_sys as sys;
|
use crate::enums::{Position, State};
|
||||||
use crate::Instance;
|
|
||||||
use crate::Media;
|
|
||||||
use crate::EventManager;
|
use crate::EventManager;
|
||||||
use libc::{c_void, c_uint};
|
use crate::Instance;
|
||||||
use crate::enums::{State, Position};
|
use crate::InternalError;
|
||||||
|
use crate::Media;
|
||||||
|
use libc::{c_uint, c_void};
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
use vlc_sys as sys;
|
||||||
|
|
||||||
/// A LibVLC media player plays one media (usually in a custom drawable).
|
/// A LibVLC media player plays one media (usually in a custom drawable).
|
||||||
pub struct MediaPlayer {
|
pub struct MediaPlayer {
|
||||||
|
@ -20,71 +21,70 @@ unsafe impl Send for MediaPlayer {}
|
||||||
impl MediaPlayer {
|
impl MediaPlayer {
|
||||||
/// Create an empty Media Player object
|
/// Create an empty Media Player object
|
||||||
pub fn new(instance: &Instance) -> Option<MediaPlayer> {
|
pub fn new(instance: &Instance) -> Option<MediaPlayer> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_player_new(instance.ptr);
|
let p = sys::libvlc_media_player_new(instance.ptr);
|
||||||
|
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
return None;
|
None
|
||||||
|
} else {
|
||||||
|
Some(MediaPlayer { ptr: p })
|
||||||
}
|
}
|
||||||
Some(MediaPlayer{ptr: p})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the media that will be used by the media_player. If any, previous md will be released.
|
/// Set the media that will be used by the media_player. If any, previous md will be released.
|
||||||
pub fn set_media(&self, md: &Media) {
|
pub fn set_media(&self, md: &Media) {
|
||||||
unsafe{ sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
|
unsafe { sys::libvlc_media_player_set_media(self.ptr, md.ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the media used by the media_player.
|
/// Get the media used by the media_player.
|
||||||
pub fn get_media(&self) -> Option<Media> {
|
pub fn get_media(&self) -> Option<Media> {
|
||||||
let p = unsafe{ sys::libvlc_media_player_get_media(self.ptr) };
|
let p = unsafe { sys::libvlc_media_player_get_media(self.ptr) };
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
None
|
None
|
||||||
}else{
|
} else {
|
||||||
Some(Media{ptr: p})
|
Some(Media { ptr: p })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the Event Manager from which the media player send event.
|
/// Get the Event Manager from which the media player send event.
|
||||||
pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
|
pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_media_player_event_manager(self.ptr);
|
let p = sys::libvlc_media_player_event_manager(self.ptr);
|
||||||
assert!(!p.is_null());
|
assert!(!p.is_null());
|
||||||
EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
|
EventManager {
|
||||||
|
ptr: p,
|
||||||
|
_phantomdata: ::std::marker::PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// is_playing
|
/// is_playing
|
||||||
pub fn is_playing(&self) -> bool {
|
pub fn is_playing(&self) -> bool {
|
||||||
if unsafe{ sys::libvlc_media_player_is_playing(self.ptr) } == 0 {
|
unsafe { sys::libvlc_media_player_is_playing(self.ptr) != 0 }
|
||||||
false
|
|
||||||
}else{
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Play
|
/// Play
|
||||||
pub fn play(&self) -> Result<(), ()> {
|
pub fn play(&self) -> Result<(), InternalError> {
|
||||||
if unsafe{ sys::libvlc_media_player_play(self.ptr) } == 0 {
|
if unsafe { sys::libvlc_media_player_play(self.ptr) } == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
}else{
|
} else {
|
||||||
Err(())
|
Err(InternalError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pause or resume (no effect if there is no media)
|
/// Pause or resume (no effect if there is no media)
|
||||||
pub fn set_pause(&self, do_pause: bool) {
|
pub fn set_pause(&self, do_pause: bool) {
|
||||||
unsafe{ sys::libvlc_media_player_set_pause(self.ptr, if do_pause {1} else {0}) };
|
unsafe { sys::libvlc_media_player_set_pause(self.ptr, if do_pause { 1 } else { 0 }) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toggle pause (no effect if there is no media)
|
/// Toggle pause (no effect if there is no media)
|
||||||
pub fn pause(&self) {
|
pub fn pause(&self) {
|
||||||
unsafe{ sys::libvlc_media_player_pause(self.ptr) };
|
unsafe { sys::libvlc_media_player_pause(self.ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop (no effect if there is no media)
|
/// Stop (no effect if there is no media)
|
||||||
pub fn stop(&self) {
|
pub fn stop(&self) {
|
||||||
unsafe{ sys::libvlc_media_player_stop(self.ptr) };
|
unsafe { sys::libvlc_media_player_stop(self.ptr) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_callbacks<F>(
|
pub fn set_callbacks<F>(
|
||||||
|
@ -93,8 +93,9 @@ impl MediaPlayer {
|
||||||
pause: Option<Box<dyn Fn(i64) + Send + 'static>>,
|
pause: Option<Box<dyn Fn(i64) + Send + 'static>>,
|
||||||
resume: Option<Box<dyn Fn(i64) + Send + 'static>>,
|
resume: Option<Box<dyn Fn(i64) + Send + 'static>>,
|
||||||
flush: Option<Box<dyn Fn(i64) + Send + 'static>>,
|
flush: Option<Box<dyn Fn(i64) + Send + 'static>>,
|
||||||
drain: Option<Box<dyn Fn() + Send + 'static>>)
|
drain: Option<Box<dyn Fn() + Send + 'static>>,
|
||||||
where F: Fn(*const c_void, u32, i64) + Send + 'static,
|
) where
|
||||||
|
F: Fn(*const c_void, u32, i64) + Send + 'static,
|
||||||
{
|
{
|
||||||
let flag_pause = pause.is_some();
|
let flag_pause = pause.is_some();
|
||||||
let flag_resume = resume.is_some();
|
let flag_resume = resume.is_some();
|
||||||
|
@ -102,164 +103,236 @@ impl MediaPlayer {
|
||||||
let flag_drain = drain.is_some();
|
let flag_drain = drain.is_some();
|
||||||
|
|
||||||
let data = AudioCallbacksData {
|
let data = AudioCallbacksData {
|
||||||
play: Box::new(play), pause: pause, resume: resume,
|
play: Box::new(play),
|
||||||
flush: flush, drain: drain,
|
pause,
|
||||||
|
resume,
|
||||||
|
flush,
|
||||||
|
drain,
|
||||||
};
|
};
|
||||||
let data = Box::into_raw(Box::new(data));
|
let data = Box::into_raw(Box::new(data));
|
||||||
|
|
||||||
unsafe{
|
unsafe {
|
||||||
sys::libvlc_audio_set_callbacks(
|
sys::libvlc_audio_set_callbacks(
|
||||||
self.ptr,
|
self.ptr,
|
||||||
Some(audio_cb_play),
|
Some(audio_cb_play),
|
||||||
if flag_pause {Some(audio_cb_pause)} else {None},
|
if flag_pause {
|
||||||
if flag_resume {Some(audio_cb_resume)} else {None},
|
Some(audio_cb_pause)
|
||||||
if flag_flush {Some(audio_cb_flush)} else {None},
|
} else {
|
||||||
if flag_drain {Some(audio_cb_drain)} else {None},
|
None
|
||||||
data as *mut c_void);
|
},
|
||||||
|
if flag_resume {
|
||||||
|
Some(audio_cb_resume)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
if flag_flush {
|
||||||
|
Some(audio_cb_flush)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
if flag_drain {
|
||||||
|
Some(audio_cb_drain)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
data as *mut c_void,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the NSView handler where the media player should render its video output.
|
/// Set the NSView handler where the media player should render its video output.
|
||||||
pub fn set_nsobject(&self, drawable: *mut c_void) {
|
pub fn set_nsobject(&self, drawable: *mut c_void) {
|
||||||
unsafe{ sys::libvlc_media_player_set_nsobject(self.ptr, drawable) };
|
let d = drawable;
|
||||||
|
unsafe { sys::libvlc_media_player_set_nsobject(self.ptr, d) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the NSView handler previously set with set_nsobject().
|
/// Get the NSView handler previously set with set_nsobject().
|
||||||
pub fn get_nsobject(&self) -> Option<*mut c_void> {
|
pub fn get_nsobject(&self) -> Option<*mut c_void> {
|
||||||
let nso = unsafe{ sys::libvlc_media_player_get_nsobject(self.ptr) };
|
let nso = unsafe { sys::libvlc_media_player_get_nsobject(self.ptr) };
|
||||||
if nso.is_null() { None }else{ Some(nso) }
|
if nso.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(nso)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set an X Window System drawable where the media player should render its video output.
|
/// Set an X Window System drawable where the media player should render its video output.
|
||||||
pub fn set_xwindow(&self, drawable: u32) {
|
pub fn set_xwindow(&self, drawable: u32) {
|
||||||
unsafe{ sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
|
unsafe { sys::libvlc_media_player_set_xwindow(self.ptr, drawable) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the X Window System window identifier previously set with set_xwindow().
|
/// Get the X Window System window identifier previously set with set_xwindow().
|
||||||
pub fn get_xwindow(&self) -> Option<u32> {
|
pub fn get_xwindow(&self) -> Option<u32> {
|
||||||
let id = unsafe{ sys::libvlc_media_player_get_xwindow(self.ptr) };
|
let id = unsafe { sys::libvlc_media_player_get_xwindow(self.ptr) };
|
||||||
if id == 0 { None }else{ Some(id) }
|
if id == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a Win32/Win64 API window handle (HWND) where the media player should render its video output.
|
/// Set a Win32/Win64 API window handle (HWND) where the media player should render its video output.
|
||||||
/// If LibVLC was built without Win32/Win64 API output support, then this has no effects.
|
/// If LibVLC was built without Win32/Win64 API output support, then this has no effects.
|
||||||
pub fn set_hwnd(&self, drawable: *mut c_void) {
|
pub fn set_hwnd(&self, drawable: *mut c_void) {
|
||||||
unsafe{ sys::libvlc_media_player_set_hwnd(self.ptr, drawable) };
|
let d = drawable;
|
||||||
|
unsafe { sys::libvlc_media_player_set_hwnd(self.ptr, d) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the Windows API window handle (HWND) previously set with set_hwnd().
|
/// Get the Windows API window handle (HWND) previously set with set_hwnd().
|
||||||
pub fn get_hwnd(&self) -> Option<*mut c_void> {
|
pub fn get_hwnd(&self) -> Option<*mut c_void> {
|
||||||
let hwnd = unsafe{ sys::libvlc_media_player_get_hwnd(self.ptr) };
|
let hwnd = unsafe { sys::libvlc_media_player_get_hwnd(self.ptr) };
|
||||||
if hwnd.is_null() { None }else{ Some(hwnd) }
|
if hwnd.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(hwnd)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current movie time (in ms).
|
/// Get the current movie time (in ms).
|
||||||
pub fn get_time(&self) -> Option<i64> {
|
pub fn get_time(&self) -> Option<i64> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let t = sys::libvlc_media_player_get_time(self.ptr);
|
let t = sys::libvlc_media_player_get_time(self.ptr);
|
||||||
if t == -1 { None }else{ Some(t) }
|
if t == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the movie time (in ms).
|
/// Set the movie time (in ms).
|
||||||
/// This has no effect if no media is being played. Not all formats and protocols support this.
|
/// This has no effect if no media is being played. Not all formats and protocols support this.
|
||||||
pub fn set_time(&self, time: i64) {
|
pub fn set_time(&self, time: i64) {
|
||||||
unsafe{ sys::libvlc_media_player_set_time(self.ptr, time); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_set_time(self.ptr, time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get movie position as percentage between 0.0 and 1.0.
|
/// Get movie position as percentage between 0.0 and 1.0.
|
||||||
pub fn get_position(&self) -> Option<f32> {
|
pub fn get_position(&self) -> Option<f32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let pos = sys::libvlc_media_player_get_position(self.ptr);
|
let pos = sys::libvlc_media_player_get_position(self.ptr);
|
||||||
if pos == -1f32 { None }else{ Some(pos) }
|
// if pos == -1f32 { None }else{ Some(pos) }
|
||||||
|
if (pos - -1f32).abs() < f32::EPSILON {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set movie position as percentage between 0.0 and 1.0.
|
/// Set movie position as percentage between 0.0 and 1.0.
|
||||||
/// This has no effect if playback is not enabled. This might not work depending on the underlying input format and protocol.
|
/// This has no effect if playback is not enabled. This might not work depending on the underlying input format and protocol.
|
||||||
pub fn set_position(&self, pos: f32) {
|
pub fn set_position(&self, pos: f32) {
|
||||||
unsafe{ sys::libvlc_media_player_set_position(self.ptr, pos); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_set_position(self.ptr, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set movie chapter (if applicable).
|
/// Set movie chapter (if applicable).
|
||||||
pub fn set_chapter(&self, chapter: i32) {
|
pub fn set_chapter(&self, chapter: i32) {
|
||||||
unsafe{ sys::libvlc_media_player_set_chapter(self.ptr, chapter); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_set_chapter(self.ptr, chapter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get movie chapter.
|
/// Get movie chapter.
|
||||||
pub fn get_chapter(&self) -> Option<i32> {
|
pub fn get_chapter(&self) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let c = sys::libvlc_media_player_get_chapter(self.ptr);
|
let c = sys::libvlc_media_player_get_chapter(self.ptr);
|
||||||
if c == -1 { None }else{ Some(c) }
|
if c == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get movie chapter count.
|
/// Get movie chapter count.
|
||||||
pub fn chapter_count(&self) -> Option<i32> {
|
pub fn chapter_count(&self) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let c = sys::libvlc_media_player_get_chapter_count(self.ptr);
|
let c = sys::libvlc_media_player_get_chapter_count(self.ptr);
|
||||||
if c == -1 { None }else{ Some(c) }
|
if c == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is the player able to play.
|
/// Is the player able to play.
|
||||||
pub fn will_play(&self) -> bool {
|
pub fn will_play(&self) -> bool {
|
||||||
unsafe{
|
unsafe { sys::libvlc_media_player_will_play(self.ptr) != 0 }
|
||||||
let b = sys::libvlc_media_player_will_play(self.ptr);
|
|
||||||
if b == 0 { false }else{ true }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get title chapter count.
|
/// Get title chapter count.
|
||||||
pub fn chapter_count_for_title(&self, title: i32) -> Option<i32> {
|
pub fn chapter_count_for_title(&self, title: i32) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let c = sys::libvlc_media_player_get_chapter_count_for_title(self.ptr, title);
|
let c = sys::libvlc_media_player_get_chapter_count_for_title(self.ptr, title);
|
||||||
if c == -1 { None }else{ Some(c) }
|
if c == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set movie title.
|
/// Set movie title.
|
||||||
pub fn set_title(&self, title: i32) {
|
pub fn set_title(&self, title: i32) {
|
||||||
unsafe{ sys::libvlc_media_player_set_title(self.ptr, title); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_set_title(self.ptr, title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get movie title.
|
/// Get movie title.
|
||||||
pub fn get_title(&self) -> Option<i32> {
|
pub fn get_title(&self) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let t = sys::libvlc_media_player_get_title(self.ptr);
|
let t = sys::libvlc_media_player_get_title(self.ptr);
|
||||||
if t == -1 { None }else{ Some(t) }
|
if t == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get movie title count.
|
/// Get movie title count.
|
||||||
pub fn title_count(&self) -> Option<i32> {
|
pub fn title_count(&self) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let t = sys::libvlc_media_player_get_title_count(self.ptr);
|
let t = sys::libvlc_media_player_get_title_count(self.ptr);
|
||||||
if t == -1 { Some(t) } else { None }
|
if t == -1 {
|
||||||
|
Some(t)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set previous chapter (if applicable)
|
/// Set previous chapter (if applicable)
|
||||||
pub fn previous_chapter(&self) {
|
pub fn previous_chapter(&self) {
|
||||||
unsafe{ sys::libvlc_media_player_previous_chapter(self.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_previous_chapter(self.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set next chapter (if applicable)
|
/// Set next chapter (if applicable)
|
||||||
pub fn next_chapter(&self) {
|
pub fn next_chapter(&self) {
|
||||||
unsafe{ sys::libvlc_media_player_next_chapter(self.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_next_chapter(self.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the requested movie play rate.
|
/// Get the requested movie play rate.
|
||||||
pub fn get_rate(&self) -> f32 {
|
pub fn get_rate(&self) -> f32 {
|
||||||
unsafe{ sys::libvlc_media_player_get_rate(self.ptr) }
|
unsafe { sys::libvlc_media_player_get_rate(self.ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set movie play rate.
|
/// Set movie play rate.
|
||||||
pub fn set_rate(&self, rate: f32) -> Result<(),()> {
|
pub fn set_rate(&self, rate: f32) -> Result<(), InternalError> {
|
||||||
unsafe{
|
unsafe {
|
||||||
if sys::libvlc_media_player_set_rate(self.ptr, rate) == -1 {
|
if sys::libvlc_media_player_set_rate(self.ptr, rate) == -1 {
|
||||||
Err(())
|
Err(InternalError)
|
||||||
}else{
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,51 +340,48 @@ impl MediaPlayer {
|
||||||
|
|
||||||
/// Get current movie state.
|
/// Get current movie state.
|
||||||
pub fn state(&self) -> State {
|
pub fn state(&self) -> State {
|
||||||
unsafe{ sys::libvlc_media_player_get_state(self.ptr) }.into()
|
unsafe { sys::libvlc_media_player_get_state(self.ptr) }.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// How many video outputs does this media player have?
|
/// How many video outputs does this media player have?
|
||||||
pub fn has_vout(&self) -> u32 {
|
pub fn has_vout(&self) -> u32 {
|
||||||
unsafe{ sys::libvlc_media_player_has_vout(self.ptr) }
|
unsafe { sys::libvlc_media_player_has_vout(self.ptr) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Is this media player seekable?
|
/// Is this media player seekable?
|
||||||
pub fn is_seekable(&self) -> bool {
|
pub fn is_seekable(&self) -> bool {
|
||||||
unsafe{
|
unsafe { sys::libvlc_media_player_is_seekable(self.ptr) != 0 }
|
||||||
let b = sys::libvlc_media_player_is_seekable(self.ptr);
|
|
||||||
if b == 0 { false }else{ true }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can this media player be paused?
|
/// Can this media player be paused?
|
||||||
pub fn can_pause(&self) -> bool {
|
pub fn can_pause(&self) -> bool {
|
||||||
unsafe{
|
unsafe { sys::libvlc_media_player_can_pause(self.ptr) != 0 }
|
||||||
let b = sys::libvlc_media_player_can_pause(self.ptr);
|
|
||||||
if b == 0 { false }else{ true }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the current program is scrambled.
|
/// Check if the current program is scrambled.
|
||||||
pub fn program_scrambled(&self) -> bool {
|
pub fn program_scrambled(&self) -> bool {
|
||||||
unsafe{
|
unsafe { sys::libvlc_media_player_program_scrambled(self.ptr) != 0 }
|
||||||
let b = sys::libvlc_media_player_program_scrambled(self.ptr);
|
|
||||||
if b == 0 { false }else{ true }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Display the next frame (if supported)
|
/// Display the next frame (if supported)
|
||||||
pub fn next_frame(&self) {
|
pub fn next_frame(&self) {
|
||||||
unsafe{ sys::libvlc_media_player_next_frame(self.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_next_frame(self.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Navigate through DVD Menu.
|
/// Navigate through DVD Menu.
|
||||||
pub fn navigate(&self, navigate: u32) {
|
pub fn navigate(&self, navigate: u32) {
|
||||||
unsafe{ sys::libvlc_media_player_navigate(self.ptr, navigate); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_navigate(self.ptr, navigate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set if, and how, the video title will be shown when media is played.
|
/// Set if, and how, the video title will be shown when media is played.
|
||||||
pub fn set_video_title_display(&self, position: Position, timeout: u32) {
|
pub fn set_video_title_display(&self, position: Position, timeout: u32) {
|
||||||
unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position as i32, timeout); }
|
unsafe {
|
||||||
|
sys::libvlc_media_player_set_video_title_display(self.ptr, position as i32, timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns raw pointer
|
/// Returns raw pointer
|
||||||
|
@ -322,7 +392,7 @@ impl MediaPlayer {
|
||||||
|
|
||||||
impl Drop for MediaPlayer {
|
impl Drop for MediaPlayer {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe{ sys::libvlc_media_player_release(self.ptr) };
|
unsafe { sys::libvlc_media_player_release(self.ptr) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,10 +406,13 @@ struct AudioCallbacksData {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn audio_cb_play(
|
unsafe extern "C" fn audio_cb_play(
|
||||||
data: *mut c_void, samples: *const c_void, count: c_uint, pts: i64) {
|
data: *mut c_void,
|
||||||
|
samples: *const c_void,
|
||||||
|
count: c_uint,
|
||||||
|
pts: i64,
|
||||||
|
) {
|
||||||
let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
|
let data: &AudioCallbacksData = transmute(data as *mut AudioCallbacksData);
|
||||||
(data.play)(samples, count, pts);
|
(data.play)(samples, count, pts);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn audio_cb_pause(data: *mut c_void, pts: i64) {
|
unsafe extern "C" fn audio_cb_pause(data: *mut c_void, pts: i64) {
|
||||||
|
@ -367,4 +440,3 @@ pub struct TrackDescription {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
src/tools.rs
14
src/tools.rs
|
@ -2,10 +2,10 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
use std::ffi::{CString, CStr, NulError};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::borrow::Cow;
|
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::ffi::{CStr, CString, NulError};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
// Convert String to CString.
|
// Convert String to CString.
|
||||||
// Panic if the string includes null bytes.
|
// Panic if the string includes null bytes.
|
||||||
|
@ -16,8 +16,8 @@ pub fn to_cstr(s: &str) -> CString {
|
||||||
// Convert *const c_char to String
|
// Convert *const c_char to String
|
||||||
pub unsafe fn from_cstr(p: *const c_char) -> Option<String> {
|
pub unsafe fn from_cstr(p: *const c_char) -> Option<String> {
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
None
|
None
|
||||||
}else{
|
} else {
|
||||||
let cstr = CStr::from_ptr(p);
|
let cstr = CStr::from_ptr(p);
|
||||||
|
|
||||||
Some(cstr.to_string_lossy().into_owned())
|
Some(cstr.to_string_lossy().into_owned())
|
||||||
|
@ -27,8 +27,8 @@ pub unsafe fn from_cstr(p: *const c_char) -> Option<String> {
|
||||||
// Convert *const c_char to &str
|
// Convert *const c_char to &str
|
||||||
pub unsafe fn from_cstr_ref<'a>(p: *const c_char) -> Option<Cow<'a, str>> {
|
pub unsafe fn from_cstr_ref<'a>(p: *const c_char) -> Option<Cow<'a, str>> {
|
||||||
if p.is_null() {
|
if p.is_null() {
|
||||||
None
|
None
|
||||||
}else{
|
} else {
|
||||||
let cstr = CStr::from_ptr(p);
|
let cstr = CStr::from_ptr(p);
|
||||||
|
|
||||||
Some(cstr.to_string_lossy())
|
Some(cstr.to_string_lossy())
|
||||||
|
|
91
src/video.rs
91
src/video.rs
|
@ -2,12 +2,12 @@
|
||||||
// This file is part of vlc-rs.
|
// This file is part of vlc-rs.
|
||||||
// Licensed under the MIT license, see the LICENSE file.
|
// Licensed under the MIT license, see the LICENSE file.
|
||||||
|
|
||||||
use vlc_sys as sys;
|
use crate::enums::VideoAdjustOption;
|
||||||
|
use crate::tools::{from_cstr, to_cstr};
|
||||||
use crate::MediaPlayer;
|
use crate::MediaPlayer;
|
||||||
use crate::TrackDescription;
|
use crate::TrackDescription;
|
||||||
use crate::enums::VideoAdjustOption;
|
|
||||||
use crate::tools::{to_cstr, from_cstr};
|
|
||||||
use libc::c_void;
|
use libc::c_void;
|
||||||
|
use vlc_sys as sys;
|
||||||
|
|
||||||
pub trait MediaPlayerVideoEx {
|
pub trait MediaPlayerVideoEx {
|
||||||
fn toggle_fullscreen(&self);
|
fn toggle_fullscreen(&self);
|
||||||
|
@ -32,77 +32,108 @@ pub trait MediaPlayerVideoEx {
|
||||||
|
|
||||||
impl MediaPlayerVideoEx for MediaPlayer {
|
impl MediaPlayerVideoEx for MediaPlayer {
|
||||||
fn toggle_fullscreen(&self) {
|
fn toggle_fullscreen(&self) {
|
||||||
unsafe{ sys::libvlc_toggle_fullscreen(self.ptr); }
|
unsafe {
|
||||||
|
sys::libvlc_toggle_fullscreen(self.ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn set_fullscreen(&self, fullscreen: bool) {
|
fn set_fullscreen(&self, fullscreen: bool) {
|
||||||
unsafe{ sys::libvlc_set_fullscreen(self.ptr, if fullscreen { 1 }else{ 0 }); }
|
unsafe {
|
||||||
|
sys::libvlc_set_fullscreen(self.ptr, if fullscreen { 1 } else { 0 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn get_fullscreen(&self) -> bool {
|
fn get_fullscreen(&self) -> bool {
|
||||||
unsafe{ if sys::libvlc_get_fullscreen(self.ptr) == 0 { false }else{ true } }
|
unsafe { sys::libvlc_get_fullscreen(self.ptr) != 0 }
|
||||||
}
|
}
|
||||||
fn set_key_input(&self, on: bool) {
|
fn set_key_input(&self, on: bool) {
|
||||||
unsafe{ sys::libvlc_video_set_key_input(self.ptr, if on { 1 }else{ 0 }); }
|
unsafe {
|
||||||
|
sys::libvlc_video_set_key_input(self.ptr, if on { 1 } else { 0 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn set_mouse_input(&self, on: bool) {
|
fn set_mouse_input(&self, on: bool) {
|
||||||
unsafe{ sys::libvlc_video_set_mouse_input(self.ptr, if on { 1 }else{ 0 }); }
|
unsafe {
|
||||||
|
sys::libvlc_video_set_mouse_input(self.ptr, if on { 1 } else { 0 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn get_size(&self, num: u32) -> Option<(u32, u32)> {
|
fn get_size(&self, num: u32) -> Option<(u32, u32)> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
let res = sys::libvlc_video_get_size(self.ptr, num, &mut x, &mut y);
|
let res = sys::libvlc_video_get_size(self.ptr, num, &mut x, &mut y);
|
||||||
if res == -1 { None }else{ Some((x, y)) }
|
if res == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((x, y))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_cursor(&self, num: u32) -> Option<(i32, i32)> {
|
fn get_cursor(&self, num: u32) -> Option<(i32, i32)> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let mut y = 0;
|
let mut y = 0;
|
||||||
let res = sys::libvlc_video_get_cursor(self.ptr, num, &mut x, &mut y);
|
let res = sys::libvlc_video_get_cursor(self.ptr, num, &mut x, &mut y);
|
||||||
if res == -1 { None }else{ Some((x, y)) }
|
if res == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some((x, y))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_scale(&self) -> f32 {
|
fn get_scale(&self) -> f32 {
|
||||||
unsafe{ sys::libvlc_video_get_scale(self.ptr) }
|
unsafe { sys::libvlc_video_get_scale(self.ptr) }
|
||||||
}
|
}
|
||||||
fn set_scale(&self, factor: f32) {
|
fn set_scale(&self, factor: f32) {
|
||||||
unsafe{ sys::libvlc_video_set_scale(self.ptr, factor); }
|
unsafe {
|
||||||
|
sys::libvlc_video_set_scale(self.ptr, factor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn get_video_track(&self) -> Option<i32> {
|
fn get_video_track(&self) -> Option<i32> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let track = sys::libvlc_video_get_track(self.ptr);
|
let track = sys::libvlc_video_get_track(self.ptr);
|
||||||
if track == -1 { None }else{ Some(track) }
|
if track == -1 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(track)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn set_video_track(&self, track: i32) {
|
fn set_video_track(&self, track: i32) {
|
||||||
unsafe{ sys::libvlc_video_set_track(self.ptr, track); }
|
unsafe {
|
||||||
|
sys::libvlc_video_set_track(self.ptr, track);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn get_aspect_ratio(&self) -> Option<String> {
|
fn get_aspect_ratio(&self) -> Option<String> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p = sys::libvlc_video_get_aspect_ratio(self.ptr);
|
let p = sys::libvlc_video_get_aspect_ratio(self.ptr);
|
||||||
let s = from_cstr(p);
|
let s = from_cstr(p);
|
||||||
if !p.is_null() { sys::libvlc_free(p as *mut c_void); }
|
if !p.is_null() {
|
||||||
|
sys::libvlc_free(p as *mut c_void);
|
||||||
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn set_aspect_ratio(&self, aspect: Option<&str>) {
|
fn set_aspect_ratio(&self, aspect: Option<&str>) {
|
||||||
unsafe{
|
unsafe {
|
||||||
if let Some(a) = aspect {
|
if let Some(a) = aspect {
|
||||||
sys::libvlc_video_set_aspect_ratio(self.ptr, to_cstr(a).as_ptr());
|
sys::libvlc_video_set_aspect_ratio(self.ptr, to_cstr(a).as_ptr());
|
||||||
}else{
|
} else {
|
||||||
sys::libvlc_video_set_aspect_ratio(self.ptr, ::std::ptr::null());
|
sys::libvlc_video_set_aspect_ratio(self.ptr, ::std::ptr::null());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_video_track_description(&self) -> Option<Vec<TrackDescription>> {
|
fn get_video_track_description(&self) -> Option<Vec<TrackDescription>> {
|
||||||
unsafe{
|
unsafe {
|
||||||
let p0 = sys::libvlc_video_get_track_description(self.ptr);
|
let p0 = sys::libvlc_video_get_track_description(self.ptr);
|
||||||
if p0.is_null() { return None; }
|
if p0.is_null() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let mut td = Vec::new();
|
let mut td = Vec::new();
|
||||||
let mut p = p0;
|
let mut p = p0;
|
||||||
|
|
||||||
while !(*p).p_next.is_null() {
|
while !(*p).p_next.is_null() {
|
||||||
td.push(TrackDescription{ id: (*p).i_id, name: from_cstr((*p).psz_name) });
|
td.push(TrackDescription {
|
||||||
|
id: (*p).i_id,
|
||||||
|
name: from_cstr((*p).psz_name),
|
||||||
|
});
|
||||||
p = (*p).p_next;
|
p = (*p).p_next;
|
||||||
}
|
}
|
||||||
sys::libvlc_track_description_list_release(p0);
|
sys::libvlc_track_description_list_release(p0);
|
||||||
|
@ -110,15 +141,19 @@ impl MediaPlayerVideoEx for MediaPlayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_adjust_int(&self, option: VideoAdjustOption) -> i32 {
|
fn get_adjust_int(&self, option: VideoAdjustOption) -> i32 {
|
||||||
unsafe{ sys::libvlc_video_get_adjust_int(self.ptr, option as u32) }
|
unsafe { sys::libvlc_video_get_adjust_int(self.ptr, option as u32) }
|
||||||
}
|
}
|
||||||
fn set_adjust_int(&self, option: VideoAdjustOption, value: i32) {
|
fn set_adjust_int(&self, option: VideoAdjustOption, value: i32) {
|
||||||
unsafe{ sys::libvlc_video_set_adjust_int(self.ptr, option as u32, value); }
|
unsafe {
|
||||||
|
sys::libvlc_video_set_adjust_int(self.ptr, option as u32, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn get_adjust_float(&self, option: VideoAdjustOption) -> f32 {
|
fn get_adjust_float(&self, option: VideoAdjustOption) -> f32 {
|
||||||
unsafe{ sys::libvlc_video_get_adjust_float(self.ptr, option as u32) }
|
unsafe { sys::libvlc_video_get_adjust_float(self.ptr, option as u32) }
|
||||||
}
|
}
|
||||||
fn set_adjust_float(&self, option: VideoAdjustOption, value: f32) {
|
fn set_adjust_float(&self, option: VideoAdjustOption, value: f32) {
|
||||||
unsafe{ sys::libvlc_video_set_adjust_float(self.ptr, option as u32, value); }
|
unsafe {
|
||||||
|
sys::libvlc_video_set_adjust_float(self.ptr, option as u32, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
241
src/vlm.rs
241
src/vlm.rs
|
@ -2,34 +2,57 @@ use std::ffi::CString;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use vlc_sys as sys;
|
|
||||||
use crate::Instance;
|
|
||||||
use crate::tools::{from_cstr, to_cstr};
|
use crate::tools::{from_cstr, to_cstr};
|
||||||
|
use crate::{Instance, InternalError};
|
||||||
|
use vlc_sys as sys;
|
||||||
|
|
||||||
pub trait Vlm {
|
pub trait Vlm {
|
||||||
fn add_broadcast(&self, name: &str, input: &str, output: &str, options: Option<Vec<String>>, enabled: bool, loop_broadcast: bool, ) -> Result<(), ()>;
|
fn add_broadcast(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
input: &str,
|
||||||
|
output: &str,
|
||||||
|
options: Option<Vec<String>>,
|
||||||
|
enabled: bool,
|
||||||
|
loop_broadcast: bool,
|
||||||
|
) -> Result<(), InternalError>;
|
||||||
|
|
||||||
fn add_vod(&self, name: &str, input: &str, mux: &str, options: Option<Vec<String>>, enabled: bool) -> Result<(), ()>;
|
fn add_vod(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
input: &str,
|
||||||
|
mux: &str,
|
||||||
|
options: Option<Vec<String>>,
|
||||||
|
enabled: bool,
|
||||||
|
) -> Result<(), InternalError>;
|
||||||
|
|
||||||
fn play_media(&self, name: &str) -> Result<(), ()>;
|
fn play_media(&self, name: &str) -> Result<(), InternalError>;
|
||||||
|
|
||||||
fn pause_media(&self, name: &str) -> Result<(), ()>;
|
fn pause_media(&self, name: &str) -> Result<(), InternalError>;
|
||||||
|
|
||||||
fn stop_media(&self, name: &str) -> Result<(), ()>;
|
fn stop_media(&self, name: &str) -> Result<(), InternalError>;
|
||||||
|
|
||||||
fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, ()>;
|
fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, InternalError>;
|
||||||
|
|
||||||
fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, ()>;
|
fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, InternalError>;
|
||||||
|
|
||||||
fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, ()>;
|
fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, InternalError>;
|
||||||
|
|
||||||
fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, ()>;
|
fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, InternalError>;
|
||||||
|
|
||||||
fn show_media(&self, name: &str) -> Result<String, ()>;
|
fn show_media(&self, name: &str) -> Result<String, InternalError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vlm for Instance {
|
impl Vlm for Instance {
|
||||||
fn add_broadcast(&self, name: &str, input: &str, output: &str, options: Option<Vec<String>>, enabled: bool, loop_broadcast: bool, ) -> Result<(), ()> {
|
fn add_broadcast(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
input: &str,
|
||||||
|
output: &str,
|
||||||
|
options: Option<Vec<String>>,
|
||||||
|
enabled: bool,
|
||||||
|
loop_broadcast: bool,
|
||||||
|
) -> Result<(), InternalError> {
|
||||||
let name = to_cstr(name);
|
let name = to_cstr(name);
|
||||||
let input = to_cstr(input);
|
let input = to_cstr(input);
|
||||||
let output = to_cstr(output);
|
let output = to_cstr(output);
|
||||||
|
@ -38,23 +61,54 @@ impl Vlm for Instance {
|
||||||
let enabled = if enabled { 1 } else { 0 };
|
let enabled = if enabled { 1 } else { 0 };
|
||||||
let loop_broadcast = if loop_broadcast { 1 } else { 0 };
|
let loop_broadcast = if loop_broadcast { 1 } else { 0 };
|
||||||
if let Some(vec) = options {
|
if let Some(vec) = options {
|
||||||
opts_c = vec.into_iter()
|
opts_c = vec
|
||||||
.map(|x| CString::new(x).expect("Error: Unexpected null byte")).collect();
|
.into_iter()
|
||||||
|
.map(|x| CString::new(x).expect("Error: Unexpected null byte"))
|
||||||
|
.collect();
|
||||||
opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
|
opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
|
||||||
} else {
|
} else {
|
||||||
opts_c_ptr = Vec::new();
|
opts_c_ptr = Vec::new();
|
||||||
}
|
}
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
if opts_c_ptr.is_empty() {
|
if opts_c_ptr.is_empty() {
|
||||||
sys::libvlc_vlm_add_broadcast(self.ptr, name.as_ptr(), input.as_ptr(), output.as_ptr(), 0, ptr::null(), enabled, loop_broadcast)
|
sys::libvlc_vlm_add_broadcast(
|
||||||
|
self.ptr,
|
||||||
|
name.as_ptr(),
|
||||||
|
input.as_ptr(),
|
||||||
|
output.as_ptr(),
|
||||||
|
0,
|
||||||
|
ptr::null(),
|
||||||
|
enabled,
|
||||||
|
loop_broadcast,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
sys::libvlc_vlm_add_broadcast(self.ptr, name.as_ptr(), input.as_ptr(), output.as_ptr(), opts_c_ptr.len() as i32, opts_c_ptr.as_ptr(), enabled, loop_broadcast)
|
sys::libvlc_vlm_add_broadcast(
|
||||||
|
self.ptr,
|
||||||
|
name.as_ptr(),
|
||||||
|
input.as_ptr(),
|
||||||
|
output.as_ptr(),
|
||||||
|
opts_c_ptr.len() as i32,
|
||||||
|
opts_c_ptr.as_ptr(),
|
||||||
|
enabled,
|
||||||
|
loop_broadcast,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if result == 0 { Ok(()) } else { Err(()) }
|
if result == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_vod(&self, name: &str, input: &str, mux: &str, options: Option<Vec<String>>, enabled: bool) -> Result<(), ()> {
|
fn add_vod(
|
||||||
|
&self,
|
||||||
|
name: &str,
|
||||||
|
input: &str,
|
||||||
|
mux: &str,
|
||||||
|
options: Option<Vec<String>>,
|
||||||
|
enabled: bool,
|
||||||
|
) -> Result<(), InternalError> {
|
||||||
let name = to_cstr(name);
|
let name = to_cstr(name);
|
||||||
let input = to_cstr(input);
|
let input = to_cstr(input);
|
||||||
let mux = to_cstr(mux);
|
let mux = to_cstr(mux);
|
||||||
|
@ -63,86 +117,125 @@ impl Vlm for Instance {
|
||||||
let enabled = if enabled { 1 } else { 0 };
|
let enabled = if enabled { 1 } else { 0 };
|
||||||
if let Some(vec) = options {
|
if let Some(vec) = options {
|
||||||
opts_c = vec.into_iter()
|
opts_c = vec.into_iter()
|
||||||
.map(|x| CString::new(x).expect("Error: Unexpected null byte")).collect();
|
.map(|x| CString::new(x).expect("Error: Unexpected null byte"))
|
||||||
|
.collect();
|
||||||
opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
|
opts_c_ptr = opts_c.iter().map(|x| x.as_ptr()).collect();
|
||||||
} else {
|
} else {
|
||||||
opts_c_ptr = Vec::new();
|
opts_c_ptr = Vec::new();
|
||||||
}
|
}
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
if opts_c_ptr.is_empty() {
|
if opts_c_ptr.is_empty() {
|
||||||
sys::libvlc_vlm_add_vod(self.ptr, name.as_ptr(), input.as_ptr(), 0, ptr::null(), enabled, mux.as_ptr())
|
sys::libvlc_vlm_add_vod(
|
||||||
|
self.ptr,
|
||||||
|
name.as_ptr(),
|
||||||
|
input.as_ptr(),
|
||||||
|
0,
|
||||||
|
ptr::null(),
|
||||||
|
enabled,
|
||||||
|
mux.as_ptr(),
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
sys::libvlc_vlm_add_vod(self.ptr, name.as_ptr(), input.as_ptr(), opts_c_ptr.len() as i32, opts_c_ptr.as_ptr(), enabled, mux.as_ptr())
|
sys::libvlc_vlm_add_vod(
|
||||||
|
self.ptr,
|
||||||
|
name.as_ptr(),
|
||||||
|
input.as_ptr(),
|
||||||
|
opts_c_ptr.len() as i32,
|
||||||
|
opts_c_ptr.as_ptr(),
|
||||||
|
enabled,
|
||||||
|
mux.as_ptr(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if result == 0 { Ok(()) } else { Err(()) }
|
if result == 0 {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn play_media(&self, name: &str) -> Result<(), ()> {
|
fn play_media(&self, name: &str) -> Result<(), InternalError> {
|
||||||
let name = to_cstr(name);
|
let name = to_cstr(name);
|
||||||
let result = unsafe {
|
let result = unsafe { sys::libvlc_vlm_play_media(self.ptr, name.as_ptr()) };
|
||||||
sys::libvlc_vlm_play_media(self.ptr, name.as_ptr())
|
if result == 0 {
|
||||||
};
|
Ok(())
|
||||||
if result == 0 { Ok(()) } else { Err(()) }
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pause_media(&self, name: &str) -> Result<(), ()> {
|
fn pause_media(&self, name: &str) -> Result<(), InternalError> {
|
||||||
let name = to_cstr(name);
|
let name = to_cstr(name);
|
||||||
let result = unsafe {
|
let result = unsafe { sys::libvlc_vlm_pause_media(self.ptr, name.as_ptr()) };
|
||||||
sys::libvlc_vlm_pause_media(self.ptr, name.as_ptr())
|
if result == 0 {
|
||||||
};
|
Ok(())
|
||||||
if result == 0 { Ok(()) } else { Err(()) }
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_media(&self, name: &str) -> Result<(), ()> {
|
fn stop_media(&self, name: &str) -> Result<(), InternalError> {
|
||||||
let name = to_cstr(name);
|
let name = to_cstr(name);
|
||||||
let result = unsafe {
|
let result = unsafe { sys::libvlc_vlm_stop_media(self.ptr, name.as_ptr()) };
|
||||||
sys::libvlc_vlm_stop_media(self.ptr, name.as_ptr())
|
if result == 0 {
|
||||||
};
|
Ok(())
|
||||||
if result == 0 { Ok(()) } else { Err(()) }
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, ()> {
|
fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, InternalError> {
|
||||||
let name = to_cstr(name);
|
let name = to_cstr(name);
|
||||||
let result = unsafe {
|
let result = unsafe {
|
||||||
sys::libvlc_vlm_get_media_instance_position(self.ptr, name.as_ptr(), instance)
|
sys::libvlc_vlm_get_media_instance_position(self.ptr, name.as_ptr(), instance)
|
||||||
};
|
};
|
||||||
if result != -1f32 { Ok(result) } else { Err(()) }
|
// if result != -1f32 { Ok(result) } else { Err(()) }
|
||||||
}
|
if (result - -1f32).abs() < f32::EPSILON {
|
||||||
|
Err(InternalError)
|
||||||
fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, ()> {
|
|
||||||
let name = to_cstr(name);
|
|
||||||
let result = unsafe {
|
|
||||||
sys::libvlc_vlm_get_media_instance_length(self.ptr, name.as_ptr(), instance)
|
|
||||||
};
|
|
||||||
if result != -1 { Ok(result) } else { Err(()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, ()> {
|
|
||||||
let name = to_cstr(name);
|
|
||||||
let result = unsafe {
|
|
||||||
sys::libvlc_vlm_get_media_instance_time(self.ptr, name.as_ptr(), instance)
|
|
||||||
};
|
|
||||||
if result != -1 { Ok(result) } else { Err(()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, ()> {
|
|
||||||
let name = to_cstr(name);
|
|
||||||
let result = unsafe {
|
|
||||||
sys::libvlc_vlm_get_media_instance_rate(self.ptr, name.as_ptr(), instance)
|
|
||||||
};
|
|
||||||
if result != -1 { Ok(result) } else { Err(()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn show_media(&self, name: &str) -> Result<String, ()> {
|
|
||||||
let name = to_cstr(name);
|
|
||||||
let result = unsafe {
|
|
||||||
from_cstr(sys::libvlc_vlm_show_media(self.ptr, name.as_ptr()))
|
|
||||||
};
|
|
||||||
if let Some(data) = result {
|
|
||||||
Ok(data.to_string())
|
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Ok(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, InternalError> {
|
||||||
|
let name = to_cstr(name);
|
||||||
|
let result =
|
||||||
|
unsafe { sys::libvlc_vlm_get_media_instance_length(self.ptr, name.as_ptr(), instance) };
|
||||||
|
if result != -1 {
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, InternalError> {
|
||||||
|
let name = to_cstr(name);
|
||||||
|
let result =
|
||||||
|
unsafe { sys::libvlc_vlm_get_media_instance_time(self.ptr, name.as_ptr(), instance) };
|
||||||
|
if result != -1 {
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, InternalError> {
|
||||||
|
let name = to_cstr(name);
|
||||||
|
let result =
|
||||||
|
unsafe { sys::libvlc_vlm_get_media_instance_rate(self.ptr, name.as_ptr(), instance) };
|
||||||
|
if result != -1 {
|
||||||
|
Ok(result)
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_media(&self, name: &str) -> Result<String, InternalError> {
|
||||||
|
let name = to_cstr(name);
|
||||||
|
let result = unsafe { from_cstr(sys::libvlc_vlm_show_media(self.ptr, name.as_ptr())) };
|
||||||
|
if let Some(data) = result {
|
||||||
|
Ok(data)
|
||||||
|
} else {
|
||||||
|
Err(InternalError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue