测试环境
- MSVC-2015
- Qt 5.14.2
- QCreator
1. libVLC(关键步骤)
参考:心流剑
libVLC 各版本 下载链接
我的下载版本为:3.0.11
- 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_ReleaseTARGET = 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_playerlibvlc_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 playinglibvlc_media_player_stop(pPlayer);// Free the media_playerlibvlc_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 += -lVLCQtCoredLIBS += -lVLCQtWidgetsd
}
else{LIBS += -lVLCQtCoreLIBS += -lVLCQtWidgets
}############ 设置输出路径、文件名、加载的链接库 ###############
CONFIG(debug, debug|release){DESTDIR =$$PWD/../bin_Debug # 输出目录TARGET = QVLCDemod # 输出文件名
}
else{DESTDIR =$$PWD/../bin_ReleaseTARGET = 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 480struct 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;
}