In this part of the series, we'll create a C program to generate a simple sine wave using GStreamer. In the following videos, we'll explore how to use Flutter to call functions from this C program.
Before following this series, ensure you have:
Basic knowledge of the C programming language.
Basic knowledge of Dart/Flutter.
Basic knowledge of CMake.
Basic knowledge of GStreamer.
This part of the series is demonstrated on a Linux PC. You may adapt the instructions for other operating systems. Below are the common requirements:
GStreamer Libraries: Install the GStreamer and its development libraries. Follow the GStreamer documentation for installation guidelines.
Code Editor: Any code editor will work, but I use VSCode.
CMake: Download from cmake.org. On Linux, you can install it via your package manager.
The C program we'll build includes a GStreamer pipeline that looks like this:
gst-launch-1.0 audiotestsrc ! audioconvert ! autoaudiosink
First, create a directory for your project:
mkdir fltgst
Next, open VSCode (or your preferred code editor) and create the main.c
file. The C code for our simple pipeline is as follows:
#include <gst/gst.h>
// gst-launch-1.0 audiotestsrc ! audioconvert ! autoaudiosink
typedef struct _FltGstData
{
GstElement *pipeline;
GstElement *audiotestsrc;
GstElement *audioconvert;
GstElement *autoaudiosink;
GMainLoop *mainloop;
} FltGstData;
FltGstData *data;
void init(void)
{
// init
gst_init(NULL, NULL);
data = (FltGstData *)malloc(sizeof(FltGstData));
}
void setup_pipeline(void)
{
// setup pipeline
data->audiotestsrc = gst_element_factory_make("audiotestsrc", NULL);
data->audioconvert = gst_element_factory_make("audioconvert", NULL);
data->autoaudiosink = gst_element_factory_make("autoaudiosink", NULL);
data->pipeline = gst_pipeline_new(NULL);
data->mainloop = g_main_loop_new(NULL, FALSE);
if (!data->audiotestsrc || !data->audioconvert || !data->autoaudiosink || !data->pipeline)
{
g_printerr("Elements could not be created.\n");
gst_object_unref(data->pipeline);
return;
}
gst_bin_add_many(GST_BIN(data->pipeline), data->audiotestsrc, data->audioconvert, data->autoaudiosink, NULL);
if (!gst_element_link_many(data->audiotestsrc, data->audioconvert, data->autoaudiosink, NULL))
{
g_printerr("Elements could not be created.\n");
gst_object_unref(data->pipeline);
return;
}
}
void start_pipeline(void)
{
// start pipeline
GstStateChangeReturn ret;
ret = gst_element_set_state(data->pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_printerr("Elements could not be created.\n");
gst_object_unref(data->pipeline);
return;
}
}
void run_mainloop(void)
{
// run main loop
g_main_loop_run(data->mainloop);
}
void free_resource(void)
{
// free resources
gst_element_set_state(data->pipeline, GST_STATE_NULL);
gst_object_unref(data->pipeline);
}
int main(int argc, char const *argv[])
{
init();
setup_pipeline();
start_pipeline();
run_mainloop();
free_resource();
return 0;
}
We need a build system to handle the compilation and linking of our program. We'll use CMake, which is compatible with Flutter's build system for C code. Write the following CMakeLists.txt
file in the same directory as main.c
:
cmake_minimum_required(VERSION 3.5)
project(fltgst VERSION 0.0.1
LANGUAGES C)
find_package(PkgConfig REQUIRED)
pkg_search_module(GST REQUIRED gstreamer-1.0)
include_directories(${GST_INCLUDE_DIRS})
add_executable(${PROJECT_NAME} main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE ${GST_LDFLAGS})
With both files created, you can now build the C program:
cmake . # this will generate the makefiles
make # this is the actual command that build the executable
You should now see an executable named fltgst
in your directory:
$ ls -l
total 60
-rw-rw-r-- 1 max max 15893 6月 24 09:56 CMakeCache.txt
drwxrwxr-x 6 max max 4096 6月 24 09:56 CMakeFiles
-rw-rw-r-- 1 max max 1646 6月 24 09:56 cmake_install.cmake
-rw-rw-r-- 1 max max 302 2月 7 20:24 CMakeLists.txt
-rwxrwxr-x 1 max max 16664 6月 24 09:56 fltgst # <- this one
-rw-rw-r-- 1 max max 2044 2月 7 20:24 main.c
-rw-rw-r-- 1 max max 5125 6月 24 09:56 Makefile
Run the executable to hear the sine wave:
./fltgst
That's it for this video. In the next video, we'll integrate GStreamer with a Flutter project targeting Linux, using similar code to what's in our main.c
file.
You can find the complete code for this project on GitHub.
Files after changes from this tutorial: https://github.com/fengjiongmax/fltgst/tree/3c73f61a78f4fa34db4e28393c80b95a3169a978