Basic tutorial 10: GStreamer 工具
Basic tutorial 10: GStreamer tools
目标
GStreamer附带了一系列工具,从基本必备的工具到方便灵活的小工具,应有尽有。本章教程无代码,将讲解如下内容:
- 无需任何C代码,如何从命令行构建和运行一个GStreamer的pipelines
- 如何找出可用的GStreamer elements(元素)及其capabilities(能力)
- 如何发现媒体文件的内部结构
gst-launch-1.0
该工具接受文本形式描述的pipeline,实例化它,并且将此pipeline设置为PLAYING
状态。它可以让你在使用GStreamer API调用前迅速的验证给定的pipeline是否能正常工作。
请记住,它只能创建简单的pipeline(管道)。特别是,它只能模拟管道与应用程序在一定级别上的交互。在任何情况下,快速测试pipeline(管道)都非常方便,全球的GStreamer开发人员每天都在使用它。
请注意,gst-launch-1.0
主要是作为开发人员的调试工具。你不应该使用它构建应用程序。你应该使用GStreamer的APIgst_parse_launch()
函数来构建管道。
尽管构建pipeline的描述规则非常简单,但是包含多个elements连接的描述规则可能又会变得复杂起来。
gst-launch-1.0
的命令行包含一个选项列表,后面跟着一个PIPELINE-DESCRIPTION
。下面给出了一些简化的说明,请参阅gst-launch-1.0
的参考页上的完整文档。
Elements(元素)
简单来说,PIPELINE-DESCRIPTION
是由感叹号(!)分隔开的elements类型列表,如下面这个示例:
gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink
你应该看到一个带有动画视频模式的窗口。在终端上使用CTRL+C停止程序。这个实例创建了一个videotestsrc
的element(生成测试视频的element),一个videoconvert
的element(原始视频格式转化的element,确保在它左右两端的element可以相互理解,其实就是协商成功)和一个autovideosink
的element(根据系统软硬件环境自动选择合适的video sink)。然后,GStreamer尝试按照列出的顺序将各element连接起来(将左边element的src连到右边element的sink)。如果element有多个可用的Pad,这时会尝试通过PadCaps来匹配兼容的Pad对(左边element的src和右边element的sink)。
Properties(属性)
Properties可用附加到Elements后面,格式为property=value(可指定多个property,用空格分隔)。使用gst-inspect-1.0
工具(下面将介绍)可查看element的可用property。
gst-launch-1.0 videotestsrc pattern=11 ! videoconvert ! autovideosink
您应该会看到一个由圆圈组成的静态测试视频。
Named elements(有名元素)
之前的教程说过任何一个element都包含一个name属性,它是一个字符串,继承自GstObject
。可以使用name属性命名element,这样就可以创建涉及多分支的复杂pipeline。可以通过names引用在之前描述中创建的element,并且对于使用具有多个输出pad的element,names是必不可少的,例如demuxers或tee。
引用已命名的element时只要在它的names后面跟个点号(.)。示例如下:
gst-launch-1.0 videotestsrc ! videoconvert ! tee name=t ! queue ! autovideosink t. ! queue ! autovideosink
您应该看到两个视频窗口,显示相同的测试视频。如果你只看到一个,试着移动它,因为它可能在第二个窗口的顶部。
这个例子实例化了一个videotestsrc
,它链接到一个videoconvert
,videoconvert
又链接到一个tee
(还记得基础教程7:多线程和Pad可用性,tee将所有通过其输入Pad的内容复制到每个输出Pad)。tee
被简单地命名为“t”(使用name属性),然后链接到一个queue
和一个autovideosink
。同样的tee
也用t.
来引用。’(注意这个点),然后链接到第二个queue
和第二个autovideosink
。
要了解为什么queue是必要的,请阅读基础教程7:多线程和Pad可用性。
Pads(链接点)
在链接两个element时,您可能希望直接指定Pad,而不是让GStreamer选择使用哪个Pad。你可以在element名称后加上一个点加上Pad名称(类似于结构体的成员引用,它必须是一个namedelement)来做到这一点。使用gst-inspect-1.0工具了解element的pad名称。
这很有用,例如,当你想从demuxer中检索一个特定的流时:
gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! matroskademux name=d d.video_0 ! matroskamux ! filesink location=sintel_video.mkv
包含媒体数据的文件一般叫做container,例如mp4,ogg,avi等。它们可以包含1个或者多个流,如视频,音频,字幕,同类型的流也可以有多个存在。
上面例子使用souphttpsrc
从网络上获取一个媒体文件,格式是webm
。我们使用matroskademux
打开这个container文件,此文件包含音频和视频,因此matroskademux
会生成2个输出类型的pad(src pad),会被自动命名为video_0
和audio_0
。
为啥会是这种格式的pad名呢?通过
gst-inspect-1.0
看到matroskademux
的Pad Templates
:
Pad Templates: SRC template: 'video_%u' Availability: Sometimes Capabilities: ANY SRC template: 'audio_%u' Availability: Sometimes Capabilities: ANY SRC template: 'subtitle_%u' Availability: Sometimes
SRC template就指定了它的命名格式,类似于printf的格式化
我们将video_0
链接到一个matroskamux
element,将视频流重新打包到一个新的container中,最后将其链接到一个filesink
,该element将把视频流写入名为“sintel_video.mkv”的文件中。(location属性指定文件的名称)。
总而言之,我们取了一个webm文件,去掉了音频数据,并将视频数据生成到一个新的matroska格式文件。如果我们只想保留音频:
gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! matroskademux name=d d.audio_0 ! vorbisparse ! matroskamux ! filesink location=sintel_audio.mka
vorbisparse
元素需要从流中提取一些信息并将其放入Pad Caps中,以便下一个元素matroskamux
知道如何处理流。在视频的情况下,这是不必要的,因为matroskademux
已经提取了该信息并将其添加到Caps中。
注意,在上面的两个例子中,没有媒体文件被解码或播放。我们只是从一个容器移动到另一个容器(多次进行demux和mux操作)。
这里又涉及到一个概念mux和demux,复用和解复用。从一个container中分离出流的过程就叫做demux,把1个或多个流整到一个container的过程就叫mux。
需要注意,这里为啥处理视频选择matroskamux, matroskademu,处理音频使用vorbisparse?其实是根据sintel_trailer-480p.webm这个文件来的,为了方便演示,提前获取了这个container里面包含的流的格式,然后直接使用对应格式的muxer、demuxer、parser。正常情况下,是通过一个叫findtype的element探测的。使用GStreamer的另一个工具gst-discoverer-1.0可以查看container的里面包含的流信息。
我们把这个文件下下来,然后用gst-discoverer-1.0查看
wget https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm gst-discoverer-1.0 sintel_trailer-480p.webm Analyzing file:///home/a/Videos/sintel_trailer-480p.webm Done discovering file:///home/a/Videos/sintel_trailer-480p.webm Topology: container: WebM audio: Vorbis video: VP8 Properties: Duration: 0:00:52.250000000 Seekable: yes Live: no Tags: container format: Matroska language code: en title: Audio, Sintel Trailer, Audio, Audio, Sintel Trailer encoder: Xiph.Org libVorbis I 20090709 bitrate: 80000 artist: Durian Open Movie Team copyright: (c) copyright Blender Foundation | durian.blender.org license: Creative Commons Attribution 3.0 license video codec: VP8 video application name: ffmpeg2theora-0.24 encoder version: 0 audio codec: Vorbis nominal bitrate: 80000
Caps filters(Caps过滤器)
当一个element有多个输出pad时(src pad),可能出现链接到下一个element时不明确到底该用哪个pad的情况:下一个element可能包含多个兼容的输入pad(sink pad),或者只有个输入pad,但是这个输入pad与前面那个element的多个输出pad兼容。在这种情况下GStreamer将使用第一个可用的pad进行链接,可以认为此时选择哪个输出pad是随机的。
如下pipeline:
gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! matroskademux ! filesink location=test
这个例子中媒体文件和demuxer和上一个例子是一样的。filesink
的输入pad的Caps是ANY
,意味着它可以接受任何类型的媒体。那matroskademux
的2个输出pad哪个会链接到filesink
呢?video_0
还是audio_0
?不得而知。
不过,你可以通过named pad,或者caps filters来消除这里的模糊性:
gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! matroskademux ! video/x-vp8 ! matroskamux ! filesink location=sintel_video.mkv
Caps filter的行为就像一个直通的element,它啥也不做,仅仅接受带有指定Caps的媒体,有效的消除了歧义。在这个例子中,在matroskademux
和matroskamux
之间,我们添加了一个video/x -vp8
的caps filter来指定我们感兴趣的输出pad,这样它就可以产生这种格式的视频。
要找出element接受和产生的Caps,可以使用gst-inspect-1.0
工具。要找出特定文件中包含的Caps,请使用gst-discoverer-1. 0
。要找出element为特定pipeline生成的Caps,可以像往常一样运行gst-launch-1.0
,并使用-v
选项打印Caps信息。
例子
使用playbin
播放一个媒体文件:
gst-launch-1.0 playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm
完整的回放pipeline构建,带音、视频操作:
gst-launch-1.0 souphttpsrc location=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! matroskademux name=d ! queue ! vp8dec ! videoconvert ! autovideosink d. ! queue ! vorbisdec ! audioconvert ! audioresample ! autoaudiosink
一个转码pipeline,它打开webm格式的容器文件,并且解码每个流(通过uridecodebin),然后再用不同的编解码器重新编码音视频流分支,最后由oggmux
重新mux到一个ogg文件中。
gst-launch-1.0 uridecodebin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm name=d ! queue ! theoraenc ! oggmux name=m ! filesink location=sintel.ogg d. ! queue ! audioconvert ! audioresample ! flacenc ! m.
一个缩放pipeline,当输入和输出帧的大小不同时,videoscale
执行缩放操作,输出caps通过caps filter设置为320x200
gst-launch-1.0 uridecodebin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm ! queue ! videoscale ! video/x-raw-yuv,width=320,height=200 ! videoconvert ! autovideosink
对gst-launch-1.0
的简短描述应该足以让您入门,完整的文档,请查看
gst-inspect-1.0
该工具有三种操作模式:
- 如果没有参数,它会列出所有可用的element类型,也就是可以用来实例化新element的类型。
- 使用文件名作为参数,它将该文件视为GStreamer插件,尝试打开它,并列出其中描述的所有elements。
- 使用GStreamer element名作为参数,它列出了关于该element的所有信息。
一个使用第三种模式的例子:
gst-inspect-1.0 vp8dec Factory Details: Rank primary (256) Long-name On2 VP8 Decoder Klass Codec/Decoder/Video Description Decode VP8 video streams Author David Schleef <ds@entropywave.com>, Sebastian Dröge <sebastian.droege@collabora.co.uk> Plugin Details: Name vpx Description VP8 plugin Filename /usr/lib64/gstreamer-1.0/libgstvpx.so Version 1.6.4 License LGPL Source module gst-plugins-good Source release date 2016-04-14 Binary package Fedora GStreamer-plugins-good package Origin URL http://download.fedoraproject.org GObject +----GInitiallyUnowned +----GstObject +----GstElement +----GstVideoDecoder +----GstVP8Dec Pad Templates: SINK template: 'sink' Availability: Always Capabilities: video/x-vp8 SRC template: 'src' Availability: Always Capabilities: video/x-raw format: I420 width: [ 1, 2147483647 ] height: [ 1, 2147483647 ] framerate: [ 0/1, 2147483647/1 ] Element Flags: no flags set Element Implementation: Has change_state() function: gst_video_decoder_change_state Element has no clocking capabilities. Element has no URI handling capabilities. Pads: SINK: 'sink' Pad Template: 'sink' SRC: 'src' Pad Template: 'src' Element Properties: name : The name of the object flags: readable, writable String. Default: "vp8dec0" parent : The parent of the object flags: readable, writable Object of type "GstObject" post-processing : Enable post processing flags: readable, writable Boolean. Default: false post-processing-flags: Flags to control post processing flags: readable, writable Flags "GstVP8DecPostProcessingFlags" Default: 0x00000403, "mfqe+demacroblock+deblock" (0x00000001): deblock - Deblock (0x00000002): demacroblock - Demacroblock (0x00000004): addnoise - Add noise (0x00000400): mfqe - Multi-frame quality enhancement deblocking-level : Deblocking level flags: readable, writable Unsigned Integer. Range: 0 - 16 Default: 4 noise-level : Noise level flags: readable, writable Unsigned Integer. Range: 0 - 16 Default: 0 threads : Maximum number of decoding threads flags: readable, writable Unsigned Integer. Range: 1 - 16 Default: 0
最关键的部分是:
- Pad Templates:这里列出了该element可以拥有的所有类型的pad,以及它们的功能。这是查找一个element是否可以与另一个element链接的地方。在这种情况下,它只有一个sink pad模板,只接受
video/x-vp8
(VP8格式的编码视频数据),只有一个src pad模板,产生视频/x-raw(解码的视频raw数据)。 - Element Properties:这将列出element的属性,以及它们的类型和可接受的值,可读可写等。
更完整的文档,请查看
gst-discoverer-1.0
该工具接受来自命令行的URI,并打印关于GStreamer可以提取的媒体的所有信息。了解使用了哪些容器和编解码器来生成媒体,以及需要在pipeline中放入哪些元素来播放媒体是很有用的。-v
选项可输出更详细的信息。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
2017-03-08 sendto函数的坑