用VLC开发视频播放器/组件(两种方式:libVLC / VLC-Qt)

16627503:

测试环境

  • MSVC-2015
  • Qt 5.14.2
  • QCreator

1. libVLC(关键步骤)

参考:心流剑

libVLC 各版本 下载链接

我的下载版本为:3.0.11
在这里插入图片描述

  • sdk/lib文件夹目录
    sdk/lib文件夹
  • qmake vlc 部分的配置(路径根据自己的修改)
  • 只需要: libvlc.lib、libvlccore.lib
#####################  VLC 库 ############################
INCLUDEPATH += $$PWD/../vlc/sdk/include
LIBS += -L$$PWD/../vlc/sdk/lib
LIBS += -llibvlccore
LIBS += -llibvlc

############ 设置输出路径、文件名、加载的链接库 ###############
CONFIG(debug, debug|release){
    
    
    DESTDIR =$$PWD/../bin_Debug # 输出目录
    TARGET = XVLCDemod  # 输出文件名
}
else{
    
    
    DESTDIR =$$PWD/../bin_Release
    TARGET = XVLCDemo
}
  • 把 plugins 文件夹、libvlc.dll、libvlccore.dll 复制到 bin_Debug / bin_Release
#include <QCoreApplication>

#ifdef _WIN32
#include <basetsd.h>
typedef SSIZE_T ssize_t;
#endif

#include <QDebug>

#include "vlc/vlc.h"

int main(int argc, char *argv[])
{
    
    
//    QCoreApplication a(argc, argv);
    libvlc_instance_t     * pInstance = nullptr;
    libvlc_media_player_t * pPlayer = nullptr;
    libvlc_media_t        * pMedia = nullptr;

    libvlc_time_t length;
    int width;
    int height;
    int wait_time = 5000;
    //libvlc_time_t length;
    /* Load the VLC engine */
    pInstance = libvlc_new(0, 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:
    // 创建一个流媒体(视频/音频对象)
    pMedia = libvlc_media_new_path(pInstance, "C:\\Users\\YuLei\\Desktop\\ch4.mp4");
    if (!pMedia)
    {
    
    
        qDebug() << "libvlc_media_new_path  fail!!!";
        return -1;
    }
    // 创建一个播放窗口(环境),加载流
    pPlayer = libvlc_media_player_new_from_media(pMedia);
    /* No need to keep the media now */
    libvlc_media_release(pMedia);
    // play the media_player
    libvlc_media_player_play(pPlayer);
    //wait until the tracks are created
    _sleep(wait_time);
    length  = libvlc_media_player_get_length(pPlayer);
    width   = libvlc_video_get_width(pPlayer);
    height  = libvlc_video_get_height(pPlayer);
    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(pPlayer);
    // Free the media_player
    libvlc_media_player_release(pPlayer);
    libvlc_release(pInstance);
    return  0;
//    return a.exec();
}

2. VLC-Qt(关键步骤)

VLC-Qt 下载地址
参考链接1:链接
参考链接2:链接
在这里插入图片描述

  • v1.1.1版本仅提供源码
    在这里插入图片描述
  • 采用 v1.1.0 版本 链接

在这里插入图片描述

  • qmake 配置
#####################  VLC 库 ############################
INCLUDEPATH += $$PWD/../vlc_qt/include
LIBS += -L$$PWD/../vlc_qt/lib
CONFIG(debug, debug|release){
    
    
    LIBS += -lVLCQtCored
    LIBS += -lVLCQtWidgetsd
}
else{
    
    
    LIBS += -lVLCQtCore
    LIBS += -lVLCQtWidgets
}

############ 设置输出路径、文件名、加载的链接库 ###############
CONFIG(debug, debug|release){
    
    
    DESTDIR =$$PWD/../bin_Debug # 输出目录
    TARGET = QVLCDemod  # 输出文件名
}
else{
    
    
    DESTDIR =$$PWD/../bin_Release
    TARGET = QVLCDemo
}

抽帧

libVLC

参考链接1
参考链接2

/**
 *  mp:媒体播放器
 *  lock:回调以锁定视频内存(不能为 NULL)
 *  unlock:回调以解锁视频内存(如果不需要,则为 NULL)
 *  display:回调以显示视频(如果不需要,则为 NULL)
 *  opaque:这三个回调的私有指针(作为第一个参数)
 */
void libvlc_video_set_callbacks( libvlc_media_player_t *mp,
                                 libvlc_video_lock_cb lock,
                                 libvlc_video_unlock_cb unlock,
                                 libvlc_video_display_cb display,
                                 void *opaque );

// 当需要解码新的视频帧时,就会调用 lock 回调。
typedef void *(*libvlc_video_lock_cb)(void *opaque, void **planes);

// 当视频帧解码完成后,将调用 unlock 回调。
typedef void (*libvlc_video_unlock_cb)(void *opaque, void *picture,
                                       void *const *planes);

// 当视频帧需要显示时,将调用 display 回调。
typedef void (*libvlc_video_display_cb)(void *opaque, void *picture);
#include 
#include 
#include 
#include 
#include 

// 定义输出视频的分辨率
#define VIDEO_WIDTH   640
#define VIDEO_HEIGHT  480

struct Context {
    
    
    QMutex mutex;
    uchar *pixels;
};

static void *lock(void *opaque, void **planes)
{
    
    
    struct Context *ctx = static_cast(opaque);
    ctx->mutex.lock();

    // 告诉 VLC 将解码的数据放到缓冲区中
    *planes = ctx->pixels;

    return nullptr;
}

// 获取 argb 图片并保存到文件中
static void unlock(void *opaque, void *picture, void *const *planes)
{
    
    
    Q_UNUSED(picture);

    struct Context *ctx = static_cast(opaque);
    unsigned char *data = static_cast<unsigned char *>(*planes);
    static int frameCount = 1;

    QImage image(data, VIDEO_WIDTH, VIDEO_HEIGHT, QImage::Format_ARGB32);
    image.save(QString("frame_%1.png").arg(frameCount++));

    ctx->mutex.unlock();
}

static void display(void *opaque, void *picture)
{
    
    
    Q_UNUSED(picture);

    (void)opaque;
}

int main()
{
    
    
    const char *localMrl = "Sample.mkv";

    struct Context ctx;
    ctx.pixels = new uchar[VIDEO_WIDTH * VIDEO_HEIGHT * 4];
    memset(ctx.pixels, 0, VIDEO_WIDTH * VIDEO_HEIGHT * 4);

    libvlc_instance_t *instance;
    libvlc_media_player_t *player;
    libvlc_media_t *media;

    instance = libvlc_new(0, nullptr);
    media = libvlc_media_new_path(instance, localMrl);
    player = libvlc_media_player_new_from_media(media);

    // 设置回调,用于提取帧或者在界面上显示。
    libvlc_video_set_callbacks(player, lock, unlock, display, &ctx);
    libvlc_video_set_format(player, "RGBA", VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_WIDTH * 4);

    libvlc_media_player_play(player);

    QThread::sleep(10);

    libvlc_media_release(media);
    libvlc_media_player_release(player);
    libvlc_release(instance);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/CXYYL/article/details/128673471