Browse Source

V0.7.19
1、抽象完成了VideoPlayer的api

apple 4 days ago
parent
commit
85fc7bf1a9

+ 3 - 3
CMakeLists.txt

@@ -196,8 +196,8 @@ add_subdirectory(${CMAKE_SOURCE_DIR}/demo/VideoPlayer)
 # add_subdirectory(${CMAKE_SOURCE_DIR}/demo/xlsx)
 # add_subdirectory(${CMAKE_SOURCE_DIR}/demo/DesignerPattern)
 # add_subdirectory(${CMAKE_SOURCE_DIR}/demo/ViewModel)
-add_subdirectory(${CMAKE_SOURCE_DIR}/demo/OpenGLWidget)
+# add_subdirectory(${CMAKE_SOURCE_DIR}/demo/OpenGLWidget)
 # add_subdirectory(${CMAKE_SOURCE_DIR}/demo/VideoPlayerGL)
-add_subdirectory(${CMAKE_SOURCE_DIR}/demo/OpenGLWidgetTest)
-
+# add_subdirectory(${CMAKE_SOURCE_DIR}/demo/OpenGLWidgetTest)
+add_subdirectory(${CMAKE_SOURCE_DIR}/demo/VideoPlayerLibrary)
 

+ 1 - 1
External

@@ -1 +1 @@
-Subproject commit 1921b59fff5902c4708b0137025a068d997fb93d
+Subproject commit 4bc45478c1cc4a944beec2d8df85b33459ad6e68

+ 54 - 0
demo/OpenGLWidgetTest/VideoPlayerAPI/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_ */

+ 4 - 1
demo/OpenGLWidgetTest/VideoPlayerAPI/VideoPlayerAPI.cpp

@@ -1 +1,4 @@
-#include "VideoPlayerAPI.h"
+#include "VideoPlayerAPI.h"
+
+#include "spdlog/spdlog.h"
+

+ 2 - 8
demo/OpenGLWidgetTest/VideoPlayerAPI/VideoPlayerAPI.h

@@ -2,16 +2,10 @@
 #define _VIDEOPLAYERAPI_H_
 
 
-#include <qchar.h>
-#include <qglobal.h>
-
-extern "C" {
-
-Q_DECL_EXPORT bool OpenVideo(const QString& fileName);
-
-
 
+class QWidget;
 
+extern "C" {
 
 
 

+ 9 - 13
demo/OpenGLWidgetTest/widget.cpp

@@ -4,9 +4,7 @@
 #include <QTimer>
 #include "spdlog/spdlog.h"
 
-#include "OpenGLWidgetAPI.h"
 
-#include "VideoPlayer.h"
 
 Widget::Widget(QWidget *parent)
     : QWidget(parent)
@@ -14,8 +12,6 @@ Widget::Widget(QWidget *parent)
 {
     ui->setupUi(this);
 
-    loadOpenGLWidgetLibrary(); // 加载OpenGL窗口库
-
     // m_playerGLWidget = createOpenGLWidget(ui->widget_display);
     // m_playerGLWidget->show(); // 显示OpenGL窗口
     // m_playerGLWidget->setGeometry(0, 0, ui->widget_display->width(), ui->widget_display->height());
@@ -56,16 +52,16 @@ void Widget::playVdeio()
     // QString videoFile = QApplication::applicationDirPath() + "/2024-07-11.mp4"; 
     QString videoFile = QApplication::applicationDirPath() + "/4K烤鸭.mp4"; // 测试视频文件
 
-    VideoPlayer* player = new VideoPlayer(this);
-    player->setWidgetParent(ui->widget_display, true); // 设置播放窗口
-    if(!player->openPlayVedio(videoFile))
-    {
-        SPDLOG_ERROR("Failed to open video file: {}", videoFile.toStdString());
-        delete player; // 释放资源
-        return;
-    }
+    // VideoPlayer* player = new VideoPlayer(this);
+    // player->setWidgetParent(ui->widget_display, true); // 设置播放窗口
+    // if(!player->openPlayVedio(videoFile))
+    // {
+    //     SPDLOG_ERROR("Failed to open video file: {}", videoFile.toStdString());
+    //     delete player; // 释放资源
+    //     return;
+    // }
 
-    player->play(); // 播放视频
+    // player->play(); // 播放视频
 }
 
 void Widget::resizeEvent(QResizeEvent *event) 

+ 1 - 1
demo/VideoPlayer/CMakeLists.txt

@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.10)
 
-set(this_exe VideoPlayer)
+set(this_exe VideoPlayer1)
 
 
 #包含源文件

+ 115 - 0
demo/VideoPlayerLibrary/CMakeLists.txt

@@ -0,0 +1,115 @@
+cmake_minimum_required(VERSION 3.10)
+
+set(libName VideoPlayer)
+
+
+
+#包含源文件
+file(GLOB LOCAL_SRC
+    ${CMAKE_CURRENT_SOURCE_DIR}/*.qrc
+    ${CMAKE_CURRENT_SOURCE_DIR}/*.rc
+    ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/*.ui
+    ${CMAKE_CURRENT_SOURCE_DIR}/OpenGLWidgetAPI/*.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/VideoPlayer/*.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/VideoPlayerAPI/*.cpp
+
+    ${CMAKE_SOURCE_DIR}/External/module/Logs/*.cpp
+    # ${CMAKE_SOURCE_DIR}/External/module/ThreadPool/*.cpp
+    
+)
+
+
+# 生成可执行程序
+
+add_library(${libName} SHARED
+    # WIN32
+    ${GLOBAL_SRC}
+    ${LOCAL_SRC} 
+)
+
+# set_target_properties(${libName} PROPERTIES
+    
+# )
+
+
+#添加头文件
+target_include_directories(${libName} PRIVATE
+
+    ${CMAKE_CURRENT_SOURCE_DIR}
+    ${CMAKE_CURRENT_SOURCE_DIR}/OpenGLWidgetAPI
+    ${CMAKE_CURRENT_SOURCE_DIR}/VideoPlayer
+    ${CMAKE_CURRENT_SOURCE_DIR}/VideoPlayerAPI
+
+    ${CMAKE_SOURCE_DIR}/External/common
+    ${CMAKE_SOURCE_DIR}/External/module
+    # ${CMAKE_SOURCE_DIR}/External/module/ThreadPool
+    ${CMAKE_SOURCE_DIR}/External/module/RingQueue
+    
+    ${spdlog_INCLUDE_DIR}
+    ${FFMPEG_INCLUDE_DIR}
+    
+)
+
+
+target_link_libraries(${libName} PRIVATE
+    Qt${QT_VERSION_MAJOR}::Widgets
+    Qt${QT_VERSION_MAJOR}::Core
+    # Qt${QT_VERSION_MAJOR}::Network
+    # Qt${QT_VERSION_MAJOR}::Gui
+
+)
+
+target_link_libraries(${libName} PRIVATE
+    # ${CURL_LIBRARY}
+    ${FFMPEG_LIBRARY}
+    ${spdlog_LIBRARY}
+
+)
+
+if(QT_VERSION_MAJOR EQUAL 5)
+    target_link_libraries(${libName} PRIVATE
+        Qt5::OpenGL
+    )
+elseif(QT_VERSION_MAJOR EQUAL 6)
+    target_link_libraries(${libName} PRIVATE
+        Qt6::OpenGLWidgets
+    )
+endif(QT_VERSION_MAJOR EQUAL 5)
+
+if(CMAKE_SYSTEM_NAME MATCHES "Windows")
+    target_link_libraries(${libName} PRIVATE 
+        opengl32
+    )
+elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
+    target_link_libraries(${libName} PRIVATE 
+        GL
+    )
+endif()
+
+# if(CMAKE_CXX_COMPILER_VERSION LESS 9.0)
+#     target_link_libraries(${libName} PRIVATE
+#         stdc++fs
+#     )
+# endif()
+
+
+
+# target_link_libraries(${libName} PRIVATE
+#     GL
+#     GUL
+# )
+# message(STATUS "CURL_LIBRARY: ${CURL_LIBRARY}")
+
+
+# if(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
+#     target_link_libraries(${libName} PRIVATE
+#         # debug spdlogd.lib
+#         # optimized spdlog.lib
+#     )
+# elseif(CMAKE_CXX_COMPILER_ID MATCHES GNU)
+#     target_link_libraries(${libName} PRIVATE
+#         # debug 
+#         # optimized ${SM_DLL}
+#     )
+# endif()

+ 0 - 0
demo/OpenGLWidgetTest/OpenGLWidgetAPI/OpenGLWidgetAPI.cpp → demo/VideoPlayerLibrary/OpenGLWidgetAPI/OpenGLWidgetAPI.cpp


+ 0 - 0
demo/OpenGLWidgetTest/OpenGLWidgetAPI/OpenGLWidgetAPI.h → demo/VideoPlayerLibrary/OpenGLWidgetAPI/OpenGLWidgetAPI.h


+ 5 - 5
demo/OpenGLWidgetTest/VideoPlayer/DecodeVedio.cpp → demo/VideoPlayerLibrary/VideoPlayer/DecodeVedio.cpp

@@ -189,11 +189,11 @@ FrameBase* DecodeVedio::getOneImage()
         return nullptr;
     }
     // FrameBase* frame = nullptr;
-    // if(!m_queueFrame.front_pop_NoBlock(frame))
+    // if(!m_queueFrame.front_pop_noBlock(frame))
     // {
     //     return nullptr;
     // }
-    return m_queueFrame.front_pop_NoBlock();
+    return m_queueFrame.front_pop_noBlock();
 }
 
 /**
@@ -216,7 +216,7 @@ FrameBase* DecodeVedio::getOneImageUntilHave(int timeOut)
     FrameBase* frame = nullptr;
     for(int i = 0; i < timeOut; i++)
     {
-        if(m_queueFrame.front_pop_NoBlock(frame))
+        if(m_queueFrame.front_pop_noBlock(frame))
         {
             return frame;
         }
@@ -248,7 +248,7 @@ void DecodeVedio::clearQueueFrame()
     while(m_queueFrame.QueueSize() > 0)
     {
         FrameBase* frame = nullptr;
-        m_queueFrame.front_pop_NoBlock(frame);
+        m_queueFrame.front_pop_noBlock(frame);
         deleteOneFrame(frame);
     }
     
@@ -259,7 +259,7 @@ void DecodeVedio::deleteOneImage()
 {
     if(m_queueFrame.QueueSize() > 0)
     {
-        auto frame = m_queueFrame.front_pop_NoBlock();
+        auto frame = m_queueFrame.front_pop_noBlock();
         deleteOneFrame(frame);
     }
 }

+ 0 - 0
demo/OpenGLWidgetTest/VideoPlayer/DecodeVedio.h → demo/VideoPlayerLibrary/VideoPlayer/DecodeVedio.h


+ 0 - 0
demo/OpenGLWidgetTest/VideoPlayer/FrameFormat.cpp → demo/VideoPlayerLibrary/VideoPlayer/FrameFormat.cpp


+ 0 - 0
demo/OpenGLWidgetTest/VideoPlayer/FrameFormat.h → demo/VideoPlayerLibrary/VideoPlayer/FrameFormat.h


+ 3 - 0
demo/VideoPlayerLibrary/VideoPlayer/IVideoPlayer.cpp

@@ -0,0 +1,3 @@
+#include "IVideoPlayer.h"
+
+

+ 54 - 0
demo/VideoPlayerLibrary/VideoPlayer/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_ */

+ 20 - 3
demo/OpenGLWidgetTest/VideoPlayer/VideoPlayer.cpp → demo/VideoPlayerLibrary/VideoPlayer/VideoPlayer.cpp

@@ -13,7 +13,7 @@
 #include "spdlog/spdlog.h"
 
 
-VideoPlayer::VideoPlayer(QObject *parent) : QObject(parent)
+VideoPlayer::VideoPlayer()
 {
     // /* 初始化解码线程 */
     // m_threadDecode = new QThread(this);
@@ -385,14 +385,14 @@ void VideoPlayer::setPlayWidgetSize(int width,int height)
  *  @arg true:独占widget,并设置一个layout,会随着传入的widget大小变化
  *  @arg false:不独占
  */
-void VideoPlayer::setWidgetParent(QWidget* widget, bool flag)
+void VideoPlayer::setWidgetParent(QWidget* widget, bool isFull)
 {
     if(widget == nullptr)
     {
         SPDLOG_WARN("传入的widget为空");
         return;
     }
-    if(flag)
+    if(isFull)
     {
         /* 设置布局 */
         QVBoxLayout* layout = new QVBoxLayout(widget);
@@ -442,6 +442,22 @@ void VideoPlayer::setFPS(int fps)
     }
 }
 
+/* 设置播放速度 */
+void VideoPlayer::setPlaySpeed(float speed)
+{
+    int fps = m_fps * speed;
+    if(fps <= 0)
+    {
+        fps = m_fps;  // 最小帧率为1
+    }
+    if(m_timerRefreshUI.isActive())
+    {
+        m_timerRefreshUI.stop();
+        m_interval = qRound64(1000.0 / fps);
+        m_timerRefreshUI.start(m_interval);
+    }
+}
+
 
 /* 设置播放回调函数 */
 // void VideoPlayer::setPlayCallBack(std::function<Play_CallBack> playCallBack,void* context)
@@ -643,6 +659,7 @@ void VideoPlayer::do_playCompleted()
     //     /* 播放完成的回调函数 */
     //     m_funcPlayCB(this, 2, nullptr, 0, m_context);
     // }
+    emit signal_playCompleted();  // 播放完成信号
 }
 
 /* 判断是否是本地文件 */

+ 41 - 26
demo/OpenGLWidgetTest/VideoPlayer/VideoPlayer.h → demo/VideoPlayerLibrary/VideoPlayer/VideoPlayer.h

@@ -1,8 +1,9 @@
 #ifndef VideoPlayer_H
 #define VideoPlayer_H
 
+#include "IVideoPlayer.h"
 #include "FrameFormat.h"
-#include <QObject>
+// #include <QObject>
 #include <QThread>
 #include <QTimer>
 #include <QSemaphore>
@@ -10,44 +11,58 @@
 class DecodeVedio;
 class QWidget;
 
-class VideoPlayer : public QObject
+class VideoPlayer : public IVideoPlayer
 {
     Q_OBJECT
 public:
-    explicit VideoPlayer(QObject *parent = nullptr);
-    ~VideoPlayer();
-
-    bool openPlayVedio(const QString& fileName);    /* 打开播放视频 */
-    bool play();                                    /* 播放视频 */
-    void pause();                                   /* 暂停播放 */
-    void stop();                                    /* 停止播放 */
-    void backward(qint64 ms);                       /* 后退,单位ms */
-    void forward(qint64 ms);                        /* 前进,单位ms */
-
-    bool getPlayStatus() { return m_playStatus; }   /* 获取播放状态 */
-    qint64 getDuration();                           /* 获取视频时长 */
-    qint64 getCurrentPos();                         /* 获取当前播放位置 */
-    void setCurrentPos(qint64 pos);                 /* 设置当前播放位置 */
-
-    void setPlayWidgetSize(int width,int height);   /* 设置播放视频窗口的大小 */
-    void setWidgetParent(QWidget* widget, bool flag = false); /* 设置播放窗口 */
-    void setPreviewImage(int num = 2);              /* 设置预览图片数目,在暂停时跳转,可能会有花屏或者黑帧,可以设置跳转图片个数跳过黑帧 */
-    void setFPS(int fps);                            /* 设置帧率,用于控制播放速度 */
+    explicit VideoPlayer();
+    ~VideoPlayer() override;
+
+    /* 打开播放视频 */
+    bool openPlayVedio(const QString& fileName) override;
+    /* 播放视频 */
+    bool play() override;
+    /* 暂停播放 */
+    void pause() override;
+    /* 停止播放 */
+    void stop() override;
+    /* 后退,单位ms */
+    void backward(qint64 ms) override;
+    /* 前进,单位ms */
+    void forward(qint64 ms) override;
+
+    /* 获取播放状态 */
+    bool getPlayStatus() override { return m_playStatus; }
+    /* 获取视频时长 */
+    qint64 getDuration() override;
+    /* 获取当前播放位置 */
+    qint64 getCurrentPos() override;
+    /* 设置当前播放位置 */
+    void setCurrentPos(qint64 pos) override;
+
+    /* 设置播放视频窗口的大小 */
+    void setPlayWidgetSize(int width,int height) override;
+    /* 设置播放窗口 */
+    void setWidgetParent(QWidget* widget, bool isFull = false)  override;
+    /* 获取播放窗口的指针 */
+    QWidget* getPlayWidget() const override { return m_playWidget; }
+    /* 设置预览图片数目,在暂停时跳转,可能会有花屏或者黑帧,可以设置跳转图片个数跳过黑帧 */
+    void setPreviewImage(int num = 2) override;
+    /* 设置帧率,用于控制播放速度 */
+    void setFPS(int fps);
+    /* 设置播放速度 */
+    void setPlaySpeed(float speed) override;
 
     // void setPlayCallBack(std::function<Play_CallBack> playCallBack,void* context);  /* 设置播放回调函数 */
 signals:
-    void signal_playCompleted();                    /* 播放完成信号 */
+    // void signal_playCompleted();                    /* 播放完成信号 */
     void signal_refreshImage();                     /* 刷新图片信号 */
 
 protected:
-    // void paintEvent(QPaintEvent *event) override;
-    // void resizeEvent(QResizeEvent *event) override;
     /* 刷新一张图片,直到有图片为止 */
     void refreshOneUIUntilHave();
     /* 刷新一帧 */
     inline void refreshFrame(FrameBase* frame);
-    /* 双击事件函数 */
-    // void mouseDoubleClickEvent(QMouseEvent *event) override;
 
 private slots:
     void do_refreshUI();                            /* 取出画面,刷新UI */

+ 323 - 0
demo/VideoPlayerLibrary/VideoPlayerAPI/VideoPlayerAPI.cpp

@@ -0,0 +1,323 @@
+#include "VideoPlayerAPI.h"
+
+#include "spdlog/spdlog.h"
+
+
+/* 创建一个播放器 */
+Q_DECL_EXPORT QObject* createPlayer()
+{
+    return new VideoPlayer();
+}
+/* 销毁一个播放器 */
+Q_DECL_EXPORT void destroyPlayer(QObject* player)
+{
+    if(player != nullptr)
+    {
+        VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+        if(videoPlayer != nullptr)
+        {
+            delete videoPlayer;
+            videoPlayer = nullptr;
+            player = nullptr;  // 确保指针不再指向已删除的对象
+        }
+    } else
+    {
+        SPDLOG_WARN("destroyVideoPlayer: 传入的player为空指针");
+    }
+}
+
+/* 打开视频 */
+Q_DECL_EXPORT bool OpenVideo(QObject* player, const QString& fileName)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("OpenVideo: 传入的player为空指针");
+        return false;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("OpenVideo: 无法将player转换为VideoPlayer");
+        return false;
+    }
+
+    return videoPlayer->openPlayVedio(fileName);
+}
+
+/* 播放视频 */
+Q_DECL_EXPORT bool play(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("play: 传入的player为空指针");
+        return false;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("play: 无法将player转换为VideoPlayer");
+        return false;
+    }
+
+    return videoPlayer->play();
+}
+
+/* 暂停播放 */
+Q_DECL_EXPORT void pause(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("pause: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("pause: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->pause();
+}
+
+/* 停止播放 */
+Q_DECL_EXPORT void stop(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("stop: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("stop: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->stop();
+}
+
+/* 后退,单位ms */
+Q_DECL_EXPORT void backward(QObject* player, qint64 ms)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("backward: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("backward: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->backward(ms);
+}
+
+/* 前进,单位ms */
+Q_DECL_EXPORT void forward(QObject* player, qint64 ms)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("forward: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("forward: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->forward(ms);
+}
+
+/* 获取播放状态 */
+Q_DECL_EXPORT bool getPlayStatus(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("getPlayStatus: 传入的player为空指针");
+        return false;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("getPlayStatus: 无法将player转换为VideoPlayer");
+        return false;
+    }
+
+    return videoPlayer->getPlayStatus();
+}
+
+/* 获取视频时长 */
+Q_DECL_EXPORT qint64 getDuration(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("getDuration: 传入的player为空指针");
+        return -1;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("getDuration: 无法将player转换为VideoPlayer");
+        return -1;
+    }
+
+    return videoPlayer->getDuration();
+}
+
+/* 获取当前播放位置 */
+Q_DECL_EXPORT qint64 getCurrentPos(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("getCurrentPos: 传入的player为空指针");
+        return -1;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("getCurrentPos: 无法将player转换为VideoPlayer");
+        return -1;
+    }
+
+    return videoPlayer->getCurrentPos();
+}
+
+/* 设置当前播放位置 */
+Q_DECL_EXPORT void setCurrentPos(QObject* player, qint64 pos)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("setCurrentPos: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("setCurrentPos: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->setCurrentPos(pos);
+}
+
+/* 设置播放视频窗口的大小 */
+Q_DECL_EXPORT void setPlayWidgetSize(QObject* player, int width,int height)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("setPlayWidgetSize: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("setPlayWidgetSize: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->setPlayWidgetSize(width, height);
+}
+
+/* 设置播放窗口 */
+Q_DECL_EXPORT void setWidgetParent(QObject* player, QWidget* widget, bool isFull)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("setWidgetParent: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("setWidgetParent: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->setWidgetParent(widget, isFull);
+}
+
+/* 获取播放窗口的指针 */
+Q_DECL_EXPORT QWidget* getPlayWidget(QObject* player)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("getPlayWidget: 传入的player为空指针");
+        return nullptr;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("getPlayWidget: 无法将player转换为VideoPlayer");
+        return nullptr;
+    }
+
+    return videoPlayer->getPlayWidget();
+}
+
+
+/* 设置预览图片数目,在暂停时跳转,可能会有花屏或者黑帧,可以设置跳转图片个数跳过黑帧 */
+Q_DECL_EXPORT void setPreviewImage(QObject* player, int num)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("setPreviewImage: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("setPreviewImage: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->setPreviewImage(num);
+}
+
+/* 设置播放速度 */
+Q_DECL_EXPORT void setPlaySpeed(QObject* player, float speed)
+{
+    if(player == nullptr)
+    {
+        SPDLOG_ERROR("setPlaySpeed: 传入的player为空指针");
+        return;
+    }
+    VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+    if(videoPlayer == nullptr)
+    {
+        SPDLOG_ERROR("setPlaySpeed: 无法将player转换为VideoPlayer");
+        return;
+    }
+
+    videoPlayer->setPlaySpeed(speed);
+}
+
+
+/* 创建一个IVideoPlayer */
+Q_DECL_EXPORT IVideoPlayer* createVideoPlayer()
+{
+    return new VideoPlayer();
+}
+
+/* 销毁一个IVideoPlayer */
+Q_DECL_EXPORT void destroyVideoPlayer(IVideoPlayer* player)
+{
+    if(player != nullptr)
+    {
+        VideoPlayer* videoPlayer = qobject_cast<VideoPlayer*>(player);
+        if(videoPlayer != nullptr)
+        {
+            delete videoPlayer;
+            videoPlayer = nullptr;
+            player = nullptr;  // 确保指针不再指向已删除的对象
+        }
+    } else
+    {
+        SPDLOG_WARN("destroyVideoPlayer: 传入的player为空指针");
+    }
+}

+ 62 - 0
demo/VideoPlayerLibrary/VideoPlayerAPI/VideoPlayerAPI.h

@@ -0,0 +1,62 @@
+#ifndef _VIDEOPLAYERAPI_H_
+#define _VIDEOPLAYERAPI_H_
+
+#include "IVideoPlayer.h"
+#include "VideoPlayer.h"
+#include <QString>
+#include <qobject.h>
+
+class QWidget;
+
+extern "C" {
+
+/* 创建一个播放器 */
+Q_DECL_EXPORT QObject* createPlayer();
+/* 销毁一个播放器 */
+Q_DECL_EXPORT void destroyPlayer(QObject* player);
+
+/* 打开视频 */
+Q_DECL_EXPORT bool OpenVideo(QObject* player, const QString& fileName);
+/* 播放视频 */
+Q_DECL_EXPORT bool play(QObject* player);
+/* 暂停播放 */
+Q_DECL_EXPORT void pause(QObject* player);
+/* 停止播放 */
+Q_DECL_EXPORT void stop(QObject* player);
+/* 后退,单位ms */
+Q_DECL_EXPORT void backward(QObject* player, qint64 ms);
+/* 前进,单位ms */
+Q_DECL_EXPORT void forward(QObject* player, qint64 ms);
+
+/* 获取播放状态 */
+Q_DECL_EXPORT bool getPlayStatus(QObject* player);
+/* 获取视频时长 */
+Q_DECL_EXPORT qint64 getDuration(QObject* player);
+/* 获取当前播放位置 */
+Q_DECL_EXPORT qint64 getCurrentPos(QObject* player);
+/* 设置当前播放位置 */
+Q_DECL_EXPORT void setCurrentPos(QObject* player, qint64 pos);
+
+/* 设置播放视频窗口的大小 */
+Q_DECL_EXPORT void setPlayWidgetSize(QObject* player, int width,int height);
+/* 设置播放窗口 */
+Q_DECL_EXPORT void setWidgetParent(QObject* player, QWidget* widget, bool isFull);
+/* 获取播放窗口的指针 */
+Q_DECL_EXPORT QWidget* getPlayWidget(QObject* player);
+
+/* 设置预览图片数目,在暂停时跳转,可能会有花屏或者黑帧,可以设置跳转图片个数跳过黑帧 */
+Q_DECL_EXPORT void setPreviewImage(QObject* player, int num = 2);
+/* 设置播放速度 */
+Q_DECL_EXPORT void setPlaySpeed(QObject* player, float speed);
+
+
+/* 创建一个IVideoPlayer */
+Q_DECL_EXPORT IVideoPlayer* createVideoPlayer();
+/* 销毁一个IVideoPlayer */
+Q_DECL_EXPORT void destroyVideoPlayer(IVideoPlayer* player);
+
+};
+
+
+
+#endif /* _VIDEOPLAYERAPI_H_ */