现在有一个需求,需要使用QT写界面,使用vlc进行视频的操作,显示在QLable上面。
借鉴了雷神大佬的博客,使用的环境是vs2015+Qt5.9.0。第一先介绍了vlc的下载和配置。二和三是雷神大佬的例子,用来测试。四介绍了完成需求的主要代码和流程。
源码下载地址
本文使用的vlc版本下载地址是: http://get.videolan.org/vlc/3.0.3/win32/ 下面的vlc-3.0.3-win32.7z
比如下载到:C:\Users\czf\Downloads\vlc-3.0.3-win32\vlc-3.0.3\
/**
* 最简单的基于libVLC的播放器
* Simplest libVLC Player
*
* 雷霄骅 Lei Xiaohua
* [email protected]
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
* 本程序是一个最简单的基于libVLC的视频播放器。
* 适合初学者学习libVLC。
*
* This example is the simplest Video Player based on libVLC.
* Suitable for the beginner of libVLC.
*/
#include
#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=5000;
//libvlc_time_t length;
/* Load the VLC engine */
inst = libvlc_new (0, NULL);
//Create a new item
//Method 1:
m = libvlc_media_new_location (inst, "file:///C:\\Users\\czf\\Desktop\\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/1000);
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 0;
}
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的推流器
* Simplest libVLC Streamer
*
* 雷霄骅 Lei Xiaohua
* [email protected]
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
* 本程序是一个最简单的基于libVLC的推流器。
* 适合初学者学习libVLC。
*
* This example is the simplest Streamer based on libVLC.
* Suitable for the beginner of libVLC.
*/
#include
#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(0, NULL);
libvlc_vlm_add_broadcast(vlc, media_name, url, sout, 0, NULL, true, false);
libvlc_vlm_play_media(vlc, media_name);
//play 30s
_sleep(30000);
libvlc_vlm_stop_media(vlc, media_name);
libvlc_vlm_release(vlc);
return 0;
}
该推流器流程:
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”。这个推流器实现了:
调用
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//CMediaPlayer::TestLocalPlayerVedio();
//CMediaPlayer::TestRtmpPlayerVedio();
testqt w; //testqt是一个QMainWindow,上面有一个QLable
w.show();
// 获取w上面的qlable控件,传入handle,显示视频到QLabel
QLabel* label = w.findChild("lb");
CMediaPlayer t;
t.PlayVedio("", (HWND)label->winId());
return a.exec();
}
实现
void CMediaPlayer::PlayVedio(const char *pstIp, HWND handle)
{
char szPlayerUrl[255] = {0};
sprintf_s(szPlayerUrl, "rtsp://admin:admin123%s", pstIp);
libvlc_media_t *pMedia = libvlc_media_new_path(m_pInstant, "C:\\Users\\czf\\Desktop\\cuc_ieschool.flv"); //本地播放
//libvlc_media_new_location(m_pInstant, szPlayerUrl); //拉流播放
if ( NULL == pMedia)
{
return;
}
libvlc_media_player_t *pPlayer = libvlc_media_player_new_from_media(pMedia);
if (NULL == pPlayer)
{
return;
}
libvlc_media_player_set_hwnd(pPlayer, handle);
int iRet = libvlc_media_player_play(pPlayer);
if (0 != iRet)
{
libvlc_media_player_stop(pPlayer);
libvlc_media_player_retain(pPlayer);
return;
}
}
流程介绍:
建立一个QT工程,只有一个QMainWindow,在QMainWindow添加一个QLable,读取该lable的Handle,传给vlc,vlc在该lable上进行视频显示。
最简单的基于libVLC的例子:最简单的基于libVLC的视频播放器
最简单的基于libVLC的视频播放器(图形界面版)
最简单的基于libVLC的推流器
1.问题描述:
解决方法:
2.问题描述:运行到libvlc_media_new_path崩溃
原因:m_pInstant = libvlc_new(0, NULL);为NULL
解决方法:把C:\Users\czf\Downloads\vlc-3.0.3-win32\vlc-3.0.3\文件夹下的plugins文件夹拷贝到exe同级目录下。
3.使用vlc会出现错误,typedef ssize_t (*libvlc_media_read_cb)(void *opaque, unsigned char *buf,size_t len);
解决方法:在文件中定义libvlc_media.h
typedef int ssize_t; //添加这一句
typedef ssize_t (*libvlc_media_read_cb)(void *opaque, unsigned char *buf, size_t len);