VLC Rtsp视频流的播放及 VLC dll的封装及调用

录像添加的实现: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));
    }

}
 

猜你喜欢

转载自blog.csdn.net/qq_16628589/article/details/85063552