首先参考官网(ubuntu16.04安装会有问题)和部分博客入门,形成对gstreamer的认识!
1.安装
gstreamer对应的github推荐使用packages安装,而不是自己编译,原文如下:
INSTALLING FROM PACKAGES
------------------------
You should always prefer installing from packages first. GStreamer is
well-maintained for a number of distributions, including Fedora, Debian,
Ubuntu, Mandrake, Gentoo, ...
Only in cases where you:
- want to hack on GStreamer
- want to verify that a bug has been fixed
- do not have a sane distribution
should you choose to build from source tarballs or git.
因此,ubuntu16.04系统下,可采用:
sudo apt-cache search gstreamer #查询系统源(比如我设置的清华镜像源)中包含的gst
sudo apt-get install gstreamer1.0* #安装上述搜索的packages
上述步骤中install可能会有错误 ,比如我的:
The following packages have unmet dependencies:
gstreamer1.0-hybris:i386 : Depends: libmedia1:i386 but it is not going to be installed
通常ubuntu安装包分为amd64(64bit)和i386(32bit)两种,这里需要在64位的系统上安装i386的包 ,因此需要手动安装。安装原则:提示差什么包就安装什么包,如这里需要安装libmedia1:i386
sudo apt-get install libmedia1:i386
2.概念
博客中写的太好,所以摘抄一段!!!
2.1 GstElement是组成管道的基本构件;
可细分3类 | Source Element 数据源元件 | 只有输出端,它仅能用来产生供管道消费的数据,而不能对数据做任何处理。一个典型的数据源元件的例子是音频捕获单元,它负责从声卡读取原始的音频数据,然后作为数据源提供给其它模块使用。 |
Filter Element 过滤器元件 | 既有输入端又有输出端,它从输入端获得相应的数据,并在经过特殊处理之后传递给输出端。一个典型的过滤器元件的例子是音频编码单元,它首先从外界获得音频数据,然后根据特定的压缩算法对其进行编码,最后再将编码后的结果提供给其它模块使用。 | |
Sink Element 接收器元件 | 只有输入端,它仅具有消费数据的能力,是整条媒体管道的终端。一个典型的接收器元件的例子是音频回放单元,它负责将接收到的数据写到声卡上,通常这也是音频处理过程中的最后一个环节。 |
现在有了组成管道的基本构件GstElement,那么怎么与外界连接呢?就得用到衬垫(pad)
2.2 pad是元件(element)与外界的连接通道,对于框架中的某个特定元件来说,其能够处理的媒体类型正是通过衬垫暴露给其它元件的。
现在本来已经可以使用管道(pipeline)技术了,但是gstreamer还把上面的几种Element装到一个箱子里面,方便统一管理,于是就有了bin
2.3 bin是GStreamer框架中的容器元件,它通常被用来容纳其它的元件对象,但由于其自身也是一个GstElement对象,因此实际上也能够被用来容纳其它的箱子对象。
3.gstreamer测试
测试源文件test.c
#include <stdio.h>
#include <gst/gst.h>
int main (int argc, char *argv[])
{
const gchar *nano_str;
guint major, minor, micro, nano;
gst_init (&argc, &argv);
gst_version (&major, &minor, µ, &nano);
if (nano == 1)
nano_str = "(CVS)";
else if (nano == 2)
nano_str = "(Prerelease)";
else
nano_str = "";
printf ("This program is linked against GStreamer %d.%d.%d %s\n",
major, minor, micro, nano_str);
return 0;
}
编译CMakeLists.txt
用到了pkg-config查找库信息(包括库的路径、头文件路径),官网解释:
It helps you insert the correct compiler options on the command line so an application can use gcc -o test test.c `pkg-config --libs --cflags glib-2.0`
for instance, rather than hard-coding values on where to find glib (or other libraries).
命令测试:
pkg-config --libs --cflags glib-2.0
输出:-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0 (字体有点看不出来,前两个是头文件路径,后一个
是库路径)
cmake_minimum_required(VERSION 2.8)
project(gst)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0)
include_directories(
${GLIB_INCLUDE_DIRS}
)
link_directories(
${GLIB_LIBRARY_DIRS}
)
set(GSTREAMER_MINIMUM_VERSION 1.0.5)
pkg_check_modules(GST1_TEST gstreamer-1.0)
if ( GST1_TEST_FOUND AND NOT ${GST1_TEST_VERSION} VERSION_LESS ${GSTREAMER_MINIMUM_VERSION} )
pkg_check_modules(GSTREAMER REQUIRED gstreamer-1.0)
pkg_check_modules(GSTREAMER-APP REQUIRED gstreamer-app-1.0)
pkg_check_modules(GSTREAMER-AUDIO REQUIRED gstreamer-audio-1.0)
pkg_check_modules(GSTREAMER-PBUTILS REQUIRED gstreamer-pbutils-1.0)
pkg_check_modules(GSTREAMER-FFT REQUIRED gstreamer-fft-1.0)
add_definitions(-DGST_API_VERSION_1=1)
else()
# fallback to gstreamer-0.10
unset(GSTREAMER_MINIMUM_VERSION)
pkg_check_modules(GSTREAMER REQUIRED gstreamer-0.10)
pkg_check_modules(GSTREAMER-APP REQUIRED gstreamer-app-0.10)
pkg_check_modules(GSTREAMER-AUDIO REQUIRED gstreamer-audio-0.10)
pkg_check_modules(GSTREAMER-FFT REQUIRED gstreamer-fft-0.10)
set_source_files_properties(WebKitWebAudioSourceGStreamer.cpp PROPERTIES COMPILE_DEFINITIONS "GLIB_DISABLE_DEPRECATION_WARNINGS=1")
endif()
include_directories(
${GSTREAMER_INCLUDE_DIRS}
${GSTREAMER-APP_INCLUDE_DIRS}
${GSTREAMER-AUDIO_INCLUDE_DIRS}
${GSTREAMER-PBUTILS_INCLUDE_DIRS}
${GSTREAMER-FFT_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
)
link_directories(
${GSTREAMER_LIBRARY_DIRS}
${GSTREAMER-APP_LIBRARY_DIRS}
${GSTREAMER-AUDIO_LIBRARY_DIRS}
${GSTREAMER-PBUTILS_LIBRARY_DIRS}
${GSTREAMER-FFT_LIBRARY_DIRS}
)
set( CMAKE_C_COMPILER gcc)
set( CMAKE_CXX_COMPILER g++)
set(test_LIBRARIES
${GSTREAMER_LIBRARIES}
${GSTREAMER-APP_LIBRARIES}
${GSTREAMER-AUDIO_LIBRARIES}
${GSTREAMER-PBUTILS_LIBRARIES}
${GSTREAMER-FFT_LIBRARIES}
pthread
${GLIB_LIBRARIES}
${GLIB_GIO_LIBRARIES}
${GLIB_GOBJECT_LIBRARIES}
)
set(src test.c)
add_executable(test ${src})
target_link_libraries(test ${test_LIBRARIES})
编译CMakeLists.txt输出
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.1")
-- Checking for module 'glib-2.0'
-- Found glib-2.0, version 2.48.2
-- Checking for module 'gstreamer-1.0'
-- Found gstreamer-1.0, version 1.8.3
-- Checking for module 'gstreamer-1.0'
-- Found gstreamer-1.0, version 1.8.3
-- Checking for module 'gstreamer-app-1.0'
-- Found gstreamer-app-1.0, version 1.8.3
-- Checking for module 'gstreamer-audio-1.0'
-- Found gstreamer-audio-1.0, version 1.8.3
-- Checking for module 'gstreamer-pbutils-1.0'
-- Found gstreamer-pbutils-1.0, version 1.8.3
-- Checking for module 'gstreamer-fft-1.0'
-- Found gstreamer-fft-1.0, version 1.8.3
CMake Warning (dev) at CMakeLists.txt:74 (add_executable):
Policy CMP0037 is not set: Target names should not be reserved and should
match a validity pattern. Run "cmake --help-policy CMP0037" for policy
details. Use the cmake_policy command to set the policy and suppress this
warning.
The target name "test" is reserved or not valid for certain CMake features,
such as generator expressions, and may result in undefined behavior.
This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring done
-- Generating done-- Build files have been written to: /media/lab/873821cf-d234-44cf-bd63-4372eac823a1/ARM_SYSTEM/raspberrypi/gstreamer/test/build
make后运行结果:
This program is linked against GStreamer 1.8.3
4.声音测试
4.1 命令测试
测试命令:
gst-launch-1.0 audiotestsrc ! autoaudiosink
系统中可能会有多个版本的gstreamer(可以通过whereis命令查看:whereis gst-inspect-1.0),比如我的Ubuntu系统中,anaconda环境下还有一个gstreamer(安装不完整),因此我将anaconda环境下的gstreamer 卸载了。
conda list | grep gst #查看gstreamer的包
卸载上述命令找到的所有包:
conda remove gstreamer
重新安装gstreamer:
sudo apt-get install gstreamer1.0*
音乐测试(filesrc是音乐源,mad是编码器,autoaudiosink是):
gst-launch-1.0 filesrc location=love.mp3 ! mad ! autoaudiosink
或以下命令:
gst-launch-1.0 filesrc location=love.mp3 ! mad ! playsink
Setting pipeline to PAUSED ...
Pipeline is PREROLLING ...
Redistribute latency...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstPulseSinkClock
Got EOS from element "pipeline0".
Execution ended after 0:04:40.932763883
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...
查看playsink和autoaudiosink
gst-inspect-1.0 playsink
gst-inspect-1.0 autoaudiosink
输出分别是:
filesrc | mad | playsink | autoaudiosink |
---|---|---|---|
Factory Details: Plugin Details: GObject Implemented Interfaces: Pad Templates: | Factory Details: Plugin Details: GObject Pad Templates: SRC template: 'src' | Factory Details: Plugin Details: GObject Implemented Interfaces: Pad Templates: SINK template: 'audio_sink' SINK template: 'video_raw_sink' SINK template: 'video_sink' SINK template: 'text_sink' | Factory Details: Plugin Details: GObject Implemented Interfaces: Pad Templates: |
source element(只有输出端) | filter element(输出端+输入端) | sink element(只有输入端),这个应该可以播放音频、视频、文本。 | sink element(只有输入端) |
4.2 程序测试
/*****
命令行工具:gst-launch-1.0 filesrc location=${1.mp3} ! mad ! autoaudiosink
source:filesrc filter:mad sink:autoaudiosink
*****/
#include<gst/gst.h>
#include<stdio.h>
int main(int argc, char *argv[])
{
//定义element pad bin等
GstElement *pipeline, *filesrc, *decoder, *musicsink;
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
gst_init(&argc, &argv); //初始化
if (argc != 2) {
g_print ("usage: %s <mp3 filename>\n", argv[0]);
return -1;
}
pipeline = gst_pipeline_new("pipeline");
filesrc = gst_element_factory_make("filesrc","disk_source");//文件源,从磁盘读取
g_object_set(G_OBJECT(filesrc),"location",argv[1],NULL); //设置从argv[1]位置读取
decoder = gst_element_factory_make("mad","decoder"); //“mad”元件中实际包含sink和src两个衬垫
/*
Pads:
SINK template: ’sink’
Availability: Always
Capabilities:
’mad_sink’:
MIME type: ’audio/mp3’:
SRC template: ’src’
Availability: Always
Capabilities:
’mad_src’:
MIME type: ’audio/raw’:
format: String: int
endianness: Integer: 1234
width: Integer: 16
depth: Integer: 16
channels: Integer range: 1 - 2
law: Integer: 0
signed: Boolean: TRUE
rate: Integer range: 11025 - 48000
*/
musicsink = gst_element_factory_make("autoaudiosink","play_audio");//接收器Element,利用声卡播放 GstElement *gst_element_factory_make (const gchar *factoryname, const gchar *name)
if (!pipeline || !filesrc || !decoder || !musicsink)
{
g_print("Not all elements could be created.\n");
return -1;
}
gst_bin_add_many(GST_BIN(pipeline), filesrc, decoder, musicsink, NULL);//将Element添加到bin中
gst_element_link_many(filesrc, decoder, musicsink, NULL);//将Element通过pad连接起来
ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);//将pipeline设置为play状态
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_print("Unable to set the pipeline to playing state.\n");
/*void gst_object_unref (gpointer object);
Decrements the reference count on object . If reference count hits zero, destroy object . This function does not take the lock on object as it relies on atomic refcounting.*/
gst_object_unref(pipeline);
return -1;
}
g_print("start to play music!");
/* Wait until error or EOS */
/*GstBus *gst_element_get_bus (GstElement *element);
Returns the bus of the element. Note that only a GstPipeline will provide a bus for the application.*/
bus = gst_element_get_bus (pipeline);
/*GstMessage *gst_bus_timed_pop_filtered (GstBus *bus, GstClockTime timeout, GstMessageType types);
Get a message from the bus whose type matches the message type mask types , waiting up to the specified timeout (and discarding any messages that do not match the mask provided).
If timeout is 0, this function behaves like gst_bus_pop_filtered(). If timeout is GST_CLOCK_TIME_NONE, this function will block forever until a matching message was posted on the bus.*/
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
g_print("msg:%s\n",msg);
/* Parse message */
if (msg != NULL) {
GError *err;
gchar *debug_info;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
break;
case GST_MESSAGE_EOS:
g_print ("End-Of-Stream reached.\n");
break;
default:
/* We should not reach here because we only asked for ERRORs and EOS */
g_printerr ("Unexpected message received.\n");
break;
}
gst_message_unref (msg);
}
gst_object_unref(bus);
//while(gst_bin_iterate_sinks(GST_BIN(pipeline)));//不断迭代bin,直到没有数据
gst_element_set_state(pipeline, GST_STATE_NULL);//将pipeline设置为NULL状态
gst_object_unref(GST_OBJECT(pipeline));
return 0;
}
编译方式:
- 直接编译:gcc mp3.c -o mp3 `pkg-config --cflags --libs gstreamer-1.0`
- 编写CMakeLists.txt编译(见上文)