C语言C语言基于GTK+Libvlc实现的概括视频播放器

微编心语:现下,各种视频播放软件层出不穷,竞争为越来越演越烈,不懂得大家有木有这个想法,小编有时在想能不克召开同磨蹭属于自己之视频播放器呢~小编特意去实验楼,整理起了即首有关如何落实简易视频播放器的博文。简易播放器,你值得拥有~

友情提醒:这里只是前篇,只是有些简的功力,其他职能以会当后篇为大家介绍——

C语言基于GTK+Libvlc实现的简单视频播放器

一如既往、课程说明

比方你念过之前达到丝之pygtk实现有道词典的色征,那该本着gtk的下产生局部询问了,这个类型课学起来会相对轻松局部。 关于Gtk或者说是通常的图形应用开发之一部分基础知识,我们见面在后的功底科目中反映,项目征收称来肯定基础的用户学习。

二、Gtk简介

GTK+ 是平等种植图形用户界面(GUI)工具包。也就是说,它是一个仓库(或者,实际上是多只精心相关的库底集结),它支持创建基于 GUI 的应用程序。可以拿 GTK+ 想像成一个工具确保,从夫家伙包中可以找到用来创造 GUI 的多多一度准备好的组织块。

初期,GTK+ 是作为其它一个响当当的开放源码项目 —— GNU Image Manipulation Program (GIMP) —— 的副产品而创立的。在开早期的 GIMP 版本时,Peter Mattis 和 Spencer Kimball 创建了 GTK(它意味着 GIMP Toolkit),作为 Motif 工具确保的代表,后者于大时刻不是免费的。(当是家伙确保拿走了面向对象特性和而扩展性之后,才在名称后长了一个加号。)

随即多就 10 年过去了。今天,在 GTK+ 的最新稳定版本 —— 2.8 版上(3.0测试中),仍然当拓展过多走,同时,GIMP 的仍是以 GTK+ 的极致显赫的主次之一,不过它已经不是无比的应用 GTK+ 的次第了。已经为 GTK+ 编写了广大的应用程序,而且至少发生星星点点只举足轻重的桌面环境(Xfce 和 GNOME)用 GTK+ 为用户提供整机的工作环境。

GTK+虽然是为此C语言写的,但是你得运用你熟悉的言语来以GTK+,因为GTK+已经被绑定到几乎有流行的言语上,如:C++,PHP, Guile,Perl, Python, TOM, Ada95, Objective C, Free Pascal, and Eiffel

采用GTK+的精良应用程序:

· GIMP-GNU图像处理程序

· GNOME、XFCE等桌面环境和大多数窗口管理器都根据GTK+

· Inkscape-类似于Illustrator、CorelDraw的矢量图形绘制工具

· Pidgin-支持多商议(IRC、Gtalk、Yahoo Talk、MSN、QQ等等)的聊天工具

· Firefox 、Chrome-两不胜盛浏览器

· …

 

 

三、Vlc简介

1.简介:

VLC多媒体播放器(英语:VLC media player,最初也VideoLAN Client,是VideoLAN计划的怒放源代码多媒体播放器。)支持广大旋律与视频解码器及文件格式,并支持DVD影音光盘,VCD影音光盘及各类流 协议。它吗会看做单播或多播的流服务器在IPv4或IPv6的迅猛网络连接下使用。调用FFmpeg计划的解码器与libdvdcss程序库使其发广播多 媒体文件及加密DVD影碟的法力。

VLC自建之动态核心模块,使所有的接口(interfaces)、视频和拍子输出(video and audio outputs)、控制(controls)、定标器(scalers)、解码器(codecs)、音频/视频滤波器(audio/video filters)包含于联合之模块之内,便于使用。在广播媒体文件时,无需用户干预,VLC会根据不同之状态自行调度输入协议(input protocol)、输入文件的格式(input file format)、输入转码器(input codec)、视频卡功能(video card capabilities)和另外参数。

VLC media player具有超过平台的表征,可用以Linux、Microsoft Windows、Mac OS X、BeOS、OS/2、BSD、安卓、iOS、及Solaris。

2.libvlc

libvlc是VLC media player使用的多媒体框架的为主引擎以及壮大编程接口,它可以帮忙开发者开发大的多媒体应用

libvlc多媒体框架结构如下:

C语言 1

 

libvlc API关系图如下:

C语言 2

 

 

 

LibVlc官方API文档

四、gtk构建gtk界面

俺们先是为只是是布局以及添加控件,之后再来实现工作逻辑,不多说,直接看图,这即是咱们要事先实现之播放器大致的界面布局,不过者界面将不见面是咱们太 终要实现之规范,因为及时是运galde界面设计器创建的布局,大家初学时最为不要直接下glade来展开布局,因为她会忽略很多细节。先由手写代码的 方式进行布局以及添加控件,这样有助于你还好的控制那些控件的动办法。

C语言 3

1.先了解之布局的层次关系

 

window
|---vbox|-------menubar|-------drawingarea|-------hbox
        |---hbuttonbox
        |   |---playbutton
        |   |---stopbutton
        |---scale
        |---fullscreenbutton

 

2.落实这个布局的代码如下:

//filename:gui.c
#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,
                *playpause_button,
                *process_scale,
                *play_icon_image,
                *pause_icon_image,
                *stop_icon_image;
    GtkAdjustment  *process_adjuest;

    // 每个gtk程序都必须要有的,两个参数对应mian函数的两个参数,用于在命令行执行程序时传递并解析参数
    gtk_init(&argc, &argv);

    // 创建一个window并完成初始化,如设置为顶层窗口,宽度和高度,标题等,并绑定destory信号,以便在关闭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添加进menubar,最后将menubar放置进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的子容器,hbuttonbox用于放置两个button,
    // 再将一个scale(滚动条,用作视频播放进度条,原本的process控件不能拖动)添加进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);

    //创建一个滚动条,使用一个自定义的adjust对象初始化
    process_adjuest = gtk_adjustment_new(0.00, 0.00, 100.00, 1.00, 0.00, 0.00);
    process_scale = gtk_scale_new(GTK_ORIENTATION_HORIZONTAL,process_adjuest);
    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), 0);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);

    // 显示所有控件,并运行gtk程序
    gtk_widget_show_all(window);
    gtk_main ();

    return 0;
}

 

 

 

 

 

设您当出窘迫可以直接下载代码:(以下内容是当实验楼网站的杜撰平台及以的,没有以实验楼的莫需下面这个手续)

$ wget https://raw.githubusercontent.com/shiyanlou/gtk-vlc-video-player/master/gui.c

3.代码认证:

上述代码,使用如下命令编译和运转:

 

# 注意pgk-config...那里不是单引号,是反单引号$ gcc gui.c -o gui `pkg-config --libs --cflags gtk+-3.0`$ ./gui

 

 

 

运转后,你用张

C语言 4

代码的说明说明,已经竭尽在诠释中说明,代码中有gtk的API的采取与详尽说明,请参考官方API文档,一些API的参数如果不顶明白,你可直接在代码中改也歧的价,然后编译并运行代码,观察效果,帮助理解.

五、使用libvlc播放媒体文件通过gtk中展示

1.运libvlc创建一个媒体播放器对象

以mian函数中上加如下代码:

    

 //setup vlc
    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);

 

 

2.使filechooserdialog打开一个视频文件

率先让菜单栏中之open添加一个点击信号处理函数on_open,注意一般信号处 理函数的下令规则就是是在部数称为前增长”on_”,但马上不是必备的,然后以on_open这个信号处理函数中,创建一个 filechoosedialog,并运行。打开文件,获取到uri(?)后,将该传递让open_media函数,使用vlc打开并播放视频文件。这里 注意,要惦记叫vlc播放的视频展示在窗口被还得让前创建的draw_area控件绑定一个信号处理函数,这之中会将vlc的播放器窗口绘制在控件被。

实际贯彻代码如下:

补加信号处理

 

 

// 添加信号处理函数
g_signal_connect(filemenu_openitem, "activate", G_CALLBACK(on_open), window);

 

 

 

处理函数实现

 

// 信号处理函数 
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, _("Cancel"), 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/video_length*100);

    play();
    libvlc_media_release(media);
}

 

 

 

 

以咱们使用了libvlc所以上面代码在编译时索要添加libvlc的编译和链接选项,可下pkg-config工具得到

比如:$ gcc -o videoplayer videoplayer.c `pkg-config --cflags --libs gtk+-3.0 libvlc`

 

 

一切正常的言语,现在你的播放器应该已经足以播放出视频了,如果您用一个视频文件来测试播放效果的话语,你得应用我提供的一个视频文件,这是一个一定幽默之视频,所以想您得要是打响,然后您才会见到这视频的情。

$ wget http://anything-about-doc.qiniudn.com/gtk_libvlc_video_player/video_demo_01.flv

 

六、实现简单的播报控制,暂定/播放以及平息

这比较简单了,就是为播放以及已按钮分别绑定两单点击信号处理函数,并重复富有当前是否也播放状态设置按钮显示为播放还是暂定,及实现视频的暂定和延续播放

切切实实代码如下:

无异于先补充加信号处理

(略)

 

处理函数实现

// 使用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);
}

// 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);
}

 

 

七、实现广播进度显示与拖动进度修跳转

1.视频播C语言放进度的示

使显播放进度,可以用单薄栽办法,第一栽乎,自定义一个信号在vlc的播放进度发生变化时就是发送这个信号,然后以滚动条绑定该信号,在拖欠信号的信 号处理函数中取得vlc播放进度,并安装为滚动条之值;另一样栽是加上一个定时器,每隔一个时刻按0.5s去赢得vlc的播放进度,使用之前创建滚动条是 自定义之一个GtkAdjuestment对象了安装滚动条的快慢。前一模一样栽办法比较复杂,这里我们以后一样种植

实际代码如下:

在open_media函数中补充加定时器

 

 

// 表示每隔500ms会调用\_update\_scale函数,并将process\_scale作为数据对象传入
g_timeout_add(500,_update_scale,process_scale);

 

 

 

_update_scale函数实现

 

 

// 该函数为一个`GSourceFunc`函数类型,要求必须要有返回值,返回类型为`gboolean`,
// 如要下次继续执行该定时器,须返回`G\_SOURCE\_CONTINUE`,否则返回`G\_SOURCE\_REMOVE`
gboolean _update_scale(gpointer data){
    // 获取当前打开视频的长度,时间单位为ms
    video_length = libvlc_media_player_get_length(media_player);    
    current_play_time = libvlc_media_player_get_time(media_player);
    gtk_adjustment_set_value(process_adjuest,current_play_time/video_length*100);
    return G_SOURCE_CONTINUE;
}

 

 

 

2.兑现拖动进度长跳转

这职能可以吃scale添加一个value\_changed信号处理函数就得实现,只是这里发出个小问题不怕,如果一直这样实现的话,会及方的速度显示出点小冲突,以为上面的速更新为会触发这里的信号处理函数,导致视频一直在那么来转卡动无法正常播放,这里我们可于更新速度条凡使用临时阻塞value\_changed信号的艺术避免这个题材

切实代码如下:

补加信号处理(略)

处理函数实现

// 通过adjuest对象获取拖动到的进度数值(根据之前的设定为1-100的范围),
// 然后使用libvlc设定播放位置(根据百分百设定,故要除以100)
void on_value_change(GtkWidget *widget, gpointer data)
{
    float scale_value = gtk_adjustment_get_value(process_adjuest);
    libvlc_media_player_set_position(media_player, scale_value/100);
}

 

 

修改_update_scale函数如下:

// 在更新进度条数值前先阻塞信号处理函数的执行,之后在取消阻塞
gboolean _update_scale(gpointer data){
    // 获取当前打开视频的长度,时间单位为ms
    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_adjuest,current_play_time/video_length*100);
    g_signal_handlers_unblock_by_func(G_OBJECT(process_scale), on_value_change, NULL);
    return G_SOURCE_CONTINUE;
}

 

 

七、总结


过地方的有认证,相信你得单独构建一个贯彻基本功能的视频播放器了,不过总的说来,它是在凡无限基础了,简单来说话根本拿不出手啊,作为团结便 使用都
会有问题,比如不克全屏,不克互补加字幕,不可知调节高低(抱歉当前我们的试验环境或吧任不顶声音,但对于一个播放器来说这等同接触我们还是如促成)等 等,这
来就请求而想下一致节省项目征收吧,我以牵动您同一步一步上加效果,完善我们的视频播放器

本节完整代码下载(以下内容是于实验楼网站的杜撰平台及运的,没有动用实验楼的免待下面这手续)

$ git clone https://github.com/shiyanlou/gtk-vlc-video-player.git

重新多详细步骤及代码请登录实验楼官方网站:http://www.shiyanlou.com/courses/69

起再度多基础课、项目征欢迎大家登陆实验楼官方网站http://www.shiyanlou.com。
今昔登陆实验楼更有感恩好礼相送http://www.shiyanlou.com/huodong/thanks.html