• GTK开发视频播放器


    按照第三方库和软件包:

     sudo apt-get install libgtk-3-dev
     sudo apt-get install libgtk-3-doc
     sudo apt-get install vlc libvlc-dev

    其中使用了gtk第三方库,具体API请看官网https://developer.gnome.org/gtk3/stable/index.html

    gtk构建gtk界面

    #include<gtk/gtk.h>
    #include<gdk/gdkx.h>
    #include<glib.h>
    
    #define BORDER_WIDTH 6
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window,
                    *vbox,
                    *hbox,
                    *menubar,
                    *filemenu,
                    *fileitem,
                    *filemenu_openitem,
                    *hbuttonbox,
                    *player_widget,
                    *stop_button,
                    *full_screen_button,
                    *preocess_scale,
                    *playpause_button,
                    *process_scale,
                    *play_icon_image,
                    *pause_icon_image,
                    *stop_icon_image;
        GtkAdjustment *process_adjust;
    
        /*
        每个gtk程序都必须要有的
        *两个参数对应main函数的两个参数
        *用于在命令行执行程序时解析参数
        */
        gtk_init(&argc, &argv);
    
        /*
        创建一个window并完成初始化,如设置为顶层窗口,宽度和高度、标题等
        *并绑定destroy信号,以便在关闭gtk窗口时程序可以完全退出
        */
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
        g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
        gtk_container_set_border_width(GTK_CONTAINER(window), 0);
        gtk_window_set_title(GTK_WINDOW(window), "GTK+ libVLC Demo");
    
        /*
        * 创建一个方向垂直间距为0的box容器,并添加到前面创建的window里
        */
        vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
        gtk_container_add(GTK_CONTAINER(window), vbox);
    
        /*
        * 创建一个menubar和两个menuitem分别为菜单里“文件”和“打开”
        * 由于他们是上下级菜单的关系
        * 所以需要一个单独menu来防止“open_menu_item”,也就是代码中的filemenu_openitem
        * */
        menubar = gtk_menu_bar_new();
        fileitem = gtk_menu_item_new_with_label("File");
        filemenu_openitem = gtk_menu_item_new_with_label("Open");
        filemenu = gtk_menu_new();
        gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), filemenu_openitem);
    
        /*
        * 将filemenu设置为上一级fileitem的子菜单,
        * 然后将fileitem添加到menumbar,最后将menumbar添加到vbox中
        * */
        gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileitem), filemenu);
        gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileitem);
        gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
    
        /*
        *创建一个draw_area控件,用作视频播放显示区域,并放进vbox中
        * */
        player_widget = gtk_drawing_area_new();
        gtk_box_pack_start(GTK_BOX(vbox), player_widget, TRUE, TRUE, 0);
    
        /*
        *再创建一个hbox作为vbox的子容器,一个hbuttonbox作为hbox的子容器
        * hbutton里面放置两个button
        * 再将一个scale(滚动条,用作视频播放进度条)添加到hbox,再将hbox放到最外面的vbox中
        * */
        hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
        hbuttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
        gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox), BORDER_WIDTH);
        gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_START);
    
        playpause_button = gtk_button_new_from_icon_name("media-playback-start", GTK_ICON_SIZE_BUTTON);
        stop_button = gtk_button_new_from_icon_name("media-playback-stop", GTK_ICON_SIZE_BUTTON);
    
        gtk_box_pack_start(GTK_BOX(hbuttonbox), playpause_button, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(hbuttonbox), stop_button, FALSE, FALSE, 0);  
        gtk_box_pack_start(GTK_BOX(hbox), hbuttonbox, FALSE, FALSE, 0); 
    
        process_adjust = gtk_adjustment_new(0.00, 0.00, 100.00, 1.00, 0.00, 0.00);
        process_scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, process_adjust);
        gtk_box_pack_start(GTK_BOX(hbox), process_scale, TRUE, TRUE, 0);
        gtk_scale_set_draw_value (GTK_SCALE(process_scale), FALSE);
        gtk_scale_set_has_origin (GTK_SCALE(preocess_scale), 0);
        gtk_scale_set_value_pos(GTK_SCALE(process_scale), 0);
        gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
    
        //显示所有控件,并运行gtk程序
        gtk_widget_show_all(window);
        gtk_main();
    
        return 0;
    }

    编译运行:

    gcc gui.c -o gui `pkg-config --libs --cflags gtk+-3.0`

    ./gui

    运行结果:

    播放视频:
    在以上代码基础上添加播放视频功能:

    makefiel

    CFLAGS=`pkg-config --cflags gtk+-3.0 libvlc`
    LIBS=`pkg-config --libs gtk+-3.0 libvlc`
    
    all:
        gcc vlcgtk.c -o vlcgtk -Wall $(LIBS) $(CFLAGS)
    clean:
        rm vlcgtk

    源码

    #include<stdlib.h>
    #include<gtk/gtk.h>
    #include<gdk/gdkx.h>
    #include<glib.h>
    #include <glib/gi18n.h>
    #include<vlc/vlc.h>
    
    #define BORDER_WIDTH 6
    
    void destroy(GtkWidget *widget, gpointer data);
    void player_widget_on_realize(GtkWidget *widget, gpointer data);
    void on_open(GtkWidget *widget, gpointer data);
    void open_media(const char *uri);
    void on_playpause(GtkWidget *widget, gpointer data);
    void on_stop(GtkWidget *widget, gpointer data);
    void play(void);
    void pause_player(void);
    
    gboolean _update_scale(gpointer data);
    void on_value_change(GtkWidget *widget, gpointer data);
    
    libvlc_media_t *media;
    libvlc_media_player_t *media_player;
    //libvlc_instance_t *vlc_inst;
    libvlc_instance_t *vlc_inst;
    
    GtkWidget *playpause_button, *play_icon_image, *pause_icon_image, *stop_icon_image,
                *process_scale;
    GtkAdjustment *process_adjueset;
    
    float video_length, current_play_time;
    
    int main(int argc, char *argv[])
    {
        GtkWidget *window,
                    *vbox,
                    *hbox,
                    *menubar,
                    *filemenu,
                    *fileitem,
                    *filemenu_openitem,
                    *player_widget,
                    *hbuttonbox,
                    *stop_button;
        
        gtk_init(&argc, &argv);
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
        gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
        g_signal_connect(window, "destroy", G_CALLBACK(destroy), NULL);
        gtk_container_set_border_width(GTK_CONTAINER(window), 0);
        gtk_window_set_title(GTK_WINDOW(window), "GTK+ libVLC Demo");
    
        vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, FALSE);
        gtk_container_add(GTK_CONTAINER(window), vbox);
        hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, FALSE);
    
        menubar = gtk_menu_bar_new();
        filemenu = gtk_menu_new();
        fileitem = gtk_menu_item_new_with_label("File");
        filemenu_openitem = gtk_menu_item_new_with_label("Open");
        gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), filemenu_openitem);
        gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileitem), filemenu);
        gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileitem);
    
        gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
        g_signal_connect(filemenu_openitem, "activate", G_CALLBACK(on_open), window);
    
        player_widget = gtk_drawing_area_new();
        gtk_box_pack_start(GTK_BOX(vbox), player_widget, TRUE, TRUE, 0);
    
        playpause_button = gtk_button_new_from_icon_name("media-playback-start", GTK_ICON_SIZE_BUTTON);
        stop_button = gtk_button_new_from_icon_name("media-playback-stop", GTK_ICON_SIZE_BUTTON);
    
        //信号处理函数
        g_signal_connect(playpause_button, "clicked", G_CALLBACK(on_playpause), NULL);
        g_signal_connect(stop_button, "clicked", G_CALLBACK(on_stop), NULL);
    
        hbuttonbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
        gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox), BORDER_WIDTH);
        gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_START);
    
        gtk_box_pack_start(GTK_BOX(hbuttonbox), playpause_button, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(hbuttonbox), stop_button, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(hbox), hbuttonbox, FALSE, FALSE, 0);
        gtk_box_pack_start(GTK_BOX(hbox), hbox, FALSE, TRUE, 0);
    
        vlc_inst = libvlc_new(0, NULL);
        media_player = libvlc_media_player_new(vlc_inst);
        g_signal_connect(G_OBJECT(player_widget), "realize", 
                        G_CALLBACK(player_widget_on_realize), media_player);
                                    
        process_adjueset = gtk_adjustment_new(0.00, 0.00, 100.00, 1.00, 0.00, 0.00);
        process_scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL, process_adjueset);
    
        gtk_box_pack_start(GTK_BOX(hbox), process_scale, TRUE, TRUE, 0);
        gtk_scale_set_draw_value (GTK_SCALE(process_scale), FALSE);
        gtk_scale_set_has_origin(GTK_SCALE(process_scale), TRUE);
        gtk_scale_set_value_pos(GTK_SCALE(process_scale), 5);
        g_signal_connect(G_OBJECT(process_scale), "value_changend", G_CALLBACK(on_value_change), NULL);
    
        gtk_widget_show_all(window);
        gtk_main();
    
        libvlc_media_player_release(media_player);
        libvlc_release(vlc_inst);
        return 0;
    }
    
    void destroy(GtkWidget *widget, gpointer data)
    {
        gtk_main_quit();
    }
    
    void player_widget_on_realize(GtkWidget *widget, gpointer data)
    {
        libvlc_media_player_set_xwindow((libvlc_media_player_t*)data, GDK_WINDOW_XID(gtk_widget_get_window(widget)));
    }
    
    //信号处理函数
    void on_open(GtkWidget *widget, gpointer data)
    {
        GtkWidget *dialog;
        GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
    
        dialog = gtk_file_chooser_dialog_new("open file", GTK_WINDOW(widget), action, 
                    _("Cancle"), GTK_RESPONSE_CANCEL, _("Open"), GTK_RESPONSE_ACCEPT, NULL);
    
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
        {
            char *uri;
            uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(dialog));
            open_media(uri);
            g_free(uri);
        }
    
        gtk_widget_destroy(dialog);
    }
    
    //传入视频文件uri,使用libvlc播放视频文件
    void open_media(const char *uri)
    {
    
        media = libvlc_media_new_location(vlc_inst, uri);
        libvlc_media_player_set_media(media_player, media);
    
        current_play_time = 0.0f;
        gtk_scale_set_value_pos(GTK_SCALE(process_scale), current_play_time);
        play();
        g_timeout_add(500, _update_scale, process_scale);
        libvlc_media_release(media);
    }
    
    //使用libvlc传入当前的播放器,获取播放状态
    void on_playpause(GtkWidget *widget, gpointer data)
    {
        if (libvlc_media_player_is_playing(media_player) == 1)
        {
            pause_player();
        }
        else
        {
            play();
        }
        
    }
    
    void on_stop(GtkWidget *widget, gpointer data)
    {
        pause_player();
        libvlc_media_player_stop(media_player);
    }
    
    //该函数为一个GSourceFunc函数类型,要求必须要有返回值,返回类型为gboolen
    //如果下次继续执行该定时,须返回`G\_SOURCE\_CONTINUE`,否则返回`G\_SOURCE\_REMOVE`
    gboolean _update_scale(gpointer data)
    {
        video_length = libvlc_media_player_get_length(media_player);
        current_play_time = libvlc_media_player_get_time(media_player);
    
        g_signal_handlers_block_by_func(G_OBJECT(process_scale), on_value_change, NULL);
        gtk_adjustment_set_value(process_adjueset, current_play_time/video_length*100);
        g_signal_handlers_unblock_by_func(G_OBJECT(process_scale), on_value_change, NULL);
        return G_SOURCE_CONTINUE;
    }
    
    //通过adjuest对象获取拖动到的进度数值(根据之前设定为1-100的范围)
    //然后使用libvlc设定播放位置(根据百分百设定,故要除以100)
    void on_value_change(GtkWidget *widget, gpointer data)
    {
        float scale_value = gtk_adjustment_get_value(process_adjueset);
        libvlc_media_player_set_position(media_player, scale_value/100);
    }
    
    //play函数播放视频,并将播放按钮的图标换成暂停的图标
    void play(void)
    {
        libvlc_media_player_play(media_player);
        pause_icon_image = gtk_image_new_from_icon_name("media-playback-pause", GTK_ICON_SIZE_BUTTON);
        gtk_button_set_image(GTK_BUTTON(playpause_button), pause_icon_image);
    }
    
    void pause_player(void)
    {
        libvlc_media_player_pause(media_player);
        play_icon_image = gtk_image_new_from_icon_name("media-playback-start", GTK_ICON_SIZE_BUTTON);
        gtk_button_set_image(GTK_BUTTON(playpause_button), play_icon_image);
    }
  • 相关阅读:
    js相关小实例——大图轮播
    js相关小实例——div实现下拉菜单
    js相关小实例——二级菜单
    html5部分相关
    CSS3常用属性(边框、背景、文本效果、2D转换、3D转换、过渡、有过渡效果大图轮播、动画)
    数据访问
    php测试
    单例模式
    Doc
    横竖列表 下拉隐藏显示
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/12164797.html
Copyright © 2020-2023  润新知