Browse Source

V1.0
1、完成了对视频播放器动态库的封装

apple 2 days ago
parent
commit
8069e47719
24 changed files with 527 additions and 0 deletions
  1. 5 0
      Libraries/Libraries.cmake
  2. 78 0
      Libraries/OpenGLWidget/FindOpenGLWidget.cmake
  3. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidget.dll
  4. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidget.dll.a
  5. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll
  6. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll.a
  7. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidget.dll
  8. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidget.dll.a
  9. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidgetd.dll
  10. BIN
      Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidgetd.dll.a
  11. 160 0
      Libraries/OpenGLWidget/src/OpenGLWidgetAPI.cpp
  12. 42 0
      Libraries/OpenGLWidget/src/OpenGLWidgetAPI.h
  13. 78 0
      Libraries/VideoPlayer/FindVideoPlayer.cmake
  14. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayer.dll
  15. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayer.dll.a
  16. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayerd.dll
  17. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayerd.dll.a
  18. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayer.dll
  19. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayer.dll.a
  20. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayerd.dll
  21. BIN
      Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayerd.dll.a
  22. 54 0
      Libraries/VideoPlayer/src/IVideoPlayer.h
  23. 84 0
      Libraries/VideoPlayer/src/VideoPlayerAPI.cpp
  24. 26 0
      Libraries/VideoPlayer/src/VideoPlayerAPI.h

+ 5 - 0
Libraries/Libraries.cmake

@@ -56,6 +56,8 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CURL)
 #链接FreeType库,目前只支持Windows
 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/FreeType)
 list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/QXlsx)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/OpenGLWidget)
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/VideoPlayer)
 
 #搜索所有的库
 # find_package(fmt REQUIRED)
@@ -74,6 +76,9 @@ find_package(LHHTTPAPI REQUIRED)
 
 find_package(QXlsx REQUIRED)
 
+#获取OpenGLWidget的api文件
+find_package(OpenGLWidget REQUIRED)
+find_package(VideoPlayer REQUIRED)
 
 #有些库缺少某些平台、编译器的库,所以这里也根据平台、编译器进行搜索
 if(CMAKE_SYSTEM_NAME MATCHES "Windows")

+ 78 - 0
Libraries/OpenGLWidget/FindOpenGLWidget.cmake

@@ -0,0 +1,78 @@
+
+
+#使用OpenGL绘制图片
+
+message(STATUS "***** Find OpenGLWidget Library *****")
+
+
+#寻找头文件,需要判断gcc编译器版本
+unset(OpenGLWidget_INCLUDE_DIR CACHE)
+unset(OpenGLWidget_SOURCE_DIR CACHE)
+
+set(OpenGLWidget_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
+set(OpenGLWidget_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
+
+unset(libDebug CACHE)
+unset(libRelease CACHE)
+unset(OpenGLWidget_LIBRARY CACHE)
+#查找库文件,需要判断操作系统,位数
+if(CMAKE_SYSTEM_NAME MATCHES "Windows")
+    #GCC编译器
+    if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+        #64位
+        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+            #判断Qt版本,是Qt5.15还是5.12
+            if(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 15)
+                set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.15.16/libOpenGLWidgetd.dll)
+                set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.15.16/libOpenGLWidget.dll)
+            elseif(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 12)
+                set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll)
+                set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidget.dll)
+            endif()
+        #32位
+        elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+            #判断Qt版本,是Qt5.15还是5.12
+            if(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 15)
+                message(STATUS "32位仅支持Qt5.12.12版本")
+            elseif(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 12)
+                set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll)
+                set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidget.dll)
+            endif()
+        endif()
+    #MSVC编译器
+    elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+        message(STATUS "暂不支持MSVC编译器")
+    endif()
+#添加Linux版本
+elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
+    set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/linux/libOpenGLWidgetd.so)
+    set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/linux/libOpenGLWidget.so)
+#MacOS版本
+elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    #MacOS版本
+    message(STATUS "暂不支持MacOS版本")
+
+endif()
+
+if(CMAKE_BUILD_TYPE MATCHES "Debug")
+    list(APPEND OpenGLWidget_LIBRARY ${libDebug})
+else()
+    list(APPEND OpenGLWidget_LIBRARY ${libRelease})
+endif()
+
+
+
+if(OpenGLWidget_INCLUDE_DIR AND OpenGLWidget_SOURCE_DIR AND OpenGLWidget_LIBRARY)
+    set(OpenGLWidget_FOUND TRUE)
+    set(OpenGLWidget_VERSION 1.0.0.0)
+
+    message(STATUS "include : OpenGLWidget_INCLUDE_DIR")
+    message(STATUS "source : OpenGLWidget_SOURCE_DIR")
+
+else()
+    set(OpenGLWidget_FOUND FALSE)
+endif()
+
+message(STATUS "OpenGLWidget FOUND: ${OpenGLWidget_FOUND}")
+message(STATUS "OpenGLWidget Version: ${OpenGLWidget_VERSION}")
+message(STATUS "--------------------------------------------------")

BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidget.dll


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidget.dll.a


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll.a


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidget.dll


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidget.dll.a


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidgetd.dll


BIN
Libraries/OpenGLWidget/Libs/windows/Qt5.15.16/libOpenGLWidgetd.dll.a


+ 160 - 0
Libraries/OpenGLWidget/src/OpenGLWidgetAPI.cpp

@@ -0,0 +1,160 @@
+#include "OpenGLWidgetAPI.h"
+
+#include <QApplication>
+#include <QLibrary>
+
+#include "spdlog/spdlog.h"
+
+Image_YUV420P::Image_YUV420P(Image_YUV420P&& other): width(other.width), height(other.height),
+          yData(std::move(other.yData)), uData(std::move(other.uData)), vData(std::move(other.vData))
+{}
+
+Image_YUV420P::Image_YUV420P(const Image_YUV420P& other)
+        : width(other.width), height(other.height),
+          yData(other.yData), uData(other.uData), vData(other.vData)
+{}
+
+Image_YUV420P& Image_YUV420P::operator=(Image_YUV420P&& other) 
+{
+    if (this != &other) {
+        width = other.width;
+        height = other.height;
+        yData = std::move(other.yData);
+        uData = std::move(other.uData);
+        vData = std::move(other.vData);
+    }
+    return *this;
+}
+
+Image_YUV420P& Image_YUV420P::operator=(const Image_YUV420P& other) 
+{
+    if (this != &other) {
+        width = other.width;
+        height = other.height;
+        yData = other.yData;
+        uData = other.uData;
+        vData = other.vData;
+    }
+    return *this;
+}
+
+bool Image_YUV420P::isValid() const 
+{
+    return width > 0 && height > 0 && !yData.isEmpty() && !uData.isEmpty() && !vData.isEmpty();
+}
+
+void Image_YUV420P::clear()
+{
+    width = 0;
+    height = 0;
+    yData.clear();
+    uData.clear();
+    vData.clear();
+}
+
+/* ----------------------------------------------------------------
+ * OpenGLWidget动态库 API
+ * ---------------------------------------------------------------- */
+
+using funcCreateOpenGLWidget = QWidget* (*)(QWidget*);
+using funcDestroyOpenGLWidget = void (*)(QWidget* widget);
+using funcRefreshRGBAImage = void (*)(QWidget* widget, QImage& image);
+using funcRefreshYUV420Image = void (*)(QWidget* widget, Image_YUV420P* yuvData);
+
+
+funcCreateOpenGLWidget pCreateOpenGLWidget = nullptr;
+funcDestroyOpenGLWidget pDestroyOpenGLWidget = nullptr;
+funcRefreshRGBAImage pRefreshRGBAImage = nullptr;
+funcRefreshYUV420Image pRefreshYUV420Image = nullptr;
+
+static std::atomic_bool isLibraryLoaded = false;
+/* 加载动态库 */
+bool loadOpenGLWidgetLibrary()
+{
+    if(isLibraryLoaded.load()) 
+    {
+        return true;
+    }
+
+    QString libPath = QApplication::applicationDirPath();
+#ifdef QT_DEBUG
+    libPath += "/libOpenGLWidgetd"; // Debug版本
+#else
+    libPath += "/libOpenGLWidget"; // Release版本
+#endif
+
+#ifdef Q_OS_WIN
+    libPath += ".dll";
+#elif defined(Q_OS_MACOS)
+    libPath += ".dylib";
+#elif defined(Q_OS_LINUX)
+    libPath += ".so";
+#endif
+    QLibrary lib(libPath);
+    if (!lib.load()) 
+    {
+        SPDLOG_ERROR("加载OpenGLWidget动态库失败: {}", libPath.toStdString());
+        SPDLOG_ERROR("错误信息: {}", lib.errorString().toStdString());
+        return false;
+    }
+
+    pCreateOpenGLWidget = reinterpret_cast<funcCreateOpenGLWidget>(lib.resolve("createOpenGLWidget"));
+    pDestroyOpenGLWidget = reinterpret_cast<funcDestroyOpenGLWidget>(lib.resolve("destroyOpenGLWidget"));
+    pRefreshRGBAImage = reinterpret_cast<funcRefreshRGBAImage>(lib.resolve("refreshRGBAImage"));
+    pRefreshYUV420Image = reinterpret_cast<funcRefreshYUV420Image>(lib.resolve("refreshYUV420Image"));
+
+    if(!pCreateOpenGLWidget || !pDestroyOpenGLWidget || 
+       !pRefreshRGBAImage || !pRefreshYUV420Image) 
+    {
+        SPDLOG_ERROR("加载OpenGLWidget动态库函数失败");
+        return false;
+    }
+
+    isLibraryLoaded = true;
+    return true;
+}
+
+/* 创建OpenGL窗口,返回QWidget指针 */
+QWidget* createOpenGLWidget(QWidget* parent)
+{
+    if(pCreateOpenGLWidget == nullptr) 
+    {
+        SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
+        return nullptr;
+    }
+    return pCreateOpenGLWidget(parent);
+}
+
+/* 销毁OpenGL窗口 */
+void destroyOpenGLWidget(QWidget* widget)
+{
+    if(pDestroyOpenGLWidget == nullptr) 
+    {
+        SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
+        return;
+    }
+    pDestroyOpenGLWidget(widget);
+}
+
+/* 刷新一帧RGBA图片 */
+void refreshRGBAImage(QWidget* widget, QImage& image)
+{
+    if(pRefreshRGBAImage == nullptr) 
+    {
+        SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
+        return;
+    }
+    pRefreshRGBAImage(widget, image);
+}
+
+/* 刷新一帧YUV420图片 */
+void refreshYUV420Image(QWidget* widget, Image_YUV420P& yuvData)
+{
+    if(pRefreshYUV420Image == nullptr) 
+    {
+        SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
+        return;
+    }
+    pRefreshYUV420Image(widget, &yuvData);
+}
+

+ 42 - 0
Libraries/OpenGLWidget/src/OpenGLWidgetAPI.h

@@ -0,0 +1,42 @@
+#ifndef _OPENGLWIDGETAPI_H_
+#define _OPENGLWIDGETAPI_H_
+
+#include <QWidget>
+#include <QString>
+
+/**
+ * @brief YUV420图片格式
+ * 
+ */
+struct Image_YUV420P
+{
+    int width;          /* 宽度 */
+    int height;         /* 高度 */
+    QByteArray yData;   /* Y分量数据 */
+    QByteArray uData;   /* U分量数据 */
+    QByteArray vData;   /* V分量数据 */
+
+    Image_YUV420P() : width(0), height(0) {}
+    Image_YUV420P(Image_YUV420P&& other);
+    Image_YUV420P(const Image_YUV420P& other);
+    Image_YUV420P& operator=(Image_YUV420P&& other);
+    Image_YUV420P& operator=(const Image_YUV420P& other);
+    bool isValid() const;
+    void clear();
+};
+
+/* 加载动态库 */
+bool loadOpenGLWidgetLibrary();
+
+/* 创建OpenGL窗口,返回QWidget指针 */
+QWidget* createOpenGLWidget(QWidget* parent = nullptr);
+/* 销毁OpenGL窗口 */
+void destroyOpenGLWidget(QWidget* widget);
+
+/* 刷新一帧RGBA图片 */
+void refreshRGBAImage(QWidget* widget, QImage& image);
+/* 刷新一帧YUV420图片 */
+void refreshYUV420Image(QWidget* widget, Image_YUV420P& yuvData);
+
+
+#endif // _OPENGLWIDGETAPI_H_

+ 78 - 0
Libraries/VideoPlayer/FindVideoPlayer.cmake

@@ -0,0 +1,78 @@
+
+
+#使用OpenGL绘制图片
+
+message(STATUS "***** Find VideoPlayer Library *****")
+
+
+#寻找头文件,需要判断gcc编译器版本
+unset(VideoPlayer_INCLUDE_DIR CACHE)
+unset(VideoPlayer_SOURCE_DIR CACHE)
+
+set(VideoPlayer_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
+set(VideoPlayer_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/src)
+
+unset(libDebug CACHE)
+unset(libRelease CACHE)
+unset(VideoPlayer_LIBRARY CACHE)
+#查找库文件,需要判断操作系统,位数
+if(CMAKE_SYSTEM_NAME MATCHES "Windows")
+    #GCC编译器
+    if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+        #64位
+        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+            #判断Qt版本,是Qt5.15还是5.12
+            if(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 15)
+                set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.15.16/libOpenGLWidgetd.dll)
+                set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.15.16/libOpenGLWidget.dll)
+            elseif(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 12)
+                set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll)
+                set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidget.dll)
+            endif()
+        #32位
+        elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
+            #判断Qt版本,是Qt5.15还是5.12
+            if(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 15)
+                message(STATUS "32位仅支持Qt5.12.12版本")
+            elseif(QT_VERSION_MAJOR EQUAL 5 AND QT_VERSION_MINOR EQUAL 12)
+                set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidgetd.dll)
+                set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/windows/Qt5.12.12/libOpenGLWidget.dll)
+            endif()
+        endif()
+    #MSVC编译器
+    elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+        message(STATUS "暂不支持MSVC编译器")
+    endif()
+#添加Linux版本
+elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
+    set(libDebug ${CMAKE_CURRENT_LIST_DIR}/Libs/linux/libOpenGLWidgetd.so)
+    set(libRelease ${CMAKE_CURRENT_LIST_DIR}/Libs/linux/libOpenGLWidget.so)
+#MacOS版本
+elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+    #MacOS版本
+    message(STATUS "暂不支持MacOS版本")
+
+endif()
+
+if(CMAKE_BUILD_TYPE MATCHES "Debug")
+    list(APPEND VideoPlayer_LIBRARY ${libDebug})
+else()
+    list(APPEND VideoPlayer_LIBRARY ${libRelease})
+endif()
+
+
+
+if(VideoPlayer_INCLUDE_DIR AND VideoPlayer_SOURCE_DIR AND VideoPlayer_LIBRARY)
+    set(VideoPlayer_FOUND TRUE)
+    set(VideoPlayer_VERSION 1.0.0.0)
+
+    message(STATUS "include : VideoPlayer_INCLUDE_DIR")
+    message(STATUS "source : VideoPlayer_SOURCE_DIR")
+
+else()
+    set(VideoPlayer_FOUND FALSE)
+endif()
+
+message(STATUS "VideoPlayer FOUND: ${VideoPlayer_FOUND}")
+message(STATUS "VideoPlayer Version: ${VideoPlayer_VERSION}")
+message(STATUS "--------------------------------------------------")

BIN
Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayer.dll


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayer.dll.a


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayerd.dll


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.12.12/libVideoPlayerd.dll.a


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayer.dll


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayer.dll.a


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayerd.dll


BIN
Libraries/VideoPlayer/Libs/windows/Qt5.15.16/libVideoPlayerd.dll.a


+ 54 - 0
Libraries/VideoPlayer/src/IVideoPlayer.h

@@ -0,0 +1,54 @@
+#ifndef _IVIDEOPLAYER_H_
+#define _IVIDEOPLAYER_H_
+
+#include <QObject>
+
+class IVideoPlayer : public QObject
+{
+    Q_OBJECT
+public:
+
+    explicit IVideoPlayer() {}
+    virtual ~IVideoPlayer() {}
+
+    /* 打开播放视频 */
+    virtual bool openPlayVedio(const QString& fileName) = 0;
+    /* 播放视频 */
+    virtual bool play() = 0;
+    /* 暂停播放 */
+    virtual void pause() = 0;
+    /* 停止播放 */
+    virtual void stop() = 0;
+    /* 后退,单位ms */
+    virtual void backward(qint64 ms) = 0;
+    /* 前进,单位ms */
+    virtual void forward(qint64 ms) = 0;
+
+    /* 获取播放状态 */
+    virtual bool getPlayStatus() = 0;
+    /* 获取视频时长 */
+    virtual qint64 getDuration() = 0;
+    /* 获取当前播放位置 */
+    virtual qint64 getCurrentPos() = 0;
+    /* 设置当前播放位置 */
+    virtual void setCurrentPos(qint64 pos) = 0;
+
+    /* 设置播放视频窗口的大小 */
+    virtual void setPlayWidgetSize(int width,int height) = 0;
+    /* 设置播放窗口 */
+    virtual void setWidgetParent(QWidget* widget, bool isFull = false) = 0;
+    /* 获取播放窗口的指针 */
+    virtual QWidget* getPlayWidget() const = 0;
+    /* 设置预览图片数目,在暂停时跳转,可能会有花屏或者黑帧,可以设置跳转图片个数跳过黑帧 */
+    virtual void setPreviewImage(int num = 2) = 0;
+    /* 设置播放速度 */
+    virtual void setPlaySpeed(float speed) = 0;
+
+signals:
+    void signal_playCompleted();                    /* 播放完成信号 */
+    // void signal_refreshImage();                     /* 刷新图片信号 */
+
+};
+
+
+#endif /* _IVIDEOPLAYER_H_ */

+ 84 - 0
Libraries/VideoPlayer/src/VideoPlayerAPI.cpp

@@ -0,0 +1,84 @@
+#include "VideoPlayerAPI.h"
+
+#include <QApplication>
+#include <QLibrary>
+#include <qchar.h>
+#include <qlibrary.h>
+
+#include "spdlog/spdlog.h"
+
+/* 定义函数 */
+using FuncCreateVideoPlayer = IVideoPlayer* (*)();
+using FuncDestroyVideoPlayer = void (*)(IVideoPlayer* player);
+
+/* 创建函数指针 */
+FuncCreateVideoPlayer pCreateVideoPlayer = nullptr;
+FuncDestroyVideoPlayer pDestroyVideoPlayer = nullptr;
+
+
+/* 加载动态库 */
+bool loadVideoPlayerLibrary()
+{
+    QString libPath = QApplication::applicationDirPath();
+
+#ifdef QT_DEBUG
+    libPath += "/libVideoPlayerd"; // Debug版本
+#else
+    libPath += "/libVideoPlayer"; // Release版本
+#endif
+
+
+#if defined (Q_OS_LINUX)
+    libPath += ".so"; // 或者 .dll 或者 .dylib
+#elif defined (Q_OS_WIN)
+    libPath += ".dll"; // Windows下的动态库
+#elif defined (Q_OS_MACOS)
+    libPath += ".dylib"; // macOS下的动态库
+#endif
+
+    QLibrary lib(libPath);
+    if(!lib.load())
+    {
+        SPDLOG_ERROR("加载VideoPlayerAPI库失败: {}", lib.errorString().toStdString());
+        SPDLOG_ERROR("VideoPlayer动态库路径: {}", libPath.toStdString());
+        return false;
+    }
+
+    pCreateVideoPlayer = reinterpret_cast<FuncCreateVideoPlayer>(lib.resolve("createVideoPlayer"));
+    if(!pCreateVideoPlayer)
+    {
+        SPDLOG_ERROR("无法解析createVideoPlayer函数: {}", lib.errorString().toStdString());
+        return false;
+    }
+    pDestroyVideoPlayer = reinterpret_cast<FuncDestroyVideoPlayer>(lib.resolve("destroyVideoPlayer"));
+    if(!pDestroyVideoPlayer)
+    {
+        SPDLOG_ERROR("无法解析destroyVideoPlayer函数: {}", lib.errorString().toStdString());
+        return false;
+    }
+
+    return true;
+}
+
+/* 创建播放器 */
+IVideoPlayer* createPlayer()
+{
+    if(pCreateVideoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("createVideoPlayer函数指针为空,请先加载动态库");
+        return nullptr;
+    }
+    return pCreateVideoPlayer();
+}
+
+/* 销毁播放器 */
+void destroyPlayer(IVideoPlayer* player)
+{
+    if(pDestroyVideoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("destroyVideoPlayer函数指针为空,请先加载动态库");
+        return;
+    }
+    pDestroyVideoPlayer(player);
+}
+

+ 26 - 0
Libraries/VideoPlayer/src/VideoPlayerAPI.h

@@ -0,0 +1,26 @@
+#ifndef _VIDEOPLAYERAPI_H_
+#define _VIDEOPLAYERAPI_H_
+
+
+#include "IVideoPlayer.h"
+
+
+
+extern "C" {
+
+
+/* 加载动态库 */
+bool loadVideoPlayerLibrary();
+
+/* 创建播放器 */
+IVideoPlayer* createPlayer();
+/* 销毁播放器 */
+void destroyPlayer(IVideoPlayer* player);
+
+
+
+};
+
+
+
+#endif /* _VIDEOPLAYERAPI_H_ */