[工程模板][MediaPlayer] Gtk+FFmpeg+GStreamer

Output

linux 系统下可执行文件。


Brief

多媒体播放器模板,使用 Gtk 构建 ui,FFmpeg做多媒体 utility ,GStreamer做多媒体框架。


结构

.
├── BUILD
├── ButtonHelper.cpp
├── ButtonHelper.h
├── CMakeLists.txt
├── DrawingAreaHelper.cpp
├── DrawingAreaHelper.h
├── layout.ui
└── main.cpp


CMakeLists.txt

# 1) cmake basic
cmake_minimum_required(VERSION 3.12) #cmake version check
set(CXX_STANDARD 17) #c++ standard version)



# 2) project info
#auto generated variables as below:
#PROJECT_NAME: "hello"
#hello_BINARY_DIR: build root dir
#hello_SOURCE_DIR: source root dir
project(hello LANGUAGES C CXX)  #project name
message("build root dir: ${hello_BINARY_DIR}")
message("source root dir: ${hello_SOURCE_DIR}")



# 3) specify source files and create target
#SOURCE_FILES: all c cpp and hpp as source file
file(GLOB_RECURSE SOURCE_FILES  #glob all source files(c cpp hpp , h is excluded)
    ${hello_SOURCE_DIR}/*.c
    ${hello_SOURCE_DIR}/*.cpp
    ${hello_SOURCE_DIR}/*.hpp
)
list(FILTER SOURCE_FILES EXCLUDE REGEX "CMakeFiles/*")   #exclude cmake files from source list
message("source files: ${SOURCE_FILES}")
add_executable(${PROJECT_NAME} ${SOURCE_FILES}) #add executable file



# 4) package dependency (pkg-config)
find_package(PkgConfig REQUIRED)

#GTK_INCLUDE_DIRS : HEADER SERARCH PATHS
#GTK_LIBRARIES : LIBRARY NAME
#GTK_LIBRARY_DIRS : LIBRARY PATHS
pkg_check_modules(GTK REQUIRED gtk+-3.0)

pkg_check_modules(GLIB REQUIRED glib-2.0)



# 5) include and link
include_directories(                    #head search path
    ${GTK_INCLUDE_DIRS}
)
link_directories(                      #library search path 
    ${GTK_LIBRARY_DIRS}
)
target_link_libraries(${PROJECT_NAME}   #what libraries needs to link
    ${GTK_LIBRARIES}
)



# 6) ADD_DEFINITIONS
ADD_DEFINITIONS(-D LINUX)



# 7) install
#install ${PROJECT_NAME} to ~/bin
set(INSTALL_PATH ~/bin)
install(
    TARGETS ${PROJECT_NAME} 
    DESTINATION ${INSTALL_PATH}
)
#install config file to ~/bin
set(INSTALL_PATH ~/bin)
file(GLOB_RECURSE CONFIG_FILES 
    ${hello_SOURCE_DIR}/*.ui
    ${hello_SOURCE_DIR}/*.ini
    ${hello_SOURCE_DIR}/*.conf
)
install(
    FILES ${CONFIG_FILES}
    DESTINATION ${INSTALL_PATH}
)

.gitignore

# ignore all first
*

# exception of "ignore all" , files with specific appendix
!*.cpp
!*.h
!*.txt
!*.ui

# exception of "ignore all" , files with specific appendix in specific dir
#!src/*.cpp
#!docs/*.md

 


基础代码

layout.ui

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow" id="main_window">
    <property name="title">GTK Video Player</property>
    <property name="default-width">1200</property>
    <property name="default-height">600</property>
    <child>
      <object class="GtkBox" id="main_hbox">
        <property name="orientation">horizontal</property>
        <property name="spacing">5</property>

        <!-- Left Sidebar with scrollable content -->
        <child>
          <object class="GtkScrolledWindow" id="scrolled_sidebar">
            <property name="width-request">150</property>
            <property name="hscrollbar-policy">never</property>
            <property name="vscrollbar-policy">automatic</property>
            <child>
              <object class="GtkViewport">
                <child>
                  <object class="GtkBox" id="sidebar">
                    <property name="orientation">vertical</property>
                    <property name="spacing">5</property>

                    <!-- Add 10 Buttons to the sidebar -->
                    <child>
                      <object class="GtkButton" id="Start">
                        <property name="label">Start</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="Pause">
                        <property name="label">Pause</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="Stop">
                        <property name="label">Stop</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_4">
                        <property name="label">Button 4</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_5">
                        <property name="label">Button 5</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_6">
                        <property name="label">Button 6</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_7">
                        <property name="label">Button 7</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_8">
                        <property name="label">Button 8</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_9">
                        <property name="label">Button 9</property>
                      </object>
                    </child>
                    <child>
                      <object class="GtkButton" id="button_10">
                        <property name="label">Button 10</property>
                      </object>
                    </child>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>

        <!-- Separator between sidebar and drawing area -->
        <child>
          <object class="GtkSeparator" id="separator">
            <property name="orientation">vertical</property>
          </object>
        </child>

        <!-- Center Video Area -->
        <child>
          <object class="GtkDrawingArea" id="video_area">
            <property name="hexpand">true</property>
            <property name="vexpand">true</property>
          </object>
        </child>

      </object>
    </child>
  </object>
</interface>

main.cpp

#include <gtk/gtk.h>
#include "ButtonHelper.h"
#include "DrawingAreaHelper.h"

static void activate(GtkApplication *app, gpointer user_data) {
    GtkBuilder *builder = gtk_builder_new();
    gtk_builder_add_from_file(builder, "layout.ui", NULL);

    GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "main_window"));

    bool ret = ButtonHelper::getInstance()->SetUp(builder);
    ret = DrawingAreaHelper::getInstance()->SetUp(builder);

    gtk_window_set_default_size(GTK_WINDOW(window), 1440, 810); // Set window size
    gtk_widget_set_size_request(window, 800, 600); // Set drawing area size
    gtk_widget_show_all(window);
}

int main(int argc, char **argv) {
    GtkApplication *app;
    int status;

    app = gtk_application_new("org.gtk.example", G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
    
    status = g_application_run(G_APPLICATION(app), argc, argv);

    gtk_main ();

    return status;
}

ButtonHelper.h

#ifndef BUTTONHELPER_H
#define BUTTONHELPER_H

#include <gtk/gtk.h>

class ButtonHelper{

private:
    ButtonHelper();
    ~ButtonHelper();

public:
    static ButtonHelper* getInstance();
    bool SetUp(GtkBuilder *builder);
};

#endif

ButtonHelper.cpp

#include "ButtonHelper.h"
#include <gtk/gtk.h>
#include <cassert>
#include <string>

ButtonHelper::ButtonHelper(){

}

ButtonHelper::~ButtonHelper(){

}

ButtonHelper* ButtonHelper::getInstance(){
    static ButtonHelper instance;
    return &instance;
}

static void Start (GtkWidget *widget, gpointer data){
  g_print ("Start\n");
}
static void Pause (GtkWidget *widget, gpointer data){
  g_print ("Pause\n");
}
static void Stop (GtkWidget *widget, gpointer data){
  g_print ("Stop\n");
}

bool ButtonHelper::SetUp(GtkBuilder *builder){
    GtkWidget *sidebar = GTK_WIDGET(gtk_builder_get_object(builder, "sidebar"));
    assert(sidebar);
    GList *children = gtk_container_get_children(GTK_CONTAINER(sidebar));
    assert(children);

    for(GList *iter = children; iter!= NULL; iter = g_list_next(iter)){
        GtkWidget *child = GTK_WIDGET(iter->data);
        assert(child);
        if(GTK_IS_BUTTON(child)){
            const char* button_lable;
            g_object_get(GTK_BUTTON(child), "label", &button_lable, NULL);
            g_print ("button_lable = %s\n", button_lable);

            //need to be refined with simpler implementation with Macro/template
            if      (std::string(button_lable) == "Start"){
                g_signal_connect(GTK_BUTTON(child), "clicked", G_CALLBACK(Start), NULL);
            }else if(std::string(button_lable) == "Pause"){
                g_signal_connect(GTK_BUTTON(child), "clicked", G_CALLBACK(Pause), NULL);
            }else if(std::string(button_lable) == "Stop"){
                g_signal_connect(GTK_BUTTON(child), "clicked", G_CALLBACK(Stop), NULL);
            }
        }
    }
}

DrawingAreaHelper.h

#ifndef DRAWING_AREA_HELPER_H
#define DRAWING_AREA_HELPER_H

#include <gtk/gtk.h>

class DrawingAreaHelper{
    DrawingAreaHelper(); //constructor
    ~DrawingAreaHelper(); //destructor
public:
    static DrawingAreaHelper* getInstance();
    bool SetUp(GtkBuilder *builder);
};

#endif

DrawingAreaHelper.cpp

#include "DrawingAreaHelper.h"
#include <gtk/gtk.h>
#include <cassert>

DrawingAreaHelper::DrawingAreaHelper(){

}

DrawingAreaHelper::~DrawingAreaHelper(){

}

DrawingAreaHelper* DrawingAreaHelper::getInstance(){
    static DrawingAreaHelper instance;
    return &instance;
}

bool DrawingAreaHelper::SetUp(GtkBuilder *builder){
    GtkWidget *drawing_area = GTK_WIDGET(gtk_builder_get_object(builder, "video_area"));
    assert(drawing_area);
}

使用方法

1)保证根目录下有BUILD目录,如果没有则创建。

2)进入BUILD目录,执行 cmake .. 

3)make 构建,make install 把构建结果 install 到 CMakeLists.txt 文件指定的路径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值