QT6 QML GStreamer (Windows+Android)显示RTSP视频流

06-01 1459阅读

        本文章介绍了Qt6.5完成了QT6.5使用第三方视频库GStreamer拉流显示的Demo程序,软件架构采用QML前端显示C++后端数据处理,目前程序在Windows与Android平台已验证成功。

        GStreamer采用官方预编译的库,库版本一定要选正确,一定要与本机的编译工具链版本匹配,否则会报出各种错误!

一、Windows GST安装

  1. Download GStreamer。
  2. 这里我选择Windows平台mingw编译版本,版本号为1.20.7,架构选择x86_64,同时下载Develop与Runtime版本msi,如下图。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

  3. 两个msi下载完成之后全部双击安装,选择Typical经典安装,默认安装在D:/gstreamer路径。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

  4. 安装工具默认已经默认将环境变量加到系统变量里。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

  5. 将GSTREAMER_1_0_ROOT_MINGW_X86_64变量加到Path里面。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

二、Android GST安装

  1. Download GStreamer。
  2. 这里直接下载即可。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

  3. 压缩包内包含安卓四个平台架构的库,解压后如下图。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

  4. 将对应架构的文件夹添加到项目工程目录下(当然也可以将该目录添加到系统环境变量里)。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

三、Qt编译器配置

  • Qt 6.5.3 CMake编译
  • Windows编译器信息如下图。

    QT6 QML GStreamer (Windows+Android)显示RTSP视频流

    • Anroid编译器信息如下,我这里android sdk api版本为33。

      QT6 QML GStreamer (Windows+Android)显示RTSP视频流

      四、代码实现

      1、创建QT Quick工程,在CMakeLists.txt加载GST库,并创建VideoStreamer类源与头文件用来拉取rtsp视频流。

      cmake_minimum_required(VERSION 3.16)
      project(GSteamerQtDemo VERSION 0.1 LANGUAGES CXX)
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      set(CMAKE_CXX_STANDARD 17)
      find_package(Qt6 6.5 REQUIRED COMPONENTS Quick Multimedia)
      qt_standard_project_setup(REQUIRES 6.5)
      set(CMAKE_AUTORCC ON)
      qt_add_executable(appGSteamerQtDemo
          main.cpp
          videostreamer.h videostreamer.cpp
      )
      qt_add_qml_module(appGSteamerQtDemo
          URI GSteamerQtDemo
          VERSION 1.0
          QML_FILES
          Main.qml
      )
      # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
      # If you are developing for iOS or macOS you should consider setting an
      # explicit, fixed bundle identifier manually though.
      set_target_properties(appGSteamerQtDemo PROPERTIES
          #    MACOSX_BUNDLE_GUI_IDENTIFIER com.example.appGSteamerQtDemo
          MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
          MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
          MACOSX_BUNDLE TRUE
          WIN32_EXECUTABLE TRUE
      )
      target_link_libraries(appGSteamerQtDemo
          PRIVATE Qt6::Quick
          PRIVATE Qt6::Multimedia
      )
      # 设置Android打包源目录
      set_property(TARGET appGSteamerQtDemo APPEND PROPERTY
          QT_ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android"
      )
      include(GNUInstallDirs)
      install(TARGETS appGSteamerQtDemo
          BUNDLE DESTINATION .
          LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
          RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
      )
      # GStreamer配置
      if(ANDROID) # ANDROID
          # 设置Android的GStreamer路径
          set(GSTREAMER_ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gstreamer/android/arm64)
          
          # 确保目录存在
          if(NOT EXISTS "${GSTREAMER_ANDROID_DIR}")
              message(FATAL_ERROR "GStreamer Android 目录不存在: ${GSTREAMER_ANDROID_DIR}")
          endif()
          
          # 检查GStreamer版本兼容性
          message(STATUS "Android sdk version is 33 and ndk version is 25.1.8937393, please ensure GStreamer version is 1.20.7")
          # 解决ffmpeg库汇编参数-fPIC报错问题
          # 因为三方库中存在汇编编译的部分,所以需要修改CFLAGS参考如下,符号不可抢占且优先使用本地符号
          set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-int-conversion -Wl,-Bsymbolic")
          set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-int-conversion -Wl,-Bsymbolic")
          # GStreamer头文件路径
          include_directories(${GSTREAMER_ANDROID_DIR}/include)
          include_directories(${GSTREAMER_ANDROID_DIR}/include/glib-2.0)
          include_directories(${GSTREAMER_ANDROID_DIR}/include/gstreamer-1.0)
          include_directories(${GSTREAMER_ANDROID_DIR}/include/gstreamer-1.0/gst)
          include_directories(${GSTREAMER_ANDROID_DIR}/lib/glib-2.0/include)
          # GStreamer库文件
          target_link_libraries(appGSteamerQtDemo
              PRIVATE
              "${GSTREAMER_ANDROID_DIR}/lib/libgstreamer-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgobject-2.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libglib-2.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgmodule-2.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgio-2.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgthread-2.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libintl.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libiconv.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libffi.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstapp-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstvideo-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstbase-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/liborc-0.4.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstrtsp-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstsdp-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstrtp-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstnet-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstcodecparsers-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgsttag-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstaudio-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstpbutils-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libz.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstvideo-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstgl-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgraphene-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libjpeg.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libpng16.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstcontroller-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libgstphotography-1.0.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libopenh264.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libavcodec.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libavfilter.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libavformat.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libavutil.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libswresample.a"
              "${GSTREAMER_ANDROID_DIR}/lib/libbz2.a"
              # 插件库
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstcoreelements.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstrtsp.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstrtp.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstrtpmanager.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstvideoparsersbad.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstplayback.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstapp.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstvideoconvert.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstaudioconvert.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstaudioresample.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstvideotestsrc.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstandroidmedia.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstopengl.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstopenh264.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstjpeg.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstpng.a"
              "${GSTREAMER_ANDROID_DIR}/lib/gstreamer-1.0/libgstlibav.a"
              
              # Android特定库
              -lEGL
              -lGLESv2
              -landroid
          )
          
          # 添加编译定义
          target_compile_definitions(appGSteamerQtDemo
              PRIVATE
              GST_STATIC_COMPILATION
              GST_DISABLE_GST_DEBUG
          )
          
      elseif(MINGW) # MINGW
          # 尝试从环境变量获取 GStreamer 路径
          if(DEFINED ENV{GSTREAMER_1_0_ROOT_MINGW_X86_64})
              set(GSTREAMER_ROOT_DIR $ENV{GSTREAMER_1_0_ROOT_MINGW_X86_64})
              message(STATUS "use ENV GSTREAMER_1_0_ROOT_MINGW_X86_64: ${GSTREAMER_ROOT_DIR}")
          else()
              # 尝试常见的安装路径
              set(GSTREAMER_ROOT_DIR "D:/Program Files/gstreamer/1.0/mingw_x86_64")
              message(WARNING "not found GSTREAMER_1_0_ROOT_MINGW_X86_64 ENV, use default: ${GSTREAMER_ROOT_DIR}")
          endif()
          # 验证路径是否存在
          if(NOT EXISTS "${GSTREAMER_ROOT_DIR}")
              message(FATAL_ERROR "GStreamer is not existed: ${GSTREAMER_ROOT_DIR}")
          endif()
          # 检查GStreamer版本兼容性
          message(STATUS "Qt MinGW version is GCC 11.2.0, please ensure GStreamer version is 1.20.7")
          # GStreamer头文件路径
          include_directories("${GSTREAMER_ROOT_DIR}/include")
          include_directories("${GSTREAMER_ROOT_DIR}/include/glib-2.0")
          include_directories("${GSTREAMER_ROOT_DIR}/include/gstreamer-1.0")
          include_directories("${GSTREAMER_ROOT_DIR}/include/gstreamer-1.0/gst")
          include_directories("${GSTREAMER_ROOT_DIR}/lib/glib-2.0/include")
          # GStreamer库文件
          target_link_libraries(appGSteamerQtDemo
              PRIVATE
              "${GSTREAMER_ROOT_DIR}/lib/gstreamer-1.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gobject-2.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/glib-2.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gmodule-2.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gio-2.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gthread-2.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/intl.lib"
              "${GSTREAMER_ROOT_DIR}/lib/iconv.lib"
              "${GSTREAMER_ROOT_DIR}/lib/ffi.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gstapp-1.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gstvideo-1.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/gstbase-1.0.lib"
              "${GSTREAMER_ROOT_DIR}/lib/orc-0.4.lib"
          )
      endif()
      

      2、AndroidManifest.xml配置安卓包参数。

      
          
          
          
          
          
          
          
          
          
              
                  
                      
                      
                  
                  
                  
                  
              
          
      
      

      3、videostreamer.h文件实现,使用QVideoSink作为视频流接收器。

      #ifndef VIDEOSTREAMER_H
      #define VIDEOSTREAMER_H
      #include 
      #include 
      #include 
      #include 
      #include 
      #include 
      class VideoStreamer : public QObject
      {
          Q_OBJECT
       public:
          explicit VideoStreamer(QObject* parent = nullptr);
          ~VideoStreamer();
          Q_INVOKABLE void setVideoSink(QVideoSink* sink);
          Q_INVOKABLE void start(const QString& rtspUrl);
          Q_INVOKABLE void stop();
       private:
          GstElement* pipeline = nullptr;
          QVideoSink* m_sink = nullptr;
          static GstFlowReturn onNewSample(GstElement* sink, VideoStreamer* self);
          static void          busCallback(GstBus* bus, GstMessage* message, VideoStreamer* self);
      };
      class GlibMainLoopThread : public QThread
      {
       public:
          void run() override
          {
              GMainLoop* loop = g_main_loop_new(nullptr, FALSE);
              g_main_loop_run(loop);
              g_main_loop_unref(loop);
          }
      };
      #endif // VIDEOSTREAMER_H
      

      4、videostreamer.cpp文件实现,调用start方法开启管道,成功连接url后,自动调用onNewSample回调函数拉取视频流,在该函数内将视频帧QVideoFrame通过QVideoSink的setVideoFrame方法传给qml前端,qml内的VideoOutput组件再将该视频帧进行视频渲染显示。

      #include "videostreamer.h"
      #include 
      #include 
      #include 
      #include 
      #include 
      #include 
      // 帮助打印GStreamer管道结构的辅助类
      class GstPrint
      {
       public:
          GstPrint() : indent(0) {}
          void printElement(GstElement* element, int depth)
          {
              indent = depth;
              printIndent();
              qDebug() 
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码