Using Gstreamer in your Flutter project Pt.1 C: file
Published on 6/23/2024
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.
Prerequisites
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.
Required Tools and Software
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.
GStreamer Pipeline
The C program we’ll build includes a GStreamer pipeline that looks like this:
gst-launch-1.0 audiotestsrc ! audioconvert ! autoaudiosink Creating the C Program
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;
} Building with CMake
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}) Compiling and Running
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 Conclusion
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.
GitHub Repository
You can find the complete code for this project on GitHub. Files after changes from this tutorial: https://github.com/fengjiongmax/fltgst/tree/3c73f61a78f4fa34db4e28393c80b95a3169a978