=====================================================
最簡單的基於libVLC的例子文章列表:
最簡單的基於libVLC的例子:最簡單的基於libVLC的視頻播放器
最簡單的基於libVLC的例子:最簡單的基於libVLC的視頻播放器(圖形界面版)
最簡單的基於libVLC的例子:最簡單的基於libVLC的推流器
=====================================================
本文記錄使用libVLC開發的一個簡單的圖形界面的視頻播放器。由於是示例程序,只包含了最簡單的媒體播放方面的功能。其中有一些功能還不完善,有時間以後再做修改。
最簡單的基於libVLC的視頻播放器(圖形界面版)
這是使用libVLC基於MFC開發的一個示例播放器。實現了一個播放器的基本功能:播放,暫停/繼續,停止,播放時間軸的顯示,以及從任一點開始播放媒體。並且支持將媒體文件拖拽至播放器進行播放。播放前將媒體文件的路徑輸入到“URL”欄中,然後單擊“Start”即可開始播放。
播放時候的效果截圖如下所示。
源代碼比較長,不再詳細記錄。簡單記錄一下其中幾個主要功能的實現機制。
視頻的播放/暫停/繼續/停止
播放
視頻“播放”的源代碼如下所示。簡單來說,完成了以下視頻播放的初始化工作:(1)
輸入的URL轉換爲UTF-8編碼(後文詳細記錄)(2)
將顯示視頻畫面的控件的句柄提供給libVLC(3)
初始化libVLC並開始播放(4)
開啓定時器,用於更新視頻播放的進度(後文詳細記錄)
-
void CplayerGUIDlg::OnBnClickedStart()
-
{
-
CStringW cstr_url;
-
-
#ifdef _UNICODE
-
m_url.GetWindowText(cstr_url);
-
#else
-
USES_CONVERSION;
-
CStringA cstr_urla;
-
m_url.GetWindowText(cstr_urla);
-
cstr_url.Format(L"%s",A2W(cstr_urla));
-
#endif
-
-
std::string str_url;
-
UNICODE_to_UTF8(cstr_url, str_url);
-
const char *char_url=str_url.c_str();
-
-
if(strcmp(char_url,"")==0){
-
AfxMessageBox(_T("Input URL is NULL!"));
-
return;
-
}
-
-
HWND screen_hwnd=NULL;
-
screen_hwnd = this->GetDlgItem(IDC_SCREEN)->m_hWnd;
-
-
if(playerstate!=STATE_PREPARE){
-
AfxMessageBox(_T("Media is playing now."));
-
return;
-
}
-
-
-
-
-
-
libvlc_m = libvlc_media_new_path (libvlc_inst, char_url);
-
-
-
libvlc_mp = libvlc_media_player_new_from_media (libvlc_m);
-
-
-
libvlc_media_release (libvlc_m);
-
-
-
libvlc_media_player_set_hwnd (libvlc_mp,screen_hwnd);
-
-
-
int x=libvlc_media_player_play (libvlc_mp);
-
-
-
-
-
playerstate=STATE_PLAY;
-
SetBtn(STATE_PLAY);
-
SetTimer(1,1000,NULL);
-
}
暫停/繼續
視頻“暫停/繼續”的源代碼如下所示。其中調用了libvlc_media_player_set_pause()設定“暫停”或者是“繼續”。
-
void CplayerGUIDlg::OnBnClickedPause()
-
{
-
if(playerstate==STATE_PLAY){
-
libvlc_media_player_set_pause(libvlc_mp,1);
-
playerstate=STATE_PAUSE;
-
GetDlgItem(ID_PAUSE)->SetWindowText(_T("Resume"));
-
}else if(playerstate==STATE_PAUSE){
-
libvlc_media_player_set_pause(libvlc_mp,0);
-
playerstate=STATE_PLAY;
-
GetDlgItem(ID_PAUSE)->SetWindowText(_T("Pause"));
-
}
-
}
停止
視頻“停止”的源代碼如下所示。其中調用了libvlc_media_player_stop()停止視頻播放,並且調用libvlc_media_player_release()釋放相應的libvlc_media_player_t結構體。
-
void CplayerGUIDlg::OnBnClickedStop()
-
{
-
if(libvlc_mp!=NULL){
-
libvlc_media_player_stop (libvlc_mp);
-
libvlc_media_player_release (libvlc_mp);
-
KillTimer(1);
-
}
-
-
SystemClear();
-
}
視頻播放進度雜時間軸的顯示
隨着視頻的播放,需要在視頻播放進度的時間軸上更新播放進度信息。在程序中使用了一個定時器完成這個功能。在視頻開始播放的時候,調用SetTimer()開啓定時器。時間間隔設置爲1000ms。
在視頻停止播放的時候,調用KillTimer()結束定時器。
在定時器的消息響應函數中,調用libvlc_media_player_get_time()獲取當前視頻的播放進度,此外調用libvlc_media_player_get_length()獲取視頻的總時長。經過計算之後,就可以把計算的結果設置到相應的編輯框(Edit Control)以及滑動控制條(Slider Control)上。
-
void CplayerGUIDlg::OnTimer(UINT_PTR nIDEvent)
-
{
-
if (nIDEvent == 1){
-
CString curtimestr,durationstr;
-
int curtime;
-
int duration;
-
int tns, thh, tmm, tss;
-
int progress;
-
-
curtime = libvlc_media_player_get_time(libvlc_mp);
-
if(curtime!=0){
-
-
tns = curtime/1000;
-
thh = tns / 3600;
-
tmm = (tns % 3600) / 60;
-
tss = (tns % 60);
-
curtimestr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);
-
m_curtime.SetWindowText(curtimestr);
-
}
-
duration = libvlc_media_player_get_length(libvlc_mp);
-
if(duration!=0){
-
tns = duration/1000;
-
thh = tns / 3600;
-
tmm = (tns % 3600) / 60;
-
tss = (tns % 60);
-
durationstr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);
-
m_duration.SetWindowText(durationstr);
-
-
progress=curtime*100/duration;
-
m_progress.SetPos(progress);
-
}
-
}
-
-
-
if(libvlc_media_player_get_state(libvlc_mp)==libvlc_Ended)
-
OnBnClickedStop();
-
-
-
CDialogEx::OnTimer(nIDEvent);
-
}
視頻播放點的調整
當鼠標拖動滑動控制條(Slider Control)控件上的滑塊的時候,需要根據拖動的位置設置視頻的播放進度。此時調用libvlc_media_player_set_position()設定視頻的播放進度。消息響應函數中的代碼如下所示。
-
void CplayerGUIDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
-
{
-
if (pScrollBar->GetSafeHwnd() == m_progress.GetSafeHwnd()){
-
float posf=0.0;
-
if(nSBCode==SB_THUMBPOSITION){
-
posf=(float)nPos/100.0;
-
libvlc_media_player_set_position(libvlc_mp,posf);
-
}
-
}
-
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
-
}
libVLC中輸入中文文件路徑問題
libVLC使用英文作爲輸入路徑的時候是沒有問題的。但是當我們直接傳遞中文路徑的時候,會出現libVLC將中文解析爲亂碼從而導致無法播放的問題。這個問題卡了我一陣子時間。造成這一問題的原因在於VLC的輸入文件路徑是使用UTF-8編碼的。因此我們需要將輸入路徑轉碼爲UTF-8編碼。轉碼之後這一問題即得到了解決。
Unicode轉碼爲UTF-8的函數代碼如下所示。
-
void CplayerGUIDlg::UNICODE_to_UTF8(CStringW& unicodeString, std::string& str)
-
{
-
int stringLength = ::WideCharToMultiByte(CP_UTF8, NULL, unicodeString, wcslen(unicodeString), NULL, 0, NULL, NULL);
-
-
char* buffer = new char[stringLength + 1];
-
::WideCharToMultiByte(CP_UTF8, NULL, unicodeString, wcslen(unicodeString), buffer, stringLength, NULL, NULL);
-
buffer[stringLength] = '\0';
-
-
str = buffer;
-
-
delete[] buffer;
-
}
下載
Simplest libVLC Example
項目主頁
SourceForge:https://sourceforge.net/projects/simplestlibvlcexample/
Github:https://github.com/leixiaohua1020/simplest_libvlc_example
開源中國:http://git.oschina.net/leixiaohua1020/simplest_libvlc_example
CDSN下載地址: http://download.csdn.net/detail/leixiaohua1020/8342413
本工程是包含了一些基於libVLC的示例程序。一共包含了如下幾個子程序。playerGUI: 最簡單的基於libVLC的播放器-圖形界面版。simplest_libvlc_example: 最簡單的基於libVLC的播放器。simplest_libvlc_streamer: 最簡單的基於libVLC的推流器。
原文鏈接:http://blog.csdn.net/leixiaohua1020/article/details/42363593