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

article/2025/10/1 17:48:59

一、简单说明

       本文讲解利用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

 

完。。。。


http://chatgpt.dhexx.cn/article/32VMbGn8.shtml

相关文章

VLC-Android编译

1.环境 硬核条件----------linux(这里用ubuntu代替)15.5.1 build-15018445 PS&#xff1a;这里安装好虚拟机以后&#xff0c;尽可能分配大内存(8GB起步)&#xff0c;如果电脑本地不允许开这么大的内存给虚拟机&#xff0c;则本博文后面的内容可能帮助不大。 安装好虚拟机后&am…

VLC介绍以及库的使用

VLC原指VideoLAN客户端(VideoLANClient)&#xff0c;是一款开源的、跨平台的、可扩展的、多媒体播放器、流媒体服务器及框架&#xff0c;可播放大多数多媒体文件&#xff0c;以及DVD、音频CD、VCD及各类流媒体协议&#xff0c;现更名为VLC media player&#xff0c;最新版本为2…

LibVLC —— 常用函数解析

函数 ● LIBVLC_API libvlc_instance_t *libvlc_new( int argc , const char *const *argv ); 功能&#xff1a;创建libvlc_instance_t对象。 用法&#xff1a; libvlc_instance_t *VlcInstance libvlc_new(0, nullptr);参数&#xff1a;                具体…

【玩转VLC】--- 基于libvlc写个最简单的播放器

通过【玩转VLC】--- ubuntu下编译vlc 我们已经把vlc编译哦了。生成了一系列的bin和libvlc.so. 接下来我们就用编译好的libvlc.so搞一个最简单的播放器。 我认为vlc的伟大之处有一点就是他并没有把整个播放器写成一个硬生生的bin。而是独立出来个libvlc库&#xff0c;其他的玩…

最简单的基于libVLC的例子:最简单的基于libVLC的推流器

最简单的基于libVLC的例子文章列表&#xff1a; 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器&#xff08;图形界面版&#xff09; 最简单的基于libVLC的例子&#xff1a;最简…

C++调用libVLC播放视频

1、下载libVLC的sdk Index of /pub/videolan/vlc/ 注意下载.7z结尾的 2、Visual Studio建立C的windows控制台项目 3、文件准备 &#xff08;1&#xff09;sdk文件夹解压缩到项目文件夹下 &#xff08;2&#xff09;在Debug下方压缩包内的几个文件 、 4、配置项目属性 注意…

最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器(图形界面版)

最简单的基于libVLC的例子文章列表&#xff1a; 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器&#xff08;图形界面版&#xff09; 最简单的基于libVLC的例子&#xff1a;最简…

基于libVLC的视频播放器之二:使用VLC-Qt播放RTSP流

此篇是 使用VLC浏览器插件播放RTSP流的姊妹篇。 一.直接使用libVLC libVLC是VLC media player多媒体框架的核心引擎和接口&#xff0c;开发者使用它能轻松的创建大量具有VLC特性的应用。 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器详细介绍了libVL…

最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器

最简单的基于libVLC的例子文章列表&#xff1a; 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器 最简单的基于libVLC的例子&#xff1a;最简单的基于libVLC的视频播放器&#xff08;图形界面版&#xff09; 最简单的基于libVLC的例子&#xff1a;最简…

用VLC开发视频播放器/组件(两种方式:libVLC / VLC-Qt)

测试环境 MSVC-2015Qt 5.14.2QCreator 1. libVLC&#xff08;关键步骤&#xff09; 参考&#xff1a;心流剑 libVLC 各版本 下载链接 我的下载版本为&#xff1a;3.0.11 sdk/lib文件夹目录 qmake vlc 部分的配置&#xff08;路径根据自己的修改&#xff09;只需要&#…

idea如何取消debug所有断点

1、debug模式下&#xff0c;在idea左下方找到【View Breakpoints】按钮或者直接按【CtrlShiftF8】快捷键&#xff0c;如下图&#xff1a; 2、在左侧窗口中&#xff0c;点击【Java Line Breakpoints】前方的全选框&#xff0c;如下图&#xff1a; 3、取消 【Java Line Breakp…

Idea断点for循环调试

前言 作为一个开发&#xff0c;最高兴和痛苦的事情就是排查问题&#xff0c;调试代码解决问题&#xff0c;掌握一些技巧可以提升效率&#xff0c;今天就讲讲for循环断点调试的技巧for循环断点调试 操作步骤&#xff1a; 1.在断点调试处加断点 2.点击断点处&#xff0c;鼠标右击…

IntelliJ IDEA-Debug断点调试 看这篇文章就够了

详解IntelliJ IDEA-Debug断点调试 如今&#xff0c;IntelliJ IDEA 目前深受广大开发者喜爱&#xff0c;我们在实际开发工作中&#xff0c;不管是用来阅读源码还是在开发过程中都需要进行代码调试。 以下为大家准备了一篇关于IntelliJ IDEA-Debug断点调试的文章&#xff0c;如…

IDEA 的基本介绍使用及断点调试

文章目录 1、IDE&#xff08;集成开发环境&#xff09;- IDEA2、IDE&#xff08;集成开发环境&#xff09;- Eclipse3、IDEA 的基本介绍和使用3.1、设置字体 和 颜色主题3.2、编译文件和源代码3.3、IDEA 常用快捷键3.4、模板/自定义模板 4、断点调试(debug)4.1、实际需求4.2、定…

idea debug调式进不了断点

问题&#xff1a; 在启动debug断点调试时&#xff0c;代码无法进入断点。 解决方案&#xff1a; 在网上搜索解决方案&#xff0c;看到说在settings——>Debugger下勾选如下位置即可。本人并未亲自测试&#xff0c;所以就做了一波搜集党。 我的解决方法&#xff1a;去掉如下…

idea断点调试jar包

本文以springbootdemo-0.0.1-SNAPSHOT.jar 为例&#xff0c;jar内容需与idea保持一致。 1、启动命令 常规jar启动&#xff1a;java -jar springbootdemo-0.0.1-SNAPSHOT.jar jar包断点调试启动&#xff1a;java -Xdebug -agentlib:jdwptransportdt_socket,servery,suspendn,ad…

如何在idea中打debug断点

在调试代码的时候&#xff0c;你的项目得debug模式启动&#xff0c;也就是点那个绿色的甲虫启动服务器&#xff0c;然后&#xff0c;就可以在代码里面断点调试啦。 下面不要在意&#xff0c;这个快捷键具体是啥&#xff0c;因为&#xff0c;这个keymap是可以自己配置的&#xf…

【IDEA 断点调试】

IDEA 断点调试 断点类型 行断点 【红色圆点】 点击左侧空白区域 、或 在行上ctrlF8 详细断点 【黄色圆点】 shift单击左侧空白区域&#xff0c;同时弹窗选择断点详细设置 方法断点 【红色菱形】 点击方法名所在左侧空白区域 。 进入方法后每一行都是挂起&#xff0c;打在接口…

IDEA debug 断点调试技巧

1、首先看下IDEA中Debug模式下的界面&#xff1a; ① 以Debug模式启动服务&#xff0c;左边的一个按钮则是以Run模式启动。在开发中&#xff0c;我一般会直接启动Debug模式&#xff0c;方便随时调试代码。 ② 断点&#xff1a;在左边行号栏单击左键&#xff0c;或者快捷键Ctrl…

IDEA 加断点debug时阻塞问题

今天有朋友提到一个问题&#xff0c;“我在springBoot项目中建一个Controller&#xff0c;然后写两个方法&#xff0c;方法1中加个断点&#xff0c;然后请求方法1&#xff0c;进入断点之后再请求方法二&#xff0c;此时方法二会一直等待&#xff0c;等方法一执行完才能再执行方…