本篇博客在上一篇ubuntu GStreamer + QT多媒体播放器开发(一)的基础上主要修改新增以下几点:
(1)使用gstreamer播放控制的部分封装成mmpalyer lib,对外的接口以及一些结构体和枚举定义单独抽离到mediaplayer.h头文件中;
(2)使用QT调用mmpalyer lib提供的接口实现播放,视频在QT窗口中进行渲染;
(3)增加playbin3 的element-added signal 监听,方便查看playbin3在自动创建pipeline时增加了那些element;
(4)mmpalyer lib初始化player完成后通过callback 返回给UI(QT)需要的参数,如pipeline地址,player id等。
以下对新增的部分简单进行说明。

1 封装mmpalyer lib

mmpalyer lib预期对外开放以下6个接口,供UI调用,实现player init、play、resume、pause等基本操作,目前只实现了init 、play、stop三个接口。

int MMPlayerInit(ST_INIT_PARAM *pstInitParam);
int MMPlayerPlay(HANDLE_ID hanldeId);
int MMPlayerStop(HANDLE_ID hanldeId);
int MMPlayerPause(HANDLE_ID hanldeId);
int MMPlayerResume(HANDLE_ID hanldeId);
int MMPlayerGetPostion(HANDLE_ID hanldeId);

play初始化时传入的是ST_INIT_PARAM结构体指针,主要向mmpalyer传递播放文件路径和初始化完成后的CALL_BACK_FUNCTION。

typedef struct _ST_INIT_PARAM {gint handleId;char *path;CALL_BACK_FUNCTION callBackFunction;
} ST_INIT_PARAM;

call back function传递的参数一个是CALL_BACK_EVENT_TYPE,另一个是void的类型指针,可以传递一些需要数据给UI。

/*call back function*/
typedef void (*CALL_BACK_FUNCTION)(CALL_BACK_EVENT_TYPE eventType, void *param);

CALL_BACK_EVENT_TYPE主要定义了一些关键的event,如init ok、play ok等,后期会扩充。

typedef enum {PLAYER_INIT_OK = 0,         CHANGE_TO_PALYING_OK,CHANGE_TO_PUASED_OK, PALY_ERROR = 20,
} CALL_BACK_EVENT_TYPE;

2 视频在QT窗口中渲染

实现的QT窗口中播放视频的关键代码如下:

    //play mm in QT windowPlayerWindow *window = new PlayerWindow(userHandle.pipeline);window->setWindowTitle("Qt&&GStreamer Player demo");window->resize(900, 600);xwinid = window->getVideoWId();//wait playsink addedwhile (NULL == userHandle.videoSink){userHandle.videoSink = gst_bin_get_by_name (GST_BIN (userHandle.pipeline), "playsink");maxWaitCount++;if (maxWaitCount > 20){g_printerr ("can not find video sink.\n", initParam.path);goto stop;}sleep(100);}gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY(userHandle.videoSink), xwinid);

创建一个基类为QWidget的PlayerWindow类,main函数中实例化window,并获window id。

WId PlayerWindow::getVideoWId(){return videoWindow->winId();
}

获取pipeline中的videosink:

userHandle.videoSink = gst_bin_get_by_name (GST_BIN (userHandle.pipeline), "playsink");

调用gst_video_overlay_set_window_handle将视频祯在QT窗口中渲染,传入的两个参数一个是
videosink,另一个时窗口Id。

 gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY(userHandle.videoSink), xwinid);

GstVideoOverlay的详细用法可以参考:GstVideoOverlay。

3 playbin3 的element-added signal 监听

上篇博客里说过,playbin3是是gstreamer的一个高级plugin,可以根据播放的文件自动在pipeline创建时添加需要的elemet和plugin,新element添加进来时会发出element-added signal,监听这个signal就可以知道有哪些element被添加进来了。

g_signal_connect(G_OBJECT(mediaHandle->pipeline), "element-added",  G_CALLBACK(handle_element_added), mediaHandle);

监听的时候需要定义一个callback function,element-added signal发出后会回调这个函数,回调函数定义如下。

//Will be emitted after the element was added to the bin.
void user_function (GstBin     *bin,GstElement *element,gpointer    user_data)Parameters :
bin:the GstBin
element:the GstElement that was added to the bin
user_data:user data set when the signal handler was connected.

前两个参数是固定的,最后一个参数是指针类型,可以传递自定义数据,这里传递了一个mediaHandle结构体指针,handle_element_added函数实现如下,目前只打印了一下element name,有需要可以在这里给element 设置属性。


void handle_element_added(GstBin *bin, GstElement *element, ST_MEDIA_HANDLE *mediaHandle)
{//Q_UNUSED(bin);gchar *elementName = gst_element_get_name(element);g_print("elementName %s. \n", elementName);if (g_str_has_prefix(elementName, "video-sink")) {g_print("find video-sink in element_add function. \n");} else if (g_str_has_prefix(elementName, "ximagesink")) {g_print("find ximagesink in element_add function. \n");} else if (g_str_has_prefix(elementName, "uridecodebin3") || g_str_has_prefix(elementName, "decodebin2") || g_str_has_prefix(elementName, "urisourcebin0")) {g_signal_connect(element, "element-added",G_CALLBACK(handle_element_added), mediaHandle);}g_free(elementName);
}

4 初始化player完成后通过callback 返回给UI需要的参数

callback function在player init时通过init param传递给mmplayer lib:

mediaHandle->filePath = pstInitParam->path;
mediaHandle->hanlecallBackFn = pstInitParam->callBackFunction;

init 完成后调用callback function把player 信息结构体返回给UI(QT)。

    mediaHandle->handleInfo.handleId = (int)mediaHandle;mediaHandle->handleInfo.handleStatus = READY_STATUS;mediaHandle->handleInfo.pipeline = mediaHandle->pipeline;if (mediaHandle->hanlecallBackFn){(mediaHandle->hanlecallBackFn)(PLAYER_INIT_OK ,(void *)&mediaHandle->handleInfo);}

相关结构体定义:

/* handle status */
typedef enum {INIT_STATUS = 0,         READY_STATUS,PLAYING_STATUS,PAUSE_STATUS,ERROR_STATUS,
} HANDLE_STATUS;typedef struct _ST_HANDLE_INFO {gint handleId;HANDLE_STATUS handleStatus;GstElement *pipeline;
} ST_HANDLE_INFO;

callback function需要在QT中实现,为了方便后期的功能增加,callback function 中通过CALL_BACK_EVENT_TYPE来决定该如何处理返回的数据,目前只在PLAYER_INIT_OK后传递hanle id、pipeline 地址和player status给QT。

void hanleCallBackEvent(CALL_BACK_EVENT_TYPE eventType, void *param)
{g_print("recive event type (%d)\n", eventType);switch (eventType){case PLAYER_INIT_OK:{g_print("player init OK! \n");ST_HANDLE_INFO *retHanleInfo = (ST_HANDLE_INFO *)param;userHandle.handleId = retHanleInfo->handleId;userHandle.pipeline = retHanleInfo->pipeline;}break;default:break;}
}

5 最终效果以及github地址

最终播放效果如下,QT上的按钮功能暂未实现。

最后附上github地址:https://github.com/zhenghaiyang123/gst_player.git,该篇博客对应tag v0.2。

ubuntu GStreamer + QT多媒体播放器开发(二)相关推荐

  1. 04 Qt音视频多媒体播放器开发,Qt6.2.3 multimedia

    Q6.2.3 multimedia 音视频多媒体播放器开发 步骤: Qt6.2版本中已经有了播放器的Demo,亲测可用.先下载Qt并安装Qt6.2.3,或者更新到Qt6.2.3,直接在欢迎页找到Med ...

  2. 采用QT进行OpenGL开发(二)绘制立方体

    在OpenGL中三维实体会被拆分成一个个小的平面图形来进行绘制.比如我们绘制的立方体,可以拆分成六个平面来进行绘制.这里我们以一个带纹理的正方体来说明一下三维实体的绘制方法. 绘制立方体 由于正方体的 ...

  3. Qt+MPlayer音乐播放器开发笔记(二):交叉编译MPlayer以及部署到开发板播放演示

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/119991329 长期持续带来更多项目与技术分享,咨询请 ...

  4. 基于QT开发的多媒体播放器

    基于QT开发的多媒体播放器 描述: 使用QT软件设计一个多媒体播放器,实现视频及音乐的播放,暂停,快进,快退,音量的调整. 歌词的实时显示和视频全屏播放等基本功能. 功能: 1.音乐系统:提供播放.暂 ...

  5. 【Qt+OpenCV项目开发学习】二、图片查看器应用程序开发

    一.前言 本博客将讲解如何用Qt+OpenCV开发一款图片查看器的Windows应用程序,其实不用OpenCV也能开发出这类软件,作者目的是为了学习Qt+OpenCV开发项目,所以会使用OpenCV, ...

  6. PX4-AutoPilot教程-0-使用VMware虚拟机安装Ubuntu系统并搭建PX4开发环境(ROS+mavros+jMAVSim+gazebo+QGC+QT)

    使用VMware虚拟机安装Ubuntu系统并搭建PX4开发环境 本教程使用VMware虚拟机安装Ubuntu18.04系统(官方推荐使用版本),搭建PX4固件版本为v1.9.2,飞控板为pixhawk ...

  7. Ubuntu 安装 Qt 开发环境 简单实现

    2019独角兽企业重金招聘Python工程师标准>>> Ubuntu 安装 Qt 开发环境 简单实现是本文要介绍的内容,内容很短,取其精华,详细介绍Qt 类库的说明,先来看内容. 一 ...

  8. Ubuntu 安装 Qt 开发环境(转)

    Ubuntu 安装 Qt 开发环境 简单实现是本文要介绍的内容,内容很短,取其精华,详细介绍Qt 类库的说明,先来看内容. (转http://mobile.51cto.com/symbian-2718 ...

  9. 案例分享:Qt激光加工焊接设备信息化软件研发(西门子PLC,mysql数据库,用户权限控制,界面设计,参数定制,播放器,二维图,期限控制,参数调试等)

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127669684 长期持续项目技术分享,有专业Qt需求请 ...

  10. 案例分享:Qt工程机械真空激光焊接系统软件产品定制(西门子PLC,mysql数据库,用户权限控制,界面配置,参数定制,播放器,二维图标,rgv小车,期限控制,参数调试等)

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/127214512 长期持续项目技术分享,有需求请回博客首 ...

最新文章

  1. Centos+PHP模块+exif扩展 (第三方模块)
  2. 分布式数据库clickhouse、tidb、palo对比
  3. 在CentOS 6安装Mysql问题
  4. systemverilog编译介绍
  5. 55个高质量的Magento主题,助你构建电子商务站点
  6. 继承(父类为虚方法以及子类的重写)
  7. PHP file_get_contents(‘php://input‘) 和POST的区别
  8. 三菱5uplc伺服电机指令_实例 | PLC触摸屏控制伺服电机程序设计
  9. 百度文库解决复制问题
  10. 夜深人静, 看看编程人生
  11. pca降维算法java_PCA降维算法
  12. java 连接池配置_【Java】java数据库连接池配置的几种方法
  13. 会员管理系统实战开发教程(三)-充值记录功能
  14. javascript超空间(removeChild和innerHTML区别)
  15. 计算机键盘可以分为哪几个区,键盘分为哪几个区?分别是什么?
  16. 电子学报、计算机研究与发展中文期刊投稿过程记录
  17. org.eclipse.wst.validation has been removed
  18. Centos7 下Scrapy安装过程
  19. 三维扫描在建筑行业应用综述
  20. tensorflow的优势

热门文章

  1. NOSql数据库的优缺点分析
  2. ubuntu18.04+opencv3.4.10+opencv3.4.10contrib+LSD使用
  3. oppo小布机器人_OPPO小布助手建立GUI+VUI协作机制,创新快应用融合能力
  4. 天天向上答案python_天天向上的力量python(举一反三)
  5. Android 代码设置来电铃声
  6. java审批流创建及代码流程
  7. 运行jar文件,jar程序闪退,cmd命令行黑框一闪而过,无法启动jar文件
  8. 虚拟局域网VLAN,trunk的各种使用
  9. 电商等一些互联网项目涉及到什么技术?
  10. mkdir: Call From lzh/192.168.66.150 to localhost:9000 failed on connection exception: