基于libVLC的视频播放器
本文来自于:http://blog.csdn.net/leixiaohua1020/article/details/42363079
最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器
本文记录使用libVLC的开发的最简单的视频播放器示例。VLC Media Player是一款优秀的播放器,但是由于它的源代码编译的难度比较大,一直没有深入研究过它的开发方面的技术。此前触到了一些VLC开发方面的东西,因 此总结了一下libVLC的开发示例程序。
如何获取VLC的SDK
VLC开发所需的库文件可以有2种获取方法:
1. 自行编译
2. 直接从安装目录里面拷贝出来
第一种方法难度要大一些。尤其是在Windows下编译VLC是个比较麻烦的事情。一般情况下可以选择第二种方法获取VLC开发所需的文件。
开发VLC所需的文件的位置:
1. 动态链接库*.dll:安装目录下的libvlc.dll,libvlccore.dll以及plugins目录下的所有文件。
PS:VLC支持非常多的plugin。因此plugins目录的体积确实是非常大的。
2. 静态链接库*.lib:安装目录/sdk/lib
3. 头文件*.h:安装目录/sdk/include
新建一个VC工程后,把上述三类文件分别拷贝至新工程目录下,并且配置它们的路径之后,就可以使用libVLC进行开发了。
最简单的基于libVLC的视频播放器
使用libVLC开发一个播放器十分的容易。最简单的基于libVLC的视频播放器的流程图如下图所示。
流程图中包含了3个结构体:
libvlc_instance_t:代表一个libVLC的实例。
libvlc_media_t:代表一个可以播放的媒体。
libvlc_media_player_t:代表一个VLC媒体播放器(一个视频播放器播放一个视频)。注意VLC并不仅仅用于媒体播放。
创建或者以上3个结构体通过以下6个函数:
libvlc_new():创建libvlc_instance_t。
libvlc_media_new_path():创建libvlc_media_t。
libvlc_media_player_new_from_media():创建libvlc_media_player_t。
libvlc_media_player_release():释放libvlc_media_player_t
libvlc_media_release():释放libvlc_media_t。
libvlc_release():释放libvlc_instance_t。
可以已通过下面的函数控制媒体的播放或者暂停,这些函数都需要使用libvlc_media_player_t作为参数。这里处于简化的目的,只使用了播放和停止函数:
libvlc_media_player_play():播放。
libvlc_media_player_pause():暂停。
libvlc_media_player_stop():停止。
除了上述3个函数之外,还包括libvlc_media_player_set_position()等函数,这里不再一一记录。
几点注意事项
libvlc_media_t的创建
创 建libvlc_media_t有两种方法:libvlc_media_new_path()和 libvlc_media_new_location()。简单描述一下这两个函数的区别:libvlc_media_new_location()用于 打开协议,而libvlc_media_new_path()用于打开文件。因而传递给libvlc_media_new_path()的就是普通的文件 路径(绝对路径例如D:\xxx.flv,或者相对路径例如xxx.flv),而传递给libvlc_media_new_location()的就是协 议地址(例如"udp://….","http://")。但是这里有一点需要注意,在VLC中"文件"也属于一种广义上的"协议"。因此使用 libvlc_media_new_location()也可以打开文件,但是必须在文件路径前面加上"文件协议"的标记"file:///"。例如打开 "F:\movie\cuc_ieschool.flv"下的视频,实际使用的代码如下所示。
libvlc_media_new_location (inst, "file:///F:\\movie\\cuc_ieschool.flv");
此外,VLC还支持很多"神奇"的协议,比如输入"screen://"协议就可以进行屏幕录制,代码如下。
libvlc_media_new_location (inst, "screen://");
把libVLC的弹出窗口嵌入到程序中
在这里我只实践过Windows下把libVLC的弹出窗口嵌入到程序中。将窗口或者控件的句柄传递给libvlc_media_player_set_hwnd()函数即可。
这里有一点需要注意,如果把libVLC弹出窗口嵌入到程序中的话,"全屏"功能就不能使用了。
关于libVLC加载的问题
在 libVLC中可以通过 libvlc_media_player_get_length(),libvlc_video_get_width(),libvlc_video_get_height() 等函数获取到视频的时长,宽,高等信息。但是有一个很奇怪的现象:如果在调用完libvlc_media_player_play()之后立即调用上述3 个函数的话,返回的值都是0,只有"等待"一段时间(例如调用sleep())后再调用上述函数,才能得到正确的数值。对于这种现象,我觉得可能是 libVLC加载完成之后,才能通过上述几个函数获得正确的值(自己推测的,还没有深究)。
#include <Windows.h>
#include "vlc/vlc.h"
int main(int argc, char* argv[])
{
libvlc_instance_t * inst;
libvlc_media_player_t *mp;
libvlc_media_t *m;
libvlc_time_t length;
int width;
int height;
int wait_time=;
//libvlc_time_t length;
/* Load the VLC engine */
inst = libvlc_new (, NULL);
//Create a new item
//Method 1:
//m = libvlc_media_new_location (inst, "file:///F:\\movie\\cuc_ieschool.flv");
//Screen Capture
//m = libvlc_media_new_location (inst, "screen://");
//Method 2:
m = libvlc_media_new_path (inst, "cuc_ieschool.flv");
/* Create a media player playing environement */
mp = libvlc_media_player_new_from_media (m);
/* No need to keep the media now */
libvlc_media_release (m);
// play the media_player
libvlc_media_player_play (mp);
//wait until the tracks are created
_sleep (wait_time);
length = libvlc_media_player_get_length(mp);
width = libvlc_video_get_width(mp);
height = libvlc_video_get_height(mp);
printf("Stream Duration: %ds\n",length/);
printf("Resolution: %d x %d\n",width,height);
//Let it play
_sleep (length-wait_time);
// Stop playing
libvlc_media_player_stop (mp);
// Free the media_player
libvlc_media_player_release (mp);
libvlc_release (inst);
return ;
}
最简单的基于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,"")==){
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(,,NULL);
}
暂停/继续
视频"暂停/继续"的源代码如下所示。其中调用了libvlc_media_player_set_pause()设定"暂停"或者是"继续"。
void CplayerGUIDlg::OnBnClickedPause()
{
if(playerstate==STATE_PLAY){
libvlc_media_player_set_pause(libvlc_mp,);
playerstate=STATE_PAUSE;
GetDlgItem(ID_PAUSE)->SetWindowText(_T("Resume"));
}else if(playerstate==STATE_PAUSE){
libvlc_media_player_set_pause(libvlc_mp,);
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();
} SystemClear();
}
视频播放进度杂时间轴的显示
随着视频的播放,需要在视频播放进度的时间轴上更新播放进度信息。在程序中使用了一个定时器完成这个功能。
在视频开始播放的时候,调用SetTimer()开启定时器。时间间隔设置为1000ms。
SetTimer(,,NULL);
在视频停止播放的时候,调用KillTimer()结束定时器。
KillTimer();
在定时器的消息响应函数中,调用libvlc_media_player_get_time()获取当前视频的播放进度,此外调用libvlc_media_player_get_length()获取视频的总时长。
经过计算之后,就可以把计算的结果设置到相应的编辑框(Edit Control)以及滑动控制条(Slider Control)上。
void CplayerGUIDlg::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == ){
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!=){
//change to second
tns = curtime/;
thh = tns / ;
tmm = (tns % ) / ;
tss = (tns % );
curtimestr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);
m_curtime.SetWindowText(curtimestr);
}
duration = libvlc_media_player_get_length(libvlc_mp);
if(duration!=){
tns = duration/;
thh = tns / ;
tmm = (tns % ) / ;
tss = (tns % );
durationstr.Format(_T("%02d:%02d:%02d"),thh,tmm,tss);
m_duration.SetWindowText(durationstr); progress=curtime*/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, , NULL, NULL); char* buffer = new char[stringLength + ];
::WideCharToMultiByte(CP_UTF8, NULL, unicodeString, wcslen(unicodeString), buffer, stringLength, NULL, NULL);
buffer[stringLength] = '\0'; str = buffer; delete[] buffer;
}
最简单的基于libVLC的例子:最简单的基于libVLC的推流器
本文记录基于libVLC的最简单的推流器。该推流器可以将本地的视频文件转码后推送至目标流媒体服务器(也可以是一个组播地址)。
最简单的基于libVLC的推流器
该推流器的代码十分简单,只用到了几个函数:
libvlc_new():创建libvlc_instance_t。
libvlc_vlm_add_broadcast():增加一个广播(broadcast)。
libvlc_vlm_play_media():播放指定名称的广播(broadcast)。
libvlc_vlm_stop_media():停止指定名称的广播(broadcast)。
libvlc_vlm_release():释放ibvlc_instance_t。
本示例的输入视频文件为"cuc_ieschool.flv"。这个推流器实现了:
- 输入视频转码为H.264
- 音频转码为mp2
- 封装格式设置为MPEG-TS
- 以UDP的形式发送至组播地址"udp://233.233.233.233:6666"
在程序发送广播的同时,会弹出一个窗口显示当前正在发送的视频。
#include <Windows.h>
#include "vlc/vlc.h" int main(int argc, char **argv) {
libvlc_instance_t *vlc;
const char *url;
//Send File
//Transcode it. Video codec use x264. Audio codec use mpga.
//Mux it to mpegts format.
//And stream it to udp://233.233.233.233:6666
/*
const char *sout = "#transcode{vcodec=h264,fps=25,venc=x264{preset=ultrafast,"\
"profile=main,tune=zerolatency},vb=512,scale=0.5," \
"acodec=mpa,aenc=ffmpeg,ab=64,channels=2}" \
":standard{access=udp,mux=ts,dst=233.233.233.233:6666}";
*/
//Send and playing at same time
const char *sout = "#transcode{vcodec=h264,fps=25,venc=x264{preset=ultrafast,"\
"profile=baseline,tune=zerolatency},vb=512," \
"acodec=mpga,ab=64,channels=2}" \
":duplicate{dst=display,dst=standard{access=udp,mux=ts,dst=233.233.233.233:6666}}";
const char *media_name = "Lei's test"; //Screen Capture
//url = "screen://"; url = "cuc_ieschool.flv"; vlc = libvlc_new(, NULL);
libvlc_vlm_add_broadcast(vlc, media_name, url, sout, , NULL, true, false);
libvlc_vlm_play_media(vlc, media_name); //play 30s
_sleep(); libvlc_vlm_stop_media(vlc, media_name);
libvlc_vlm_release(vlc);
return ;
}
基于libVLC的视频播放器的更多相关文章
- 最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器(图形界面版)
===================================================== 最简单的基于libVLC的例子文章列表: 最简单的基于libVLC的例子:最简单的基于lib ...
- 最简单的基于libVLC的例子:最简单的基于libVLC的推流器
===================================================== 最简单的基于libVLC的例子文章列表: 最简单的基于libVLC的例子:最简单的基于lib ...
- 基于VLC的视频播放器
原文:基于VLC的视频播放器 最近在研究视频播放的功能,之前是使用VideoView.在网上看了一下,感觉不是很好,支持的格式比较少,现在网络视频的格式各种各样,感觉用VideoView播放起来局限性 ...
- 转:最简单的基于 DirectShow 的视频播放器
50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...
- Android开发学习之路--基于vitamio的视频播放器(二)
终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...
- 50行代码实现的一个最简单的基于 DirectShow 的视频播放器
本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectShow 播放视频所有必备的函数. 直接贴上代码,具体代码的含义都写在注释中 ...
- 基于VLC的视频播放器(转载)
最近在研究视频播放的功能,之前是使用VideoView.在网上看了一下,感觉不是很好,支持的格式比较少,现在网络视频的格式各种各样,感觉用VideoView播放起来局限性很大. 找到了一个比较合适的播 ...
- 自定义基于 VLC 的视频播放器
前言(蛋疼的背景故事) 前段时间,接了一个小项目,有个需求是要在系统待机一段时间以后,循环播放 MV(类似于 Windows 系统的屏幕保护). 听到这个需求,我首先想到的是 MediaPlayer ...
- GJM :自定义基于 VLC 的视频播放器 [转载]
感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...
随机推荐
- 2019 gplt团体程序设计天梯赛总结
分很菜… 以后写题一定记得把题意理清楚了再开始写. 模拟题还是大坑,代码还是写得不够多,代码量一大就写bug. 补题 l1-8 估值一亿的AI核心代码 补题链接:https://pintia.cn/p ...
- 一键安装LNMP(适合centos7)
1.准备工作,下载源码包 wget https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.22-linux-glibc2.12-x86_64.tar ...
- 50.常用的query查询方式
主要知识点 match all match multi match range query term query terms query exist query 1.match all ...
- 2、Linux的关机方式
shutdown 关机指令,你可以man shutdown 来看一下帮助文档.例如你可以运行如下命令关机: shutdown –h 10 ‘This server will shutdown afte ...
- Mysql学习总结(38)——21条MySql性能优化经验
今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情. 当我们去设计数据库表结构,对操作数 ...
- POJ 3608
1.计算P上y坐标值最小的顶点(称为 yminP )和Q上y坐标值最大的顶点(称为 ymaxQ). 2.为多边形在 yminP 和 ymaxQ 处构造两条切线 LP 和 LQ 使得他们对应的多边形位于 ...
- Cocos2d-x3.3beta0创建动画的3种方式
1.单独载入精灵对象 渲染效率低,浪费资源,不推荐用该方法.代码例如以下:注:代码仅仅需贴到HelloWorldScene.cpp中就可以. //First,单独渲染每个精灵帧 auto sprite ...
- jcaptcha进阶
1.改动CaptchaServiceSingleton类.使用带參构造方法来创建DefaultManageableImageCaptchaService对象. watermark/2/text/aHR ...
- 自己定义隐式转换和显式转换c#简单样例
自己定义隐式转换和显式转换c#简单样例 (出自朱朱家园http://blog.csdn.net/zhgl7688) 样例:对用户user中,usernamefirst name和last name进行 ...
- 【NOIP 2011】 Mayan游戏
[题目链接] https://www.luogu.org/problemnew/show/P1312 [算法] 深度优先搜索 [代码] #include<bits/stdc++.h> us ...