vlc/
media.rs

1// Copyright (c) 2015 T. Okubo
2// This file is part of vlc-rs.
3// Licensed under the MIT license, see the LICENSE file.
4
5use 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    /// Create a media with a certain given media resource location, for instance a valid URL. 
17    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    /// Create a media for a certain file path. 
31    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    /// Read the meta of the media.
76    /// If the media has not yet been parsed this will return None.
77    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    /// Set the meta of the media.
87    /// (This function will not save the meta, call save_meta in order to save the meta) 
88    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    /// Save the meta previously set.
95    pub fn save_meta(&self) -> bool {
96        if unsafe{ sys::libvlc_media_save_meta(self.ptr) } == 0 { false }else{ true }
97    }
98
99    /// Get current state of media descriptor object.
100    pub fn state(&self) -> State {
101        unsafe{ sys::libvlc_media_get_state(self.ptr) }
102    }
103
104    /// Get duration (in ms) of media descriptor object item.
105    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    /// Parse a media. 
113    pub fn parse(&self) {
114        unsafe{ sys::libvlc_media_parse(self.ptr) };
115    }
116
117    /// Parse a media.
118    pub fn parse_async(&self) {
119        unsafe{ sys::libvlc_media_parse_async(self.ptr) };
120    }
121
122    /// Get Parsed status for media descriptor object.
123    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    /// Returns raw pointer
186    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