Merge pull request #7 from Spiideo/vlm-broadcast

VLM support
merge-requests/7/merge
T. Okubo 2019-11-25 20:34:07 +09:00 committed by GitHub
commit 8e18b13beb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 209 additions and 23 deletions

View File

@ -5,7 +5,7 @@
use std::ptr; use std::ptr;
use std::borrow::Cow; use std::borrow::Cow;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ffi::CString; use std::ffi::{CString, CStr};
use std::i32; use std::i32;
use libc::{c_void, c_char, c_int}; use libc::{c_void, c_char, c_int};
use crate::sys; use crate::sys;
@ -31,6 +31,8 @@ pub struct Instance {
} }
unsafe impl Send for Instance {}
impl Instance { impl Instance {
/// Create and initialize a libvlc instance with specified args. /// Create and initialize a libvlc instance with specified args.
/// Note: args.len() has to be less or equal to i32::MAX /// Note: args.len() has to be less or equal to i32::MAX
@ -119,6 +121,15 @@ impl Instance {
} }
} }
/// Returns the VLM event manager
pub fn vlm_event_manager<'a>(&'a self) -> EventManager<'a> {
unsafe{
let p = sys::libvlc_vlm_get_event_manager(self.ptr);
assert!(!p.is_null());
EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
}
}
/// Set logging callback /// Set logging callback
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));
@ -296,17 +307,17 @@ pub enum Event {
MediaDiscovererStarted, MediaDiscovererStarted,
MediaDiscovererEnded, MediaDiscovererEnded,
VlmMediaAdded, VlmMediaAdded(Option<String>, Option<String>),
VlmMediaRemoved, VlmMediaRemoved(Option<String>, Option<String>),
VlmMediaChanged, VlmMediaChanged(Option<String>, Option<String>),
VlmMediaInstanceStarted, VlmMediaInstanceStarted(Option<String>, Option<String>),
VlmMediaInstanceStopped, VlmMediaInstanceStopped(Option<String>, Option<String>),
VlmMediaInstanceStatusInit, VlmMediaInstanceStatusInit(Option<String>, Option<String>),
VlmMediaInstanceStatusOpening, VlmMediaInstanceStatusOpening(Option<String>, Option<String>),
VlmMediaInstanceStatusPlaying, VlmMediaInstanceStatusPlaying(Option<String>, Option<String>),
VlmMediaInstanceStatusPause, VlmMediaInstanceStatusPause(Option<String>, Option<String>),
VlmMediaInstanceStatusEnd, VlmMediaInstanceStatusEnd(Option<String>, Option<String>),
VlmMediaInstanceStatusError VlmMediaInstanceStatusError(Option<String>, Option<String>)
} }
pub struct EventManager<'a> { pub struct EventManager<'a> {
@ -485,37 +496,59 @@ fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
Event::MediaDiscovererEnded Event::MediaDiscovererEnded
}, },
EventType::VlmMediaAdded => { EventType::VlmMediaAdded => {
Event::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 => { EventType::VlmMediaRemoved => {
Event::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 => { EventType::VlmMediaChanged => {
Event::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 => { EventType::VlmMediaInstanceStarted => {
Event::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 => { EventType::VlmMediaInstanceStopped => {
Event::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 => { EventType::VlmMediaInstanceStatusInit => {
Event::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 => { EventType::VlmMediaInstanceStatusOpening => {
Event::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 => { EventType::VlmMediaInstanceStatusPlaying => {
Event::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 => { EventType::VlmMediaInstanceStatusPause => {
Event::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 => { EventType::VlmMediaInstanceStatusEnd => {
Event::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 => { EventType::VlmMediaInstanceStatusError => {
Event::VlmMediaInstanceStatusError unsafe {
Event::VlmMediaInstanceStatusError(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
}
}, },
} }
} }

View File

@ -15,6 +15,7 @@ mod media_library;
mod enums; mod enums;
mod video; mod video;
mod audio; mod audio;
mod vlm;
pub use crate::enums::*; pub use crate::enums::*;
pub use crate::core::*; pub use crate::core::*;
@ -24,3 +25,4 @@ pub use crate::media_list::*;
pub use crate::media_library::*; pub use crate::media_library::*;
pub use crate::video::*; pub use crate::video::*;
pub use crate::audio::*; pub use crate::audio::*;
pub use crate::vlm::*;

View File

@ -12,6 +12,8 @@ pub struct Media {
pub(crate) ptr: *mut sys::libvlc_media_t, pub(crate) ptr: *mut sys::libvlc_media_t,
} }
unsafe impl Send for Media {}
impl Media { impl Media {
/// Create a media with a certain given media resource location, for instance a valid URL. /// Create a media with a certain given media resource location, for instance a valid URL.
pub fn new_location(instance: &Instance, mrl: &str) -> Option<Media> { pub fn new_location(instance: &Instance, mrl: &str) -> Option<Media> {

View File

@ -15,6 +15,8 @@ pub struct MediaPlayer {
pub(crate) ptr: *mut sys::libvlc_media_player_t, pub(crate) ptr: *mut sys::libvlc_media_player_t,
} }
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> {

147
src/vlm.rs 100644
View File

@ -0,0 +1,147 @@
use std::ffi::CString;
use std::os::raw::c_char;
use std::ptr;
use crate::{Instance, sys};
use crate::tools::{from_cstr, to_cstr};
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_vod(&self, name: &str, input: &str, mux: &str, options: Option<Vec<String>>, enabled: bool) -> Result<(), ()>;
fn play_media(&self, name: &str) -> Result<(), ()>;
fn pause_media(&self, name: &str) -> Result<(), ()>;
fn stop_media(&self, name: &str) -> Result<(), ()>;
fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, ()>;
fn get_media_instance_length(&self, name: &str, instance: i32) -> Result<i32, ()>;
fn get_media_instance_time(&self, name: &str, instance: i32) -> Result<i32, ()>;
fn get_media_instance_rate(&self, name: &str, instance: i32) -> Result<i32, ()>;
fn show_media(&self, name: &str) -> Result<String, ()>;
}
impl Vlm for Instance {
fn add_broadcast(&self, name: &str, input: &str, output: &str, options: Option<Vec<String>>, enabled: bool, loop_broadcast: bool, ) -> Result<(), ()> {
let name = to_cstr(name);
let input = to_cstr(input);
let output = to_cstr(output);
let opts_c_ptr: Vec<*const c_char>;
let opts_c: Vec<CString>;
let enabled = if enabled { 1 } else { 0 };
let loop_broadcast = if loop_broadcast { 1 } else { 0 };
if let Some(vec) = options {
opts_c = vec.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();
} else {
opts_c_ptr = Vec::new();
}
let result = unsafe {
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)
} 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)
}
};
if result == 0 { Ok(()) } else { Err(()) }
}
fn add_vod(&self, name: &str, input: &str, mux: &str, options: Option<Vec<String>>, enabled: bool) -> Result<(), ()> {
let name = to_cstr(name);
let input = to_cstr(input);
let mux = to_cstr(mux);
let opts_c_ptr: Vec<*const c_char>;
let opts_c: Vec<CString>;
let enabled = if enabled { 1 } else { 0 };
if let Some(vec) = options {
opts_c = vec.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();
} else {
opts_c_ptr = Vec::new();
}
let result = unsafe {
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())
} 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())
}
};
if result == 0 { Ok(()) } else { Err(()) }
}
fn play_media(&self, name: &str) -> Result<(), ()> {
let name = to_cstr(name);
let result = unsafe {
sys::libvlc_vlm_play_media(self.ptr, name.as_ptr())
};
if result == 0 { Ok(()) } else { Err(()) }
}
fn pause_media(&self, name: &str) -> Result<(), ()> {
let name = to_cstr(name);
let result = unsafe {
sys::libvlc_vlm_pause_media(self.ptr, name.as_ptr())
};
if result == 0 { Ok(()) } else { Err(()) }
}
fn stop_media(&self, name: &str) -> Result<(), ()> {
let name = to_cstr(name);
let result = unsafe {
sys::libvlc_vlm_stop_media(self.ptr, name.as_ptr())
};
if result == 0 { Ok(()) } else { Err(()) }
}
fn get_media_instance_position(&self, name: &str, instance: i32) -> Result<f32, ()> {
let name = to_cstr(name);
let result = unsafe {
sys::libvlc_vlm_get_media_instance_position(self.ptr, name.as_ptr(), instance)
};
if result != -1f32 { Ok(result) } else { Err(()) }
}
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 {
Err(())
}
}
}