MFC调用vlc动态库libvlc.dll实现简单播放器 中文路径处理

转自 : http://blog.csdn.net/xuplus/article/details/34082363


一、简单说明

       本文讲解利用MFC调用vlc(2.0.0)的动态库实现简单的播放器,实现播放、暂停、停止、音量控制、进度控制,支持中文路径等。

VLC 中文路径转码问题<转>

最近用MFC编写调用libVLC的程序时碰到中文路径不能打开的问题,愤闷了两天终于给解决了,在这里贴出来希望给那些遇到转码问题的人一点帮助。

主要问题是编码方式不对,现在程序主要是用Unicode码,我遇到的libVLC默认为UTF8,这就在遇到中文是需要转为UTF8。我遇到的主要是CString转为const char *或char *。VC++提供强制转码貌似是行不通的,这里写了个函数供参考(因为是转Unicode,所以支持所有语言,还有确保你的项目编码方式是Use Multi-Byte Character Set(不是宽字节编码))。

 char* UniToUTF8(CString strUnicode)
{
USES_CONVERSION;
LPWSTR pwStr=new wchar_t[strUnicode.GetLength()+1];
wcscpy(pwStr,T2W((LPCTSTR)strUnicode));
int ilen = WideCharToMultiByte(CP_UTF8, 0, pwStr, -1, NULL, 0, NULL, NULL); //获取长度
char *szUtf8Temp=new char[ilen + 1];
memset(szUtf8Temp, 0, ilen +1);

WideCharToMultiByte (CP_UTF8, 0, pwStr, -1, szUtf8Temp, ilen, NULL,NULL); //UTF转码
detele pwStr;

return szUtf8Temp;
}

这函数也可以用在其他需要转码的地方。

注:szUtf8Temp用完记得释放空间


二、所需环境说明

     VC6.0 VLC的版本为2.0.0

三、搭建MFC调用libvlc的环境

1.新建立一个VC的工程,暂时取名为VLCDemo

2.首先将VLC的目录下的vlc/sdk\include\vlc.h复制到工程目录下,然后新建立vlc和lib两个文件夹

3.将include目录下的除vlc.h中所有文件拷贝到vlc下,同事将vlc\lib下的两个libvlc.lib和libvlccore.lib复制到lib文件夹下。

4、将vlc目录下的livvlc.dll和libvlccore.dll以及plugins目录到复制到Debug目录下

5.网上下载stdint.h复制主目录下。

推荐地址为:http://download.csdn.net/detail/yigebing52/5747815

6.在项目中添加libvlc.lib和libvlccore.lib的引用。

6.在C**DLG.cpp中加入vlc.h的包含

7点击编译按钮,按照提示将<**>修改为“”就可以了。

这时环境就以及搭建好了。

四。绘制界面,开始增加功能

    整体界面图如下图

 

     按钮的作用从上到下依次为:显示当前播放的文件路径,浏览文件按钮,测试按钮(用于测试函数用法),播放、停止。

其中显示文件路径的Edit框ID为IDC_VIDEO_PATH,关联一个成员变量。浏览按钮ID为IDC_SELECT_VIDEO,其他几个按钮ID分别为IDC_BTN_TEST,

IDC_PLAYTIME,IDC_VOLUME,IDC_PLAY,IDC_PAUSE,IDC_STOP。中间播放界面为一个文本框,修改其ID为IDC_STATIC_PIC。

五,一步一步实现功能。

1.绘制播放窗口为黑色

正在窗口绘制函数OnPaint()中加入如下代码:

 CBrush *oldBursh, brNew;
 HWND hWnd = GetDlgItem(IDC_STATIC_PIC)->GetSafeHwnd();
 brNew.CreateSolidBrush(RGB(0, 0, 0));  
 HDC hDC = ::GetDC(hWnd);
 CDC *pDC = CDC::FromHandle(hDC);
 oldBursh = pDC->SelectObject(&brNew); 

 CRect rect2;
 ::GetClientRect(hWnd, &rect2);  
 pDC->Rectangle(rect2);
 pDC->SelectObject(oldBursh);

 

 2.浏览播放文件按钮功能函数。

    void CVLCDemoDlg::OnSelectVideo() 
{
 // TODO: Add your control notification handler code here
 
 TCHAR BASED_CODE szFilter[] = _T("Video Files All Files (*.*)|*.*||");
 CFileDialog fileDlg (TRUE, _T("Video file"), _T(""), OFN_FILEMUSTEXIST, szFilter, this);
 if(fileDlg.DoModal() == IDOK)
 {
  m_VideoPath = fileDlg.GetPathName();
  m_bNew = true;
 }
 UpdateData(FALSE);
}

3.播放按钮的函数实现

首先需要在VLCDemoDlg.h添加几个变量。

  bool  m_bNew;----------表明当前文件是否为新文件
 libvlc_instance_t*  m_vlcInst;-------vlc的入口变量
 libvlc_media_player_t* m_vlcMplay;
 libvlc_media_t*   m_vlcMedia;
  libvlc_time_t m_TotalTime;---文件总的时间
  UINT_PTR m_playerTimer;----定时器变量

在初始化函数OnInitDialog添加

 SetWindowText("VLC SDK demo");
 char *vlc_argv[100];
 int vlc_argc = 0;
 vlc_argv[vlc_argc++] = "--ignore-config";

 m_vlcInst = libvlc_new (vlc_argc, vlc_argv);

 m_SliderPlayer.SetRange(0, 1000);
 m_SliderPlayer.SetPos(0);

 m_SliderVolume.SetRange(0,100);
 m_SliderVolume.SetPos(100);

 

 

在cpp中构造函数中初始化上面几个变量

  m_vlcInst = NULL;
  m_vlcMedia = NULL;
  m_vlcMplay = NULL;
  m_bNew = true;

 

在cpp文件中添加如下函数

void CVLCDemoDlg::OnPlay() 
{
 UpdateData(true);
 if (m_VideoPath == "")
 {
  return;
 }
 if(m_bNew == true)
 {
  if(m_vlcMplay != NULL)
  {
   libvlc_media_player_release(m_vlcMplay);
  }

  m_vlcMedia = libvlc_media_new_path (m_vlcInst, EncodeToUTF8(m_VideoPath.GetBuffer(0)));
  m_vlcMplay = libvlc_media_player_new_from_media (m_vlcMedia);
  HWND hwnd = GetDlgItem(IDC_STATIC_PIC)->GetSafeHwnd();
  libvlc_media_player_set_hwnd (m_vlcMplay, hwnd);
  m_bNew = false;
 }

 libvlc_media_player_play (m_vlcMplay);
 m_TotalTime = libvlc_media_player_get_length(m_vlcMplay);
 m_playerTimer = SetTimer(100,1*100,NULL);

}

这个程序支持中文路径的视频文件,上面讲assi转化为utf-8即可。

char* EncodeToUTF8(const char* mbcsStr) 

  wchar_t*  wideStr; 
  char*   utf8Str; 
  int   charLen;

  charLen = MultiByteToWideChar(CP_UTF8, 0, mbcsStr, -1, NULL, 0); 
  wideStr = (wchar_t*) malloc(sizeof(wchar_t)*charLen); 
  MultiByteToWideChar(CP_ACP, 0, mbcsStr, -1, wideStr, charLen);

  charLen = WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, NULL, 0, NULL, NULL);

  utf8Str = (char*) malloc(charLen);

  WideCharToMultiByte(CP_UTF8, 0, wideStr, -1, utf8Str, charLen, NULL, NULL);

  free(wideStr); 
  return utf8Str;
}

 

此时在就能播放视频文件了。

3.暂停

void CVLCDemoDlg::OnPause() 
{
  if(m_vlcMplay != NULL)
   libvlc_media_player_pause(m_vlcMplay);
}

4.停止

void CVLCDemoDlg::OnStop() 
{
 // TODO: Add your control notification handler code here
 if (m_vlcMplay == NULL)
 {
  return;
 }
  libvlc_media_player_stop(m_vlcMplay);
  m_bNew = true;
 m_vlcMplay = NULL;
  //libvlc_exception_clear(&m_vlcEx);
 if (m_vlcMedia != NULL)
 {
  libvlc_media_release(m_vlcMedia);
 }
 if (m_vlcMplay != NULL)
 {
  libvlc_media_player_release(m_vlcMplay);
 }
 KillTimer(100);
 m_SliderPlayer.SetPos(0);
 OnPaint();
}

5.播放时进度条跟着时间变化而走动

通过一个定时器实现的。

void CVLCDemoDlg::OnTimer(UINT_PTR nIDEvent)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 if (nIDEvent == 100)
 {
  libvlc_time_t m_CurTime = libvlc_media_player_get_time(m_vlcMplay);
  //float fPos = libvlc_media_player_get_position(m_vlcMplay, &m_vlcEx);
  m_TotalTime = libvlc_media_player_get_length(m_vlcMplay);
   int m_npos = m_CurTime*1000/m_TotalTime;
   m_SliderPlayer.SetPos(m_npos);
 }
 if(libvlc_Ended == libvlc_media_player_get_state(m_vlcMplay))//获取播放状态的函数,如果是结束就发送stop命令,更改状态。
  OnStop();

 CDialog::OnTimer(nIDEvent);
}
6.屏蔽回车键和退出键。

BOOL CVLCDemoDlg::PreTranslateMessage(MSG* pMsg)

 if (pMsg->message == WM_KEYDOWN) {
  if (pMsg->wParam == VK_ESCAPE || pMsg->wParam == VK_RETURN) 
  {
   //SetFullScreen();
   return TRUE;
  }
 }
 
 return CDialog::PreTranslateMessage(pMsg);
}

7.拖动进度条 修改播放进度。

void CVLCDemoDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
 {
  if (pScrollBar->GetSafeHwnd() == m_SliderPlayer.GetSafeHwnd())
  {
  if (m_vlcMplay != NULL)
  {
   libvlc_time_t m_CurTime;
   m_TotalTime = libvlc_media_player_get_length(m_vlcMplay);
   double pos = m_SliderPlayer.GetPos()/1000.0;
   m_CurTime = m_TotalTime * pos;
   libvlc_media_player_set_time(m_vlcMplay,m_CurTime);
  }
  }
 else if (pScrollBar->GetSafeHwnd() == m_SliderVolume.GetSafeHwnd())
  {
   if (m_vlcMplay != NULL)
   {
   int iVolume = m_SliderVolume.GetPos();
   libvlc_audio_set_volume(m_vlcMplay,iVolume);//取值范围为0-100
   }
  } 
 else
  {
   CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
  }
 }

六。程序工程文件下载地址。

 http://www.pudn.com/downloads559/sourcecode/windows/multimedia/detail2305271.html

 

完。。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值