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

最简单的基于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;
	}

     /* Create a new item */
     //m = libvlc_media_new_location (libvlc_inst, "http://mycool.movie.com/test.mov");

     libvlc_m = libvlc_media_new_path (libvlc_inst, char_url);

     /* Create a media player playing environement */
     libvlc_mp = libvlc_media_player_new_from_media (libvlc_m);

     /* No need to keep the media now */
     libvlc_media_release (libvlc_m);

    //on windows
     libvlc_media_player_set_hwnd (libvlc_mp,screen_hwnd);

     /* play the media_player */
     int x=libvlc_media_player_play (libvlc_mp);

     //_sleep (30000); /* Let it play a bit */

	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。

SetTimer(1,1000,NULL);

在视频停止播放的时候,调用KillTimer()结束定时器。

KillTimer(1);

在定时器的消息响应函数中,调用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;
		//ms
		curtime = libvlc_media_player_get_time(libvlc_mp);
		if(curtime!=0){
			//change to second
			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);
		}
	}

	//Stop in the end
	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的推流器。

最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器(图形界面版)的更多相关文章

  1. 最简单的基于DirectShow的示例:视频播放器图形界面版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  2. 转:最简单的基于 DirectShow 的视频播放器

    50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...

  3. 最简单的基于DirectShow的示例:视频播放器自定义版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  4. 最简单的基于DirectShow的示例:视频播放器

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

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

    ===================================================== 最简单的基于libVLC的例子文章列表: 最简单的基于libVLC的例子:最简单的基于lib ...

  6. 基于libVLC的视频播放器

    本文来自于:http://blog.csdn.net/leixiaohua1020/article/details/42363079 最简单的基于libVLC的例子:最简单的基于libVLC的视频播放 ...

  7. C语言基于GTK+Libvlc实现的简易视频播放器

    小编心语:现下,各种视频播放软件层出不穷,竞争也越演越烈,不知道大家有木有这个想法,小编有时在想能不能做一款属于自己的视频播放器呢~小编特意去实验楼,整理出了这篇关于如何实现简易视频播放器的博文.简易 ...

  8. AgileEAS.NET SOA 中间件平台.Net Socket通信框架-简单例子-实现简单的服务端客户端消息应答

    一.AgileEAS.NET SOA中间件Socket/Tcp框架介绍 在文章AgileEAS.NET SOA 中间件平台Socket/Tcp通信框架介绍一文之中我们对AgileEAS.NET SOA ...

  9. 基于Python使用SVM识别简单的字符验证码的完整代码开源分享

    关键字:Python,SVM,字符验证码,机器学习,验证码识别 1   概述 基于Python使用SVM识别简单的验证字符串的完整代码开源分享. 因为目前有了更厉害的新技术来解决这类问题了,但是本文作 ...

随机推荐

  1. hdu 2888 二维RMQ模板题

    Check Corners Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) T ...

  2. [bzoj省选十连测推广赛2]T2七彩树

    抄自:http://blog.csdn.net/coldef/article/details/61412577 当时看了就不会,看了别人的题解不懂怎么维护,最后抄了个代码....... 给定一棵n个点 ...

  3. 学生管理系统(SSM简易版)总结

    之前用 Servlet + JSP 实现了一个简易版的学生管理系统,在学习了 SSM 框架之后,我们来对之前写过的项目重构一下! 技术准备 为了完成这个项目,需要掌握如下技术: Java 基础知识 前 ...

  4. python2.7入门---操作mysql数据库增删改查

    Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口.Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: G ...

  5. 小程序敏感信息解密-java

    /** * AES解密 * @param content 密文 * @return * @throws InvalidAlgorithmParameterException * @throws NoS ...

  6. 排序分析函数中对null的处理

    --排序分析函数中对null的处理 --分析:对于null在分析函数中是升序默认是nulls last,降序默认是nulls first.如果不指定排序,那么是升序 )); ,'测试1'); ,'测试 ...

  7. Python之禅及其翻译

    凡是用过 Python的人,基本上都知道在交互式解释器中输入 import this 就会显示 Tim Peters 的 The Zen of Python,但它那偈语般的语句有点令人费解,所以我想分 ...

  8. 无忧代理免费ip爬取(端口js加密)

    起因 为了训练爬虫技能(其实主要还是js技能-),翻了可能有反爬的网站挨个摧残,现在轮到这个网站了:http://www.data5u.com/free/index.shtml 解密过程 打开网站,在 ...

  9. Oracle数据库常用命令记录

    1.Sql建表 CREATE TABLE AAABBBCCCDDD( ID ) primary key, AAAAAAAA ) not NULL, BBBBBBBB ), CCCCCCCC ), DD ...

  10. hiredis异步接口封装并导出到Lua

    hiredis异步接口封装并导出到Lua(金庆的专栏 2017.1)hiredis 不支持 Windows, Windows 下使用 wasppdotorg / hiredis-for-windows ...