在libVLC中可以通过如下等函数获取。
libvlc_media_player_get_length()
//libvlc_video_get_width()
//libvlc_video_get_height()
实测已经没有上述2个函数,以下面一个函数代替:
libvlc_video_get_size(mp, 0, &width, &height);
但是有一个很奇怪的现象:如果在调用完libvlc_media_player_play()之后,立即调用上述3个函数的话,返回的值都是0,只有“等待”一段时间(例如调用sleep())后再调用上述函数,才能得到正确的数值。
以下是我运行过的程序,实现vlc代码提取摄像机图像:
// Created by toson on 19-4-15.
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vlc/vlc.h>
#include <opencv2/opencv.hpp>
#include "unistd.h"
using namespace std;
using namespace cv;
int IMG_WIDTH = 3840;//2592//1920;//1280//1280
int IMG_HEIGHT= 2160;//1520//1080;//960//720
namespace vlcreader_ns {
//#pragma comment(lib,"libvlc.so.5")
//#pragma comment(lib,"libvlccore.so.8")
class VLCReader
public:
VLCReader(char* url = 0);
~VLCReader();
void start(int wantW = IMG_WIDTH, int wantH = IMG_HEIGHT);
void pause(bool paused);
void ctrl(const char *psz_options);
cv::Mat frame() { return img; }
unsigned int w, h;
private:
char* rtspAddress = "rtsp://admin:admin123@192.168.1.102:554/cam/realmonitor?channel=1&subtype=0";
libvlc_instance_t *inst;
libvlc_media_player_t *mp;
unsigned char *pixel;
cv::Mat img;
libvlc_media_t *media;
static void *cb_lock(void *opaque, void **plane);
static void cb_unlock(void *opaque, void *picture, void * const *plane);
static void cb_display(void *opaque, void *picture);
unsigned char * updataSize();
VLCReader::VLCReader(char*url)
: inst(0), mp(0), pixel(0), w(0), h(0), rtspAddress(url)
const char * vlc_args[] = {
"--ipv4", //将会默认为所有连接使用 IPv4。 (默认关闭)
"--no-prefer-system-codecs", //无论是否有可用的选择都优先使用您系统中的原生插件替代VLC自己的插件。 (默认关闭)
"--rtsp-caching=300", //延迟速度ms //允许您修改 RTSP 流的默认缓存值。此值必须以毫秒为单位设置。
"--network-caching=500", //设高可减少花屏 //远程文件额外增加的缓存值,以毫秒为单位。
"--demux=h264", //去复用器被用于分离 "复合" 流 (类似音频和视频流)。
"--rtsp-tcp", //--rtsp-host //--rtsp-tcp //使用 RTP over RTSP (TCP) (默认关闭)
std::string rstp_str(rtspAddress);
if (rstp_str.substr(0, 4) == "file")
vlc_args[4] = "";
vlc_args[5] = "";
inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
mp = libvlc_media_player_new(inst);
libvlc_video_set_callbacks(mp, cb_lock, cb_unlock, cb_display, this);
VLCReader::~VLCReader()
libvlc_media_player_stop(mp);
libvlc_media_player_release(mp);
libvlc_release(inst);
void VLCReader::start(int wantW, int wantH)
libvlc_media_player_pause(mp);
media = libvlc_media_new_location(inst, rtspAddress);
libvlc_media_player_set_media(mp, media);
libvlc_media_release(media);
libvlc_video_set_format(mp, "RV24", wantW, wantH, wantW * 3);
libvlc_media_player_play(mp);
void VLCReader::pause(bool paused)
if (mp) {
libvlc_media_player_set_pause(mp, paused);
unsigned char * VLCReader::updataSize()
libvlc_video_get_size(mp, 0, &w, &h);
//int w = libvlc_video_get_width(mp);
//int h = libvlc_video_get_height(mp);
if (!w || !h)
return 0;
if (pixel && (this->w != w || this->h != h)) {
delete[] pixel;
pixel = 0;
if (!pixel) {
pixel = new unsigned char[w*h * 3];
this->w = w;
this->h = h;
return pixel;
void* VLCReader::cb_lock(void *opaque, void **plane)
VLCReader *p = (VLCReader*)opaque;
*plane = p->updataSize(); //tell VLC to put decoded data to this buffer
return *plane;
void VLCReader::cb_unlock(void *opaque, void *picture, void * const *plane)
VLCReader *p = (VLCReader*)opaque;
unsigned char *pix = (unsigned char*)picture;
if (pix) {
p->img = cv::Mat(p->h, p->w, CV_8UC3, pix);
void VLCReader::cb_display(void *opaque, void *picture)
VLCReader *p = (VLCReader*)opaque;
if (!p->img.empty()) {
// cv::cvtColor(p->img, p->img, cv::COLOR_BGR2RGB);
// cv::namedWindow("1", CV_WINDOW_NORMAL);
// resize(p->img, p->img, Size(0,0), 0.5, 0.5, INTER_LINEAR);
cv::imshow("1", p->img);
cv::waitKey(1);
void VLCReader::ctrl(const char *psz_options)
libvlc_media_add_option(media, psz_options);
using namespace vlcreader_ns;
int main(int argc, char* argv[])
VLCReader vlc_reader("rtsp://admin:admin123@192.168.1.106:554/cam/realmonitor?channel=1&subtype=0");
// VLCReader vlc_reader("file:home/toson/videos/BigBuckBunny_320x180.mp4");
vlc_reader.start();
sleep(3);
vlc_reader.pause(true); //暂停
sleep(3);
vlc_reader.pause(false);
sleep(3);
// vlc_reader.ctrl("-f"); //"--fullscreen"
sleep(3);
sleep(100);
return 0;
概要:vlc编译, 硬解基于libva库(VAAPI), live555(liblivemedia-dev), --enable-live555才能播放rtsp流, 基于liveMedia库, vlc对ffmpeg是运行时依赖,把libavcodec_plugin.so删了就可以。编著:重点章节:“END、我在编译VLC时做过的操作” :“1.依赖相关”、“2.VLC编译安装”。该2节为我...
sudo apt-get install automake ant autopoint cmake build-essential libtool-bin \
patch pkg-config protobuf-compiler ragel subversion unzip git \
openjdk-8-jre openjdk-8-jdk flex python wget vim
功能部份:
VLC媒體播放器的核心是libvlc ,它提供了界面,應用處理功能,如播放列表管理,音頻和視頻解碼和輸出,線程系統。所有libvlc源文件設在的/src目錄及其子目錄:
# config/ :從命令行和配置文件加載配置,提供功能模塊的讀取和寫入配置
# control/: 提供動作控制功能,如播放/暫停,音量管理,全屏,日誌等。
# extras/: 大多是平台的特...
2.安装以下插件[需要联网]
$ sudo apt-get install -y gcc-mingw-w64-i686 g++-mingw-w64-i686 mingw-w64-tools
$ sudo apt-get install -y lua5.2 libtool automake autoconf au
VLC 源码VS2015项目从https://github.com/sunqueen?tab=repositories下载。直接打开VS2015工程编译,编译顺序:
1)libcompat
2) plugins
3) libvlccore
4) libvlc
5) winvlc
编译过程中遇到的报错:
1)compat.h中snprint符号重定义,直接注释掉。
2)libvlccore工程链接报错:
libiconv.lib(iconv.o) : error LNK2019: ...
在Linux上支持GPU加速。
vaapi:https://www.freedesktop.org/wiki/Software/vaapi/
在Linux / X11上,有两个用于硬件视频解码的竞争接口:
Intel的VA-API
NVIDI...