录像添加的实现:https://patches.videolan.org/patch/606/
在属性-C/C++添加VLC所需要的头文件
在VS下创建动态库,创建完成后新建头,如VLC_MediaDLL.h文件,添加代码如下:
#ifdef DLL_VLC_MEDIADLL//如果已经定义就什么都不做
#else
#define DLL_VLC_MEDIADLL __declspec(dllexport)
#endif
#include <stdio.h>
#include <iostream>
#include <mutex>
#include "vlc/vlc.h"
//DLL_VLC_MEDIADLL void SetLockPicture(libvlc_video_lock_cb cbFunMsgEntry);
//DLL_VLC_MEDIADLL void SetUnLockPicture(libvlc_video_unlock_cb unLock);
//DLL_VLC_MEDIADLL void SetDisPicture(libvlc_video_display_cb unDisplay);
//DLL_VLC_MEDIADLL void setParam(void * parm); //参数定义
DLL_VLC_MEDIADLL void InitVLC();
DLL_VLC_MEDIADLL void realseVLC();
DLL_VLC_MEDIADLL void setMediaAddress(char* file, void* wId = 0);//如果句柄为0时,可以在页面上编辑,如果不为0时只能用于显示
DLL_VLC_MEDIADLL void play_RtspVideo();
DLL_VLC_MEDIADLL void setSizeWH(int width, int heigth);
DLL_VLC_MEDIADLL void setCache(int nTime);
DLL_VLC_MEDIADLL void setCallParam(libvlc_video_lock_cb lock_param, libvlc_video_unlock_cb unlock_param, libvlc_video_display_cb display_parm, void *parm);
DLL_VLC_MEDIADLL void start_player_record(const char *path);
DLL_VLC_MEDIADLL void stop_player_record();
class vlcManager
{
public:
vlcManager();
~vlcManager();
void init();
void realse();
static vlcManager *getInstance();
void setCache(int cache); //设置缓冲时间。
void setMedia(char *address, void* id);
void setId(void * id);
void setVolume(int volume); //设置音量。
char *getUrl(); //获得当前地址。
void start_record(const char *path);
void stop_record();
//播放控制方法:播放、暂停、停止
void playRtsp();
void pause();
void stop();
private:
//vlc指针。
libvlc_instance_t *base;
libvlc_media_t *media;
libvlc_media_player_t *player;
static vlcManager *m_instance;
void * m_id;
//缓冲时间。
int cache;
};
在VLC_MediaDLL.cpp文件中添加实现:
// VLC_MediaDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "VLC_MediaDLL.h"
vlcManager* vlcManager::m_instance = NULL;
static libvlc_video_lock_cb g_lockPicture = NULL;
static libvlc_video_unlock_cb g_unlockPicture = NULL;
static libvlc_video_display_cb g_displayPicture = NULL;
static void *g_opaque = NULL;
static int height = 400;
static int width = 400;
void setSizeWH(int w, int h)
{
height = h;
width = w;
}
void start_player_record(const char *path)
{
vlcManager::getInstance()->start_record(path);
}
void stop_player_record()
{
vlcManager::getInstance()->stop_record();
}
void setCallParam(libvlc_video_lock_cb lock_param, libvlc_video_unlock_cb unlock_param, libvlc_video_display_cb display_parm, void *parm)
{
g_lockPicture = lock_param;
g_unlockPicture = unlock_param;
g_displayPicture = display_parm;
g_opaque = parm;
}
void InitVLC()
{
vlcManager::getInstance()->init();
}
void realseVLC()
{
vlcManager::getInstance()->realse();
}
void setMediaAddress(char* file, void * wId)
{
vlcManager::getInstance()->setMedia(file, wId);
}
void play_RtspVideo()
{
vlcManager::getInstance()->playRtsp();
}
void setCache(int nTime)
{
vlcManager::getInstance()->setCache(nTime);
}
/*
void SetLockPicture(libvlc_video_lock_cb cbFunMsgEntry)
{
g_lockPicture = cbFunMsgEntry;
}
void SetUnLockPicture(libvlc_video_unlock_cb unLock)
{
g_unlockPicture = unLock;
}
void SetDisPicture(libvlc_video_display_cb unDisplay)
{
g_displayPicture = unDisplay;
}
void setParam(void * parm)
{
g_opaque = parm;
}
*/
vlcManager* vlcManager::getInstance()
{
if (!m_instance)
{
m_instance = new vlcManager;
}
return m_instance;
}
vlcManager::vlcManager()
{
/*base = libvlc_new(0, NULL);
media = NULL;
player = libvlc_media_player_new(base);
cache = 2000;*/
}
void vlcManager::init()
{
base = libvlc_new(0, NULL);
media = NULL;
player = libvlc_media_player_new(base);
cache = 2000;
}
void vlcManager::realse()
{
libvlc_media_player_release(player);
libvlc_media_release(media);
libvlc_release(base);
}
vlcManager::~vlcManager()
{
/*libvlc_media_player_release(player);
libvlc_media_release(media);
libvlc_release(base);*/
}
void vlcManager::setCache(int cache)
{
this->cache = cache;
}
void vlcManager::setMedia(char *address, void* id)
{
m_id = id;
libvlc_media_release(media);
media = libvlc_media_new_location(base, address);
player = libvlc_media_player_new_from_media(media);
if (id != 0)
{
libvlc_media_player_set_hwnd(player, (void *)id);
}
}
void vlcManager::setId(void* id)
{
libvlc_media_player_set_hwnd(player, (void *)id);
}
void vlcManager::setVolume(int volume)
{
libvlc_audio_set_volume(player, volume);
}
int getTest()
{
return 2;
}
char *vlcManager::getUrl()
{
return libvlc_media_get_mrl(media);
}
void vlcManager::playRtsp()
{
//获得char ×类型的缓冲时间参数。
std::string para = "network-caching=";
char ws[128];
sprintf_s(ws, "%s%d", para, cache);
libvlc_media_add_option(media, ws);
if (m_id == 0)
{
libvlc_video_set_callbacks(player, g_lockPicture, g_unlockPicture, g_displayPicture, g_opaque);
}
libvlc_video_set_format(player, "RGBA", width, height, width * 4);
libvlc_media_player_play(player);
}
void vlcManager::pause()
{
libvlc_media_player_pause(player);
}
void vlcManager::stop()
{
libvlc_media_player_stop(player);
}
void vlcManager::start_record(const char *path)
{
libvlc_media_player_recorder_start(player, path);
}
void vlcManager::stop_record()
{
libvlc_media_player_recorder_stop(player);
}
这样就可以生成dll文件了,在VS下添加 QT GUI 测试程序
//testDLL.h
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_testDll.h"
#include <QPixmap>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QColor>
#include <QPainter>
#include <QPalette>
#include <QPixmap>
#include <QPoint>
#include <QImage>
#include <QMap>
#include <QJsonArray>
const int n_width = 300;
const int n_height = 300;
class testDll : public QMainWindow
{
Q_OBJECT
public:
testDll(QWidget *parent = Q_NULLPTR);
~testDll();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void updatePicture(const QImage &image);
static void *lock(void *op, void **plane);
static void unlock(void *op, void *pic, void *const *plane);
static void display(void *op, void *pic);
private:
Ui::testDllClass ui;
QImage m_FramePix;
typedef QVector<QPoint> VecPoint;
QMap<int, VecPoint> m_map;
VecPoint m_vecPoint;
};
typedef struct TCallbackParam
{
QMutex mutex;
//testDll wnd;
uchar *pixels;
}TCallbackParam;
//testDLL.cpp文件如下:
#include "testDll.h"
#include "VLC_MediaDLL.h"
#include <windows.h>
testDll *g_testDLL = nullptr;
testDll::testDll(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
InitVLC();
g_testDLL = this;
char *addr = "rtsp://admin:[email protected]";
setMediaAddress(addr, (void*)this->winId());
setCache(2000);
setSizeWH(n_width, n_height);
TCallbackParam *param = new TCallbackParam;
param->pixels = new uchar[n_width * n_height * 4];
memset(param->pixels, 0, n_width * n_height * 4);
setCallParam(lock, unlock, display, param);
//set_video_toggle_path("E:\\11\\1.avf");
play_RtspVideo();
QString str = "textfile";
start_player_record(str.toStdString().c_str());
Sleep(10000);
stop_player_record();
}
testDll::~testDll()
{
realseVLC();
}
void *testDll::lock(void *op, void **plane)
{
TCallbackParam *p = (TCallbackParam *)op;
p->mutex.lock();
*plane = p->pixels;
return NULL;
}
#include <QFile>
#include<iostream>
#include<fstream>
void testDll::unlock(void *op, void *pic, void *const *plane)
{
TCallbackParam *p = (TCallbackParam *)op;
uchar *pp = (uchar *)*plane;
unsigned char *data = (unsigned char *)*plane;
std::fstream file("fir.txt", std::ofstream::app | std::ios::binary | std::ofstream::out);
QImage a(data, n_width, n_height, QImage::Format_ARGB32);
g_testDLL->updatePicture(a);
p->mutex.unlock();
}
void testDll::display(void *op, void *pic)
{
(void)op;
}
void testDll::mousePressEvent(QMouseEvent *event)
{
m_map.clear();
m_vecPoint.clear();
QPoint tempP = event->pos();
m_vecPoint.push_back(event->pos());
}
void testDll::mouseMoveEvent(QMouseEvent *event)
{
m_vecPoint.push_back(event->pos());
update();
}
void testDll::updatePicture(const QImage &image)
{
m_FramePix = image;
//m_FramePix = QPixmap::fromImage(image);
update();
}
void testDll::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawImage(this->rect(), m_FramePix);
QPen pen;
pen.setColor(QColor(0, 0, 0));
pen.setWidth(2);
painter.setPen(pen);
for (int i = 1; i < m_vecPoint.size(); i++)
{
painter.drawLine(m_vecPoint.at(i), m_vecPoint.at(i - 1));
}
}