libVLC 軌道信息

對于媒體文件來說,除了元數(shù)據(jù)之外,軌道信息也非常有用,例如:編解碼器、分辨率、幀率等。由于 VLC media player 能夠顯示這些信息,所以 libVLC 也可以做到這一點。
像常見的視頻文件(例如:電影),我們看到的是一個整體,但實際上一般會被分為音頻和視頻兩部分。如果將電影導(dǎo)入視頻編輯軟件,可以很容易地看到音頻和視頻是分開的 - 視頻在視頻軌道上,音頻在音頻軌道上。如果有需求,甚至還可以對它們進行編輯(音量、聲道、時間、制式等)。
1
軌道信息
要解析 libVLC 中的媒體信息,有必要先了解一下它里面的一些數(shù)據(jù)結(jié)構(gòu)。
媒體軌道信息由 libvlc_media_track_t 表示:
typedef?struct?libvlc_media_track_t
{
????/*?Codec?fourcc?*/
????uint32_t????i_codec;??//?編解碼器
????uint32_t????i_original_fourcc;??//?四字符代碼
????int?????????i_id;??//?軌道?ID
????libvlc_track_type_t?i_type;???//?類型
????/*?Codec?specific?*/
????int?????????i_profile;??//?編碼級別
????int?????????i_level;??//?級別的等級
????union?{
????????libvlc_audio_track_t?*audio;??//?音頻軌道
????????libvlc_video_track_t?*video;??//?視頻軌道
????????libvlc_subtitle_track_t?*subtitle;??//?字幕軌道
????};
????unsigned?int?i_bitrate;??//?碼率
????char?*psz_language;??//?語言
????char?*psz_description;??//?描述
}?libvlc_media_track_t;
i_codec 和 i_original_fourcc 的類型是 uint32_t,并不具有可讀性。若想獲取一個可讀信息,需要使用 libvlc_media_get_codec_description()?進行轉(zhuǎn)換。
軌道類型由 libvlc_track_type_t 表示:
typedef?enum?libvlc_track_type_t
{
????libvlc_track_unknown???=?-1,??//?未知
????libvlc_track_audio?????=?0,???//?音頻
????libvlc_track_video?????=?1,???//?視頻
????libvlc_track_text??????=?2????//?文字
}?libvlc_track_type_t;
有了這些值,可以很容易的根據(jù) i_type 來判斷軌道類型。
音頻軌道由 libvlc_audio_track_t 表示:
typedef?struct?libvlc_audio_track_t
{
????unsigned????i_channels;??//?聲道
????unsigned????i_rate;??????//?采樣率
}?libvlc_audio_track_t;
視頻軌道由 libvlc_video_track_t 表示:
typedef?struct?libvlc_video_track_t
{
????unsigned????i_height;??????????//?視頻高度
????unsigned????i_width;???????????//?視頻寬度
????unsigned????i_sar_num;?????????//?像素寬高比的分子???
????unsigned????i_sar_den;?????????//?像素寬高比的分母
????unsigned????i_frame_rate_num;??//?幀率的分子
????unsigned????i_frame_rate_den;??//?幀率的分母
????libvlc_video_orient_t???????i_orientation;??//?方向
????libvlc_video_projection_t???i_projection;
????libvlc_video_viewpoint_t????pose;?/**
}?libvlc_video_track_t;
有兩個字母需要解釋一下:num 是 numerator 的縮寫,表示分子;den 是 denominator 的縮寫,表示分母。
倘若要計算幀率(FPS,每秒鐘多少幀畫面),可以通過 i_frame_rate_num/i_frame_rate_den 來獲得。
字幕軌道由 libvlc_subtitle_track_t 表示:
typedef?struct?libvlc_subtitle_track_t
{
????char?*psz_encoding;??//?編碼
}?libvlc_subtitle_track_t;
2
獲取軌道信息
以本地的一個視頻文件為例,來看看它的軌道信息:

需要注意的是,在獲取軌道信息之前,需要先調(diào)用解析媒體文件(例如:使用?libvlc_media_parse()?),或者至少播放一次多媒體:
int?main()
{
????const?char?*?localMrl?=?"Sample.mkv";
????libvlc_instance_t?*instance;
????libvlc_media_t?*media;
????instance?=?libvlc_new(0,?nullptr);
????media?=?libvlc_media_new_path(instance,?localMrl);
????//?解析媒體以從中讀取信息
????libvlc_media_parse(media);
????//?獲取軌道信息
????reading(media);
????libvlc_media_release(media);
????libvlc_release(instance);
????getchar();
????return?0;
}
具體的獲取如下,主要利用?libvlc_media_tracks_get()?接口:
//?獲取軌道信息
void?reading(libvlc_media_t?*media)
{
????//?用于存儲媒體軌跡的信息
????libvlc_media_track_t?**tracks;
????unsigned?tracksCount;
????//?獲取軌道信息
????tracksCount?=?libvlc_media_tracks_get(media,?&tracks);
????if?(tracksCount?<=?0)
????????return;
????for?(unsigned?i?=?0;?i?????????libvlc_media_track_t?*track?=?tracks[i];
????????cout?<"i_type:?"?<i_type?<endl;
????????cout?<"i_codec:?"?<i_codec?<endl;
????????cout?<"i_original_fourcc:?"?<i_original_fourcc?<endl;
????????//?編解碼器
????????const?char*?codec?=?libvlc_media_get_codec_description(track->i_type,?track->i_codec);
????????const?char*?fourcc_codec?=?libvlc_media_get_codec_description(track->i_type,?track->i_original_fourcc);
????????if?(nullptr?!=?codec)
????????????cout?<"track?codec:?"?<endl;
????????if?(nullptr?!=??fourcc_codec)
????????????cout?<"fourcc?codec:?"?<endl;
????????cout?<"i_profile:?"?<i_profile?<endl;
????????cout?<"i_level:?"?<i_level?<endl;
????????if?(nullptr?!=?track->psz_language)
????????????cout?<"psz_language:?"?<psz_language?<endl;
????????if?(nullptr?!=?track->psz_description)
????????????cout?<"psz_description:?"?<psz_description?<endl;
????????//?音頻軌道
????????if?(track->i_type?==?libvlc_track_audio)?{
????????????libvlc_audio_track_t?*audioTrack?=?track->audio;
????????????cout?<"i_channels:?"?<i_channels?<endl;
????????????cout?<"i_rate:?"?<i_rate?<endl;
????????}?else?if?(track->i_type?==?libvlc_track_video)?{??//?視頻軌道
????????????libvlc_video_track_t?*videoTrack?=?track->video;
????????????//?視頻寬度、高度
????????????cout?<"i_width:?"?<i_width?<endl;
????????????cout?<"i_height:?"?<i_height?<endl;
????????????cout?<"i_sar_num:?"?<i_sar_num?<endl;
????????????cout?<"i_sar_den:?"?<i_sar_den?<endl;
????????????cout?<"i_frame_rate_num:?"?<i_frame_rate_num?<endl;
????????????cout?<"i_frame_rate_den:?"?<i_frame_rate_den?<endl;
????????????//?幀率
????????????if?(videoTrack->i_sar_num?>?0)?{
????????????????double?frameRate?=?videoTrack->i_frame_rate_num?/?double(videoTrack->i_frame_rate_den);
????????????????cout?<"frame_rate:?"?<endl;
????????????}
????????????//?像素寬高比
????????????if?(videoTrack->i_sar_num?>?0)?{
????????????????double?sar?=?videoTrack->i_sar_num?/?double(videoTrack->i_sar_den);
????????????????cout?<"sar:?"?<endl;
????????????}
????????}
????????cout?<"--------------------"?<endl;
????}
????libvlc_media_tracks_release(tracks,?tracksCount);
}
3
還有些什么
其實上面偷了個懶,因為?libvlc_media_parse() 這個接口已經(jīng)被遺棄了,并不推薦使用:
LIBVLC_DEPRECATED?LIBVLC_API?void
libvlc_media_parse(?libvlc_media_t?*p_md?);
取而代之的是?libvlc_media_parse_with_options(),所以應(yīng)盡量使用這個接口,并監(jiān)聽 libvlc_MediaParsedChanged 事件,具體用法可參考《libVLC 事件機制》。
·END·
?
點個在看,么么噠!

