最簡單的基於libVLC的例子:最簡單的基於libVLC的視頻播放器(圖形界面版)

=====================================================

最簡單的基於libVLC的例子文章列表:

最簡單的基於libVLC的例子:最簡單的基於libVLC的視頻播放器

最簡單的基於libVLC的例子:最簡單的基於libVLC的視頻播放器(圖形界面版)

最簡單的基於libVLC的例子:最簡單的基於libVLC的推流器

=====================================================

本文記錄使用libVLC開發的一個簡單的圖形界面的視頻播放器。由於是示例程序,只包含了最簡單的媒體播放方面的功能。其中有一些功能還不完善,有時間以後再做修改。

 


最簡單的基於libVLC的視頻播放器(圖形界面版)

這是使用libVLC基於MFC開發的一個示例播放器。實現了一個播放器的基本功能:播放,暫停/繼續,停止,播放時間軸的顯示,以及從任一點開始播放媒體。並且支持將媒體文件拖拽至播放器進行播放。播放前將媒體文件的路徑輸入到“URL”欄中,然後單擊“Start”即可開始播放。


播放時候的效果截圖如下所示。


源代碼比較長,不再詳細記錄。簡單記錄一下其中幾個主要功能的實現機制。

視頻的播放/暫停/繼續/停止

播放

視頻“播放”的源代碼如下所示。簡單來說,完成了以下視頻播放的初始化工作:
(1) 輸入的URL轉換爲UTF-8編碼(後文詳細記錄)
(2) 將顯示視頻畫面的控件的句柄提供給libVLC
(3) 初始化libVLC並開始播放
(4) 開啓定時器,用於更新視頻播放的進度(後文詳細記錄)
  1. void CplayerGUIDlg::OnBnClickedStart()  
  2. {  
  3.     CStringW cstr_url;  
  4.   
  5. #ifdef _UNICODE  
  6.     m_url.GetWindowText(cstr_url);  
  7. #else  
  8.     USES_CONVERSION;  
  9.     CStringA cstr_urla;  
  10.     m_url.GetWindowText(cstr_urla);  
  11.     cstr_url.Format(L"%s",A2W(cstr_urla));  
  12. #endif  
  13.   
  14.     std::string str_url;  
  15.     UNICODE_to_UTF8(cstr_url, str_url);  
  16.     const char *char_url=str_url.c_str();  
  17.   
  18.     if(strcmp(char_url,"")==0){  
  19.         AfxMessageBox(_T("Input URL is NULL!"));  
  20.         return;  
  21.     }  
  22.       
  23.     HWND screen_hwnd=NULL;  
  24.     screen_hwnd = this->GetDlgItem(IDC_SCREEN)->m_hWnd;   
  25.   
  26.     if(playerstate!=STATE_PREPARE){  
  27.         AfxMessageBox(_T("Media is playing now."));  
  28.         return;  
  29.     }  
  30.   
  31.   
  32.      /* Create a new item */  
  33.      //m = libvlc_media_new_location (libvlc_inst, "http://mycool.movie.com/test.mov");  
  34.   
  35.      libvlc_m = libvlc_media_new_path (libvlc_inst, char_url);  
  36.   
  37.      /* Create a media player playing environement */  
  38.      libvlc_mp = libvlc_media_player_new_from_media (libvlc_m);  
  39.        
  40.      /* No need to keep the media now */  
  41.      libvlc_media_release (libvlc_m);  
  42.    
  43.     //on windows  
  44.      libvlc_media_player_set_hwnd (libvlc_mp,screen_hwnd);  
  45.    
  46.      /* play the media_player */  
  47.      int x=libvlc_media_player_play (libvlc_mp);  
  48.       
  49.      //_sleep (30000); /* Let it play a bit */  
  50.       
  51.   
  52.     playerstate=STATE_PLAY;  
  53.     SetBtn(STATE_PLAY);  
  54.     SetTimer(1,1000,NULL);  
  55. }  

暫停/繼續

視頻“暫停/繼續”的源代碼如下所示。其中調用了libvlc_media_player_set_pause()設定“暫停”或者是“繼續”。
  1. void CplayerGUIDlg::OnBnClickedPause()  
  2. {  
  3.     if(playerstate==STATE_PLAY){  
  4.         libvlc_media_player_set_pause(libvlc_mp,1);  
  5.         playerstate=STATE_PAUSE;  
  6.         GetDlgItem(ID_PAUSE)->SetWindowText(_T("Resume"));  
  7.     }else if(playerstate==STATE_PAUSE){  
  8.         libvlc_media_player_set_pause(libvlc_mp,0);  
  9.         playerstate=STATE_PLAY;  
  10.         GetDlgItem(ID_PAUSE)->SetWindowText(_T("Pause"));  
  11.     }  
  12. }  

停止

視頻“停止”的源代碼如下所示。其中調用了libvlc_media_player_stop()停止視頻播放,並且調用libvlc_media_player_release()釋放相應的libvlc_media_player_t結構體。
  1. void CplayerGUIDlg::OnBnClickedStop()  
  2. {  
  3.     if(libvlc_mp!=NULL){  
  4.         libvlc_media_player_stop (libvlc_mp);  
  5.         libvlc_media_player_release (libvlc_mp);  
  6.         KillTimer(1);  
  7.     }  
  8.       
  9.     SystemClear();  
  10. }  

視頻播放進度雜時間軸的顯示

隨着視頻的播放,需要在視頻播放進度的時間軸上更新播放進度信息。在程序中使用了一個定時器完成這個功能。
在視頻開始播放的時候,調用SetTimer()開啓定時器。時間間隔設置爲1000ms。
  1. SetTimer(1,1000,NULL);  
在視頻停止播放的時候,調用KillTimer()結束定時器。
  1. KillTimer(1);  
在定時器的消息響應函數中,調用libvlc_media_player_get_time()獲取當前視頻的播放進度,此外調用libvlc_media_player_get_length()獲取視頻的總時長。
經過計算之後,就可以把計算的結果設置到相應的編輯框(Edit Control)以及滑動控制條(Slider Control)上。
  1. void CplayerGUIDlg::OnTimer(UINT_PTR nIDEvent)  
  2. {  
  3.     if (nIDEvent == 1){  
  4.         CString curtimestr,durationstr;  
  5.         int curtime;  
  6.         int duration;  
  7.         int tns, thh, tmm, tss;  
  8.         int progress;  
  9.         //ms  
  10.         curtime = libvlc_media_player_get_time(libvlc_mp);  
  11.         if(curtime!=0){  
  12.             //change to second  
  13.             tns = curtime/1000;  
  14.             thh  = tns / 3600;  
  15.             tmm  = (tns % 3600) / 60;  
  16.             tss  = (tns % 60);  
  17.             curtimestr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);  
  18.             m_curtime.SetWindowText(curtimestr);  
  19.         }  
  20.         duration  = libvlc_media_player_get_length(libvlc_mp);  
  21.         if(duration!=0){  
  22.             tns = duration/1000;  
  23.             thh  = tns / 3600;  
  24.             tmm  = (tns % 3600) / 60;  
  25.             tss  = (tns % 60);  
  26.             durationstr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);  
  27.             m_duration.SetWindowText(durationstr);  
  28.   
  29.             progress=curtime*100/duration;  
  30.             m_progress.SetPos(progress);  
  31.         }  
  32.     }  
  33.   
  34.     //Stop in the end  
  35.     if(libvlc_media_player_get_state(libvlc_mp)==libvlc_Ended)  
  36.         OnBnClickedStop();  
  37.   
  38.   
  39.     CDialogEx::OnTimer(nIDEvent);  
  40. }  


視頻播放點的調整

當鼠標拖動滑動控制條(Slider Control)控件上的滑塊的時候,需要根據拖動的位置設置視頻的播放進度。此時調用libvlc_media_player_set_position()設定視頻的播放進度。消息響應函數中的代碼如下所示。
  1. void CplayerGUIDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)  
  2. {  
  3.     if (pScrollBar->GetSafeHwnd() == m_progress.GetSafeHwnd()){  
  4.         float posf=0.0;  
  5.         if(nSBCode==SB_THUMBPOSITION){  
  6.             posf=(float)nPos/100.0;  
  7.             libvlc_media_player_set_position(libvlc_mp,posf);  
  8.         }  
  9.     }  
  10.     CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);  
  11. }  

libVLC中輸入中文文件路徑問題

libVLC使用英文作爲輸入路徑的時候是沒有問題的。但是當我們直接傳遞中文路徑的時候,會出現libVLC將中文解析爲亂碼從而導致無法播放的問題。這個問題卡了我一陣子時間。造成這一問題的原因在於VLC的輸入文件路徑是使用UTF-8編碼的。因此我們需要將輸入路徑轉碼爲UTF-8編碼。轉碼之後這一問題即得到了解決。

Unicode轉碼爲UTF-8的函數代碼如下所示。
  1. void CplayerGUIDlg::UNICODE_to_UTF8(CStringW& unicodeString, std::string& str)  
  2. {  
  3.     int stringLength = ::WideCharToMultiByte(CP_UTF8, NULL, unicodeString, wcslen(unicodeString), NULL, 0, NULL, NULL);  
  4.   
  5.     char* buffer = new char[stringLength + 1];  
  6.     ::WideCharToMultiByte(CP_UTF8, NULL, unicodeString, wcslen(unicodeString), buffer, stringLength, NULL, NULL);  
  7.     buffer[stringLength] = '\0';  
  8.   
  9.     str = buffer;  
  10.   
  11.     delete[] buffer;  
  12. }  

下載


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章