1use sys;
6use ::{Instance, EventManager};
7use ::enums::{State, Meta, TrackType};
8use ::tools::{to_cstr, from_cstr, path_to_cstr};
9use std::path::Path;
10
11pub struct Media {
12 pub(crate) ptr: *mut sys::libvlc_media_t,
13}
14
15impl Media {
16 pub fn new_location(instance: &Instance, mrl: &str) -> Option<Media> {
18 let cstr = to_cstr(mrl);
19
20 unsafe{
21 let p = sys::libvlc_media_new_location(instance.ptr, cstr.as_ptr());
22 if p.is_null() {
23 return None;
24 }
25
26 Some(Media{ptr: p})
27 }
28 }
29
30 pub fn new_path<T: AsRef<Path>>(instance: &Instance, path: T) -> Option<Media> {
32 let cstr = match path_to_cstr(path.as_ref()) {
33 Ok(s) => s,
34 Err(_) => { return None; },
35 };
36
37 unsafe{
38 let p = sys::libvlc_media_new_path(instance.ptr, cstr.as_ptr());
39 if p.is_null() {
40 return None;
41 }
42
43 Some(Media{ptr: p})
44 }
45 }
46
47 pub fn new_fd(instance: &Instance, fd: i32) -> Option<Media> {
48 unsafe{
49 let p = sys::libvlc_media_new_fd(instance.ptr, fd);
50 if p.is_null() {
51 return None;
52 }
53
54 Some(Media{ptr: p})
55 }
56 }
57
58 pub fn mrl(&self) -> Option<String> {
59 unsafe{
60 let p_str = sys::libvlc_media_get_mrl(self.ptr);
61 let s = from_cstr(p_str);
62 sys::libvlc_free(p_str as *mut ::libc::c_void);
63 s
64 }
65 }
66
67 pub fn event_manager<'a>(&'a self) -> EventManager<'a> {
68 unsafe{
69 let p = sys::libvlc_media_event_manager(self.ptr);
70 assert!(!p.is_null());
71 EventManager{ptr: p, _phantomdata: ::std::marker::PhantomData}
72 }
73 }
74
75 pub fn get_meta(&self, meta: Meta) -> Option<String> {
78 unsafe{
79 let p_str = sys::libvlc_media_get_meta(self.ptr, meta);
80 let s = from_cstr(p_str);
81 sys::libvlc_free(p_str as *mut ::libc::c_void);
82 s
83 }
84 }
85
86 pub fn set_meta(&self, meta: Meta, value: &str) {
89 unsafe{
90 sys::libvlc_media_set_meta(self.ptr, meta, to_cstr(value).as_ptr());
91 }
92 }
93
94 pub fn save_meta(&self) -> bool {
96 if unsafe{ sys::libvlc_media_save_meta(self.ptr) } == 0 { false }else{ true }
97 }
98
99 pub fn state(&self) -> State {
101 unsafe{ sys::libvlc_media_get_state(self.ptr) }
102 }
103
104 pub fn duration(&self) -> Option<i64> {
106 let time = unsafe{
107 sys::libvlc_media_get_duration(self.ptr)
108 };
109 if time != -1 { Some(time) }else{ None }
110 }
111
112 pub fn parse(&self) {
114 unsafe{ sys::libvlc_media_parse(self.ptr) };
115 }
116
117 pub fn parse_async(&self) {
119 unsafe{ sys::libvlc_media_parse_async(self.ptr) };
120 }
121
122 pub fn is_parsed(&self) -> bool {
124 if unsafe{ sys::libvlc_media_is_parsed(self.ptr) } == 0 { false }else{ true }
125 }
126
127 pub fn tracks(&self) -> Option<Vec<MediaTrack>> {
128 unsafe{
129 let mut p_track: *mut *mut sys::libvlc_media_track_t = ::std::ptr::null_mut();
130 let n = sys::libvlc_media_tracks_get(self.ptr, &mut p_track);
131 if n == 0 {
132 return None;
133 }
134
135 let mut track = Vec::new();
136
137 for i in 0..n {
138 let p = p_track.offset(i as isize);
139 let type_specific_data = match (**p).i_type {
140 TrackType::Audio => {
141 let audio = (**p).audio();
142 MediaTrackUnion::Audio(AudioTrack{
143 channels: (*audio).i_channels,
144 rate: (*audio).i_rate,
145 })
146 },
147 TrackType::Video => {
148 let video = (**p).video();
149 MediaTrackUnion::Video(VideoTrack{
150 height: (*video).i_height,
151 width: (*video).i_width,
152 sar_num: (*video).i_sar_num,
153 sar_den: (*video).i_sar_den,
154 frame_rate_num: (*video).i_frame_rate_num,
155 frame_rate_den: (*video).i_frame_rate_den,
156 })
157 },
158 TrackType::Text => {
159 let subtitle = (**p).subtitle();
160 MediaTrackUnion::Subtitle(SubtitleTrack{
161 encoding: from_cstr((*subtitle).psz_encoding)
162 })
163 },
164 TrackType::Unknown => MediaTrackUnion::None,
165 };
166 track.push(MediaTrack{
167 codec: (**p).i_codec,
168 original_fourcc: (**p).i_original_fourcc,
169 id: (**p).i_id,
170 track_type: (**p).i_type,
171 profile: (**p).i_profile,
172 level: (**p).i_level,
173 bitrate: (**p).i_bitrate,
174 language: from_cstr((**p).psz_language),
175 description: from_cstr((**p).psz_description),
176 type_specific_data: type_specific_data,
177 });
178 }
179
180 sys::libvlc_media_tracks_release(p_track, n);
181 Some(track)
182 }
183 }
184
185 pub fn raw(&self) -> *mut sys::libvlc_media_t {
187 self.ptr
188 }
189}
190
191impl Drop for Media {
192 fn drop(&mut self) {
193 unsafe{ sys::libvlc_media_release(self.ptr) };
194 }
195}
196
197#[derive(Clone, PartialEq, Eq, Hash, Debug)]
198pub struct MediaTrack {
199 pub codec: u32,
200 pub original_fourcc: u32,
201 pub id: i32,
202 pub track_type: TrackType,
203 pub profile: i32,
204 pub level: i32,
205 pub bitrate: u32,
206 pub language: Option<String>,
207 pub description: Option<String>,
208 pub type_specific_data: MediaTrackUnion,
209}
210
211#[derive(Clone, PartialEq, Eq, Hash, Debug)]
212pub enum MediaTrackUnion {
213 Audio(AudioTrack), Video(VideoTrack), Subtitle(SubtitleTrack), None,
214}
215
216#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
217pub struct AudioTrack {
218 pub channels: u32,
219 pub rate: u32,
220}
221
222#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
223pub struct VideoTrack {
224 pub height: u32,
225 pub width: u32,
226 pub sar_num: u32,
227 pub sar_den: u32,
228 pub frame_rate_num: u32,
229 pub frame_rate_den: u32,
230}
231
232#[derive(Clone, PartialEq, Eq, Hash, Debug)]
233pub struct SubtitleTrack {
234 pub encoding: Option<String>,
235}
236