Gstreamer 应用开发:1-基础介绍

article/2025/11/8 5:05:02

        我们之前的系列,正式的介绍了Gstreamer,并且围绕如何使用USB相机推流实现RTSP服务器来做了介绍,并在Jeston TX1 平台上做了优化急速的一些探索。

        今天我们开始围绕如何用命令实现一个音视频混合,或者单独的音频,和单独的视频文件如何实现播放,并逐步开始使用C语言程序来实现之前我们用命令行来实现的功能。

        在国内,在音视频领域接触最多实现的方案通常是通过ffmpeg(PC和sever端居多)或者硬件厂家的的SDK实现特定硬件的编解码功能(机顶盒,电视等嵌入式设备)。

        gstreamer跟ffmpeg一样,也是一个媒体框架,可以实现采集,编码,解码,渲染,滤镜等一条龙的媒体解决方案。 gstreamer基于glib实现,用C语言来实现面向对象思维,完全不是标准C++那一套逻辑,由于要跨平台,原生的系统API都是适配封装了一套,甚至自己实现队列,MAP,容器,协程,线程,异步操作,不熟悉glib 的API话,代码理解比较困难,用惯了C++,STL,boost,感觉得这是gstream最让人反感的一点,不合主流,搞的又要学一套API。 Gstreamer采用插件管理各个模块,软件框架比较复杂,采用了异步,协程编程模型,进一步增加了理解难度。

 

1、一个简单的视频播放示例

关于播放,我们先举例说明:我们首先有一个AVI的视频文件。

 

接下来我们播放这个视频。

gst-launch-1.0 filesrc location=/home/nvidia/Pictures/x-raw-640-480-25.avi ! avidemux ! videoconvert ! videoscale ! xvimagesink

 

接下来我们播放的过程中,叠加一个计时器看看:

gst-launch-1.0 filesrc location=/home/nvidia/Pictures/x-raw-640-480-25.avi ! avidemux ! videoconvert ! timeoverlay ! videoscale ! xvimagesink

 

计时显示,播放了20秒内容,这和录制时保持了一致。

#播放MPEG 视频保存成的 AVI文件
gst-launch-1.0 filesrc location=/home/nvidia/Pictures/jpeg_1280_720_30.avi ! avidemux ! jpegdec ! videoconvert ! timeoverlay ! videoscale ! xvimagesink#播放YUV2视频压缩成H.264的视频 保存成的AVI文件
gst-launch-1.0 filesrc location=/home/nvidia/Pictures/x264-video-640-480-30.avi ! avidemux \
! h264parse ! avdec_h264 \
! videoconvert ! timeoverlay ! videoscale ! xvimagesink

2、基础概念介绍

#播放音视频混录ogv文件
gst-launch-1.0 filesrc location=sintel_trailer-480p.ogv \
! oggdemux name=demux \
! queue ! vorbisdec ! autoaudiosink demux. \
! queue ! theoradec ! videoconvert ! xvimagesink
​通过上面的命令播放文件时,会创建如下pipeline:

元件(Elements)

        元件(element)是 GStreamer 中最重要的概念。你可以通过创建一系列的元件(Elements),并把它们连接起来,从而让数据流在这个被连接的各个元件(Elements)之间传输。每个元件(Elements)都有一个特殊的函数接口,对于有些元件(Elements)的函数接口它们是用于能够读取文件的数据,解码文件数据的。而有些元件(Elements)的函数接口只是输出相应的数据到具体的设备上(例如,声卡设备)。你可以将若干个元件(Elements)连接在一起,从而创建一个管道(pipeline)来完成一个特殊的任务,例如,媒体播放或者录音。GStreamer 已经默认安装了很多有用的元件(Elements),通过使用这些元件(Elements)你能够构建一个具有多种功能的应用程序。当然,如果你需要的话,你可以自己编写一个新的元件(Elements)。对于如何编写元件(Elements)的话题在 GStreamer Plugin Writer's Guide 中有详细的说明。

箱柜(Bins)和管道(pipelines)

        箱柜(Bins)是一个可以装载元件(element)的容器。管道(pipelines)是箱柜(Bins)的一个特殊的子类型,管道(pipelines)可以操作包含在它自身内部的所有元件(element)。因为箱柜(Bins)本身又是元件(element)的子集,所以你能够象操作普通元件(element)一样的操作一个箱柜(Bins), 通过这种方法可以降低你的应用程序的复杂度。你可以改变一个箱柜(Bins)的状态来改变箱柜(Bins)内部所有元件(element)的状态。箱柜(Bins)可以发送总线消息(bus messages)给它的 子集元件(element)(这些消息包括:错误消息(error messages),标签消息(tag messages),EOS 消息(EOS messages))。管道(pipeline)是高级的箱柜(Bins)。当你设定管道的暂停或者播放状态的时候,数据流将开始流动,并且媒体数据处理也开始处理。一旦开始,管道将在一个 单独的线程中运行,直到被停止或者数据流播放完毕。

衬垫(Pads)

        衬垫(Pads)在 GStreamer 中被用于多个元件的链接,从而让数据流能在这样的链接中流动。 一个衬垫(Pads)可以被看作是一个元件(element)插座或者端口,元件(element)之间的链接就是依靠着衬垫(Pads)。 衬垫(Pads)有处理特殊数据的能力:一个衬垫(Pads)能够限制数据流类型的通过。链接成功的条件是:只有在两个衬垫(Pads)允许通过的数据类型一致的时候才被建立。数据类型的设定使用了一个叫做 caps negotiation 的方法。数据类型被为一个 GstCaps 变量所描述。下面的这个比喻可能对你理解衬垫(Pads)有所帮助。一个衬垫(Pads)很象一个物理设备上的插头。例如一个家庭影院系统。一个家庭影院系统由一个功放(amplifier),一个 DVD 机,还有一个无声的视频投影组成。 我们需要连接 DVD 机到功放(amplifier),因为两个设备都有音频插口;我们还需要连接投影机到 DVD 机上,因为 两个设备都有视频处理插口。但我们很难将投影机与功放(amplifier)连接起来,因为他们之间处理的是不同的 插口。GStreamer 衬垫(Pads)的作用跟家庭影院系统中的插口是一样的。对于大部分情况,所有的数据流都是在链接好的元素之间流动。数据向元件(element)以外流出可以通过一个或者多个 source 衬垫(Pads),元件(element)接受数据是通过一个或者多个 sink 衬垫(Pads)来完成的。Source 元件(element)和 sink 元件(element)分别有且仅有一个 sink 衬垫(Pads)或者 source 衬垫(Pads)。数据在这里代表的是缓冲区(buffers) (GstBuffer对象描述了数据的缓冲区(buffers)的信息)和事件(events) (GstEvent 对象描述了数据的事件(events)信息)。

也有一种简单的介绍和理解。

        Pad是一个element的输入/输出接口,分为src pad(生产数据)和sink pad(消费数据)两种。两个element必须通过pad才能连接起来,pad拥有当前element能处理数据类型的能力(capabilities),会在连接时通过比较src pad和sink pad中所支持的能力,来选择最恰当的数据类型用于传输,如果element不支持,程序会直接退出。在element通过pad连接成功后,数据会从上一个element的src pad传到下一个element的sink pad然后进行处理。当element支持多种数据处理能力时,我们可以通过Cap来指定数据类型.

比如下面的命令:videotestsrc 会根据 "video/x-raw,width=1280,height=720"说明的格式和长宽高产生视频

gst-launch-1.0 videotestsrc ! "video/x-raw,width=1280,height=720" ! xvimagesink

 

#使用USB的YUY2数据格式通道,格式为! 'video/x-raw,format=YUY2,width=1280, height=720, framerate=5/1'
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=1 \
! 'video/x-raw,format=YUY2,width=1280, height=720, framerate=5/1' \
! jpegenc ! filesink location=/home/nvidia/Pictures/file_1280_720_YUV_1401.jpg
#使用USB的MPEG数据格式通道,格式为! ' image/jpeg,width=640,height=480,framerate=30/1'
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=1 \
! image/jpeg,width=640,height=480,framerate=30/1 ! \
filesink location=/home/nvidia/Pictures/file_jpeg_640_480_1417.jpg

在之前的介绍中,我们就有很多类似Cap来指定数据类型的使用。

gst-launch-1.0

        我们常用的gst-launch-1.0 其作用就是用于创建及执行一个Pipline,因此通常使用gst-launch先验证相关功能,然后再编写相应应用。 通过上面ogg视频播放的例子,我们已经看到,一个pipeline的多个element之间通过 “!" 分隔,同时可以设置element及Cap的属性。例如:播放音视频

gst-launch-1.0 playbin file:///home/root/test.mp4

3、信息交互

这一部分内容,我们主要是为后续的编程实现,准备一些基本的概念思路。

在pipeline运行的过程中,各个element以及应用之间不可避免的需要进行数据消息的传输,gstreamer提供了bus系统以及多种数据类型(Buffers、Events、Messages,Queries)来达到此目的:

 

Bus

        Bus是gstreamer内部用于将消息从内部不同的streaming线程,传递到bus线程,再由bus所在线程将消息发送到应用程序。应用程序只需要向bus注册消息处理函数,即可接收到pipline中各element所发出的消息,使用bus后,应用程序就不用关心消息是从哪一个线程发出的,避免了处理多个线程同时发出消息的复杂性。

Buffers

        用于从sources到sinks的媒体数据传输。

Events

        用于element之间或者应用到element之间的信息传递,比如播放时的seek操作是通过event实现的。

Messages

        是由element发出的消息,通过bus,以异步的方式被应用程序处理。通常用于传递errors, tags, state changes, buffering state, redirects等消息。消息处理是线程安全的。由于大部分消息是通过异步方式处理,所以会在应用程序里存在一点延迟,如果要及时的相应消息,需要在streaming线程捕获处理。

Queries

        用于应用程序向gstreamer查询总时间,当前时间,文件大小等信息。

gst-inspect-1.0

        查看gstreamer的plugin、element的信息。直接将plugin/element的类型作为参数,会列出其详细信息。如果不跟任何参数,会列出当前系统gstreamer所能查找到的所有插件。


http://chatgpt.dhexx.cn/article/7iTY1O2K.shtml

相关文章

【gstreamer】入门介绍

概述 GStreamer是一个基于流媒体的框架,是一个开放源代码的多媒体框架,用于创建音频和视频处理应用程序。它是一个运行在多个操作系统上的跨平台框架,支持多种不同的多媒体格式。 GStreamer框架的核心是基于插件的体系结构,插件…

Gstreamer基础讲解

Gstreamer讲解 文章目录 Gstreamer讲解基础背景小结 元件(Element)衬垫(Pads)Gstreamer的面向对象Gstreamer的多线程 实用工具Gstreamer常用插件介绍gstreamer工程记录关于YUV的补充知识 基础 背景 ​ 从历史的角度来看,Linux在多媒体方面已…

Gstreamer 简介

转载自:John.Leng - 博客园http://www.cnblogs.com/xleng/ 什么是Gstreamer? Gstreamer是一个支持Windows,Linux,Android, iOS的跨平台的多媒体框架,应用程序可以通过管道(Pipeline&#xff0…

微博视频怎么下载?微博视频下载和保存工具

本文转载自:怎么下载微博视频 ​​​微博视频怎么下载?当你刷微博看到自己特别喜欢的视频时,除了转发该视频到自己的微博外,你可能还想把这个微博视频保存到自己电脑或者手机中,那应该怎么实现weibo视频的下载呢&#…

GitHub 标星 120K+!这些神器仅需一行代码即可下载全网视频!

大家好,我是 JackTian。 今天这篇文章的内容对于经常浏览各大视频网站的同学来说,是一大神器工具。当你看到自己目前所需的视频时想尽各种办法保存至本地,方便后期再次回看。恰巧有些视频可能需要会员才能够下载,有些第三方的视频…

那些你可能不知道的视频下载奇技淫巧

之前已经写过好几篇的奇技淫巧系列了,今天说说怎么快速下载视频。 我平常经常看视频的网站就是爱奇艺,b站,微博,知乎,网易这些。 这里以微博为例,下载周杰伦的《晴天》,微博地址是 https://w…

部分主流视频网站下载方法

如果在微博或其他视频网站上看到非常喜欢的视频,想下载下来,但是又苦于不知如何下载。 这里我推荐一个网站,支持主流的86视频网站(发表博客时)的视频下载。 主流视频网站(16): 搜狐视频 乐视网 酷6网 56…

快手火山抖音视频怎么快速去重消重和去水印秒拍视频批量采集下载怎么快速去重消重去水印视频批量采...

快手火山抖音视频怎么快速去重消重和去水印 秒拍视频批量采集下载 怎么快速去重消重去水印 视频批量采集下载软件,怎么找到视频批量采集下载软件 趣头条今日头条等自媒体视频批量采集下载软件有哪些? 大鱼号视频批量采集下载去重消重去水印软件 视频怎么…

硕鼠——前些年很好用的视频下载神器

前言 首先解释一下为什么要说是前几年。因为它太好用,知道的人越来越多,导致引起了视频平台的注意,以版权为由禁止自己的视频从硕鼠下载。这里推荐小众软件Annie,在我的另一篇中有介绍,传送门。 官方网站 http://w…

网页保存视频最有效的几种方法

最近朋友问我了这样的问题: 如何才能把网络上的视频下载下来当做课堂资料播放呢? 的确,这个问题也困过我: 想要下载视频作为课件素材播放: 在微博收藏了许多有关「技能学习」的视频,但等到想看的时候发…

性能比肩美拍秒拍的Android视频录制编辑特效解决方案

前言 众所周知,Android平台开发分为Java层和C层,即Android SDK和Android NDK。常规产品功能只需要涉及到Java层即可,除非特殊需要是不需要引入NDK的。但如果是进行音视频开发呢? Android系统Java层API对音视频的支持在MediaCode…

仿秒拍视频网UI主题模板+Emlog内核开发

介绍: 高仿秒拍视频网emlog主题模板,相似度非常高,EMLOG加上这款模板完全可以用来当做视频网站使用,这款模板可以插入秒拍网的视频,只需要输入秒拍网的视频ID就可以直接调用播放,并且支持直接调用MP4视频链接播放&…

android 上传图片视频教程,秒拍怎么上传长视频 秒拍APP拍长视频并上传图文教程...

大家都知道秒拍是十秒拍大片,但是如果要拍长视频怎么办呢?拍了长视频又怎么上传呢?下面针对这些问题,小编就为大家带来秒拍拍长视频和上传的方法教程,希望可以帮到大家。 软件名称:秒拍 一下视频 for andro…

微博视频下载教程

文章目录 一、电脑端二、手机端三、其它写在最后 一、电脑端 1.网页搜索,点击官网。 2.在输入框搜索ID,以下图为例,点击相关用户。 3.点击【微博】,才可以看到全部内容。刚进来默认是【精选】,只有部分内容。 4.找到一…

用python下载视频代码_python实现视频下载

最近一两年短视频业务风生水起,各个视频网站都有各自特色的短视频内容。如果有这样一个程序,可以把各大视频网站的热门用户最新发布的视频都下载下来,不仅方便自己观看,还可以将没有版权的视频发布在个人社交网站上,增…

在电脑上如何直接下载秒拍的视频?

在生活中,我们想下载秒拍的视频,但是却找不到下载的标志?这该怎么办呢? 没有关系,不要着急,今天我就一步一步地教你下载 1.首先我们打开你想要下载的秒拍的视频的网页: 2.然后对于Chrome浏览器的…

php 秒拍视频解析,新浪微博视频解析源码_秒拍视频站外调用可自定义广告

这是一套非常不错的源码,这套源码一共只有100KB左右,你只需要将源码下载解压以后上传到支持php运行的服务器或者虚拟主机上,就可以直接使用了,使用方法很简单,将源码上传以后,直接通过:http://你…

php 秒拍视频解析,高仿秒拍视频网EMLOG主题模板

高仿秒拍视频网EMLOG主题模板,相似度非常高,EMLOG加上这款模板完全可以用来当做视频网站使用,这款模板可以插入秒拍网的视频,只需要输入秒拍网的视频ID就可以直接调用播放,并且支持直接调用MP4视频链接播放&#xff0c…

Terracotta设计原理分析

因为工作中历史产品采用了terracotta作为分布式缓存线性扩展平台,因此不得不提前对其原理做了相关了解,当然其中很多的设计思想和oracle、memcached的设计相似,但也有自己的亮点,那就是JVM的懒加载细粒度拷贝以及线性扩展&#xf…

Terracotta Java分布式任务调度平台 - Quartz

高效分布式Java任务调度平台 - Quartz Quartz是Java领域最著名的开源Java任务调度工具。它允许用户通过类似Unix上crontab类似的任务计划语法定义对Java任务的调度计划。 Terracotta于2009年末并购了Quartz项目,并将它与Terracotta核心平台进行紧密整合…