注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

jasy.ice 的小房子

iceplayer gtk linux c

 
 
 

日志

 
 

Splayer 1.001  

2009-12-13 14:04:28|  分类: IcePlayer |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
>splayer,开发到2009年11月多的时候才发现名字被  射手播放器  用了,,,杯具啊,所以我的代码内都是用splayer的。。。。。

>2009年9月9日,经过一个多小时的编写,splayer的雏形出来了。。版本为1.001
       只完成基本界面,能选择和播放單曲,并实现播放、停止功能。
       解码器为gst的。用gtk2.0的button和filechoose及combox控件。
>由于是第一个版本,用于过程测试(白盒)有很多bug和警告,不具参考性学习性。建议等待之后的版本。
              SlaxPlayer_1.0.01 - jasy.ice - Jasy.ice
全部源代码及makefile:

      http://www.uushare.com/filedownload?user=jayivy1&id=2313752
     运行需要:  gstreamer0.10-ffmpeg,libc6,libglib2.0-0, libgtk2.0-0
     编译需要:  libgstreamer0.10-dev   libgtk2.0-dev 

主要源代码:

#include <gtk/gtk.h>
#include <pthread.h>
#include <gst/gst.h>
#include <stdbool.h>
GtkWidget *button;
GtkWidget *combo;
GtkWidget *combo_entry;
GtkWidget *image_play;
GtkWidget *image_pause;
gboolean play_state;

pthread_t playing_pthread;//播放 线程 标识符。
int playing_pthread_int;//播放 线程的int。
GList *files;

GMainLoop *loop;//播放循环

char file_name[400] = "file://";//file_name即要播放的 文件的uri 格式为"file:///home/1.mp3"。
char file_name_new[400] = "file://";//file_name_new 即手动选 择的新的 要播放的文 件,格式和上面一样。

void SPlayer (void);//负责主界面
void on_button_clicked (GtkWidget *button,gpointer user_data);//播放键按下时调用此函数,将会看play_state 的值来改变按钮的图像和播放或暂停
GdkPixbuf *create_pixbuf (const gchar * filename);
void selected (GtkList *list,GtkWidget *item);//当用户自己选择列表的歌曲时调用此函数
void choose_file (GtkWidget *filechooserbutton,gpointer user_data);//生成对话框来选择文件
void play_uri ();
gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer user_data);//At L247,播放文件的循环函数,调用g_main_loop_quit(loop)便可终止(loop已经弄成全局函数了)
int gtk_combo_index (GtkCombo *combo);//FIXME At L211 这是获取当前的combo的播放列表的index函数很不好,臃肿低效,是我很久以前combobox还没出来的时候写的,懒得改了。
void main_quit();

void
SPlayer (void)
{
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\界面代码//////////////////////////////////////
//\\\\\\\\\\\\\\\\\\\\\////////////////////////
    GtkWidget *MainWin_SPlayer;
    GtkWidget *hbox;
    GtkWidget *fixed;
    GtkWidget *filechooserbutton;
    GdkPixbuf *MainWin_SPlayer_icon_pixbuf;

    MainWin_SPlayer = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title (GTK_WINDOW (MainWin_SPlayer), "SPlayer");
    gtk_window_set_position (GTK_WINDOW (MainWin_SPlayer), GTK_WIN_POS_CENTER);
    gtk_window_set_resizable (GTK_WINDOW (MainWin_SPlayer), FALSE);
    MainWin_SPlayer_icon_pixbuf = create_pixbuf ("app.png");
// gtk_window_set_skip_taskbar_hint (GTK_WINDOW (MainWin_SPlayer), TRUE);//放不放到taskbar 自己决定
    if (MainWin_SPlayer_icon_pixbuf)
    {
        gtk_window_set_icon (GTK_WINDOW (MainWin_SPlayer), MainWin_SPlayer_icon_pixbuf);
    }

    hbox = gtk_hbox_new (FALSE, 0);
    gtk_widget_show (hbox);
    gtk_container_add (GTK_CONTAINER (MainWin_SPlayer), hbox);

    button = gtk_button_new ();
    gtk_widget_show (button);
    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
    gtk_widget_set_size_request (button, -1, 36);

    image_play = gtk_image_new_from_stock ("gtk-media-play", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show (image_play);

    image_pause = gtk_image_new_from_stock ("gtk-media-pause", GTK_ICON_SIZE_BUTTON);
    gtk_widget_show (image_pause);
    gtk_container_add (GTK_CONTAINER (button), image_pause);


    fixed = gtk_fixed_new ();
    gtk_widget_show (fixed);
    gtk_box_pack_start (GTK_BOX (hbox), fixed, TRUE, TRUE, 0);
    gtk_widget_set_size_request (fixed, 30, -1);

    filechooserbutton = gtk_button_new ();
    gtk_widget_show (filechooserbutton);
    gtk_fixed_put (GTK_FIXED (fixed), filechooserbutton, 0, 8);
    gtk_widget_set_size_request (filechooserbutton, 30, 21);

    combo = gtk_combo_new ();
    g_object_set_data (G_OBJECT (GTK_COMBO (combo)->popwin),"GladeParentKey", combo);
    gtk_widget_show (combo);
    gtk_box_pack_start (GTK_BOX (hbox), combo, TRUE, TRUE, 0);
    gtk_combo_set_use_arrows_always (GTK_COMBO (combo), TRUE);

    combo_entry = GTK_COMBO (combo)->entry;
    gtk_widget_show (combo_entry);
    gtk_widget_set_size_request (combo_entry, 300, 18);
    gtk_editable_set_editable (GTK_EDITABLE (combo_entry), FALSE);
    gtk_entry_set_has_frame (GTK_ENTRY (combo_entry), FALSE);
    gtk_entry_set_invisible_char (GTK_ENTRY (combo_entry), 8226);

    g_signal_connect ((gpointer) button, "clicked",G_CALLBACK(on_button_clicked),NULL);
    g_signal_connect ((gpointer) MainWin_SPlayer, "delete_event",G_CALLBACK(main_quit),NULL);
    gtk_signal_connect (GTK_OBJECT (GTK_COMBO(combo)->list),"select_child",GTK_SIGNAL_FUNC (selected),NULL);
    g_signal_connect ((gpointer) filechooserbutton,"clicked",G_CALLBACK(choose_file),NULL);

//////////////////////////\\\\\\\\\\\\\\\\\\\\\\
////////////////////////////////////////界面代码\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//
    play_state = FALSE;
    gtk_widget_show_all (MainWin_SPlayer);
    gtk_main ();
    if (loop!=NULL)g_main_loop_quit(loop);
}

void main_quit()
{
    if(loop)g_main_loop_quit(loop);
    gtk_main_quit();
}

void on_button_clicked (GtkWidget *button,gpointer user_data)//播放键按下时调用此函数,将会看play_state 的值来改变按钮的图像和播放或暂停
{
    if (play_state == FALSE)//暂停
    {
        gtk_container_remove (GTK_CONTAINER (button), image_pause);
        gtk_container_add (GTK_CONTAINER (button), image_play);
        playing_pthread_int = pthread_create (&playing_pthread,NULL,play_uri,NULL);//创建线程 连接到play_uri函数
        play_state = TRUE;
    }
    else
    {
        gtk_container_remove (GTK_CONTAINER (button), image_play);
        gtk_container_add (GTK_CONTAINER (button), image_pause);
        if (loop!=NULL)g_main_loop_quit(loop); //终止播放循环
        play_state = FALSE;
    }
}

void selected (GtkList *list,GtkWidget *item)//当用户自己选择列表的歌曲时调用此函数
{
    g_print ("Splay>>>>选择列表的歌曲\n");
    strcpy (file_name_new,"file://");
    strcat (file_name_new,gtk_entry_get_text (combo_entry));//得到combo的文本框的内容
    if (strcmp(file_name,file_name_new)!=0)//分辨用户是否更改了歌曲
    {
        g_main_loop_quit (loop);
        strcpy (file_name,file_name_new);
        play_state = FALSE;
        on_button_clicked (button,NULL);
    }
}
void choose_file (GtkWidget *filechooserbutton,gpointer user_data)//生成对话框来选择文件
{
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\界面代码//////////////////////////////////////
//\\\\\\\\\\\\\\\\\\\\\////////////////////////
    g_print ("Splay>>>>生成对话框来选择文件\n");
    GtkWidget *filechooserdialog;
    GtkWidget *dialog_vbox1;
    GtkWidget *dialog_action_area1;
    GtkWidget *button1;
    GtkWidget *button2;

    filechooserdialog = gtk_file_chooser_dialog_new ("请选择歌曲", NULL, GTK_FILE_CHOOSER_ACTION_OPEN, NULL);
    gtk_container_set_border_width (GTK_CONTAINER (filechooserdialog), 5);
    g_object_set (filechooserdialog,"select-multiple", TRUE,NULL);
    gtk_window_set_position (GTK_WINDOW (filechooserdialog), GTK_WIN_POS_CENTER);
    gtk_window_set_skip_taskbar_hint (GTK_WINDOW (filechooserdialog), TRUE);
    gtk_window_set_type_hint (GTK_WINDOW (filechooserdialog), GDK_WINDOW_TYPE_HINT_DIALOG);

    dialog_vbox1 = GTK_DIALOG (filechooserdialog)->vbox;
    gtk_widget_show (dialog_vbox1);

    dialog_action_area1 = GTK_DIALOG (filechooserdialog)->action_area;
    gtk_widget_show (dialog_action_area1);
    gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area1), GTK_BUTTONBOX_END);

    button1 = gtk_button_new_from_stock ("gtk-cancel");
    gtk_widget_show (button1);
    gtk_dialog_add_action_widget (GTK_DIALOG (filechooserdialog), button1, GTK_RESPONSE_CANCEL);
    GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);

    button2 = gtk_button_new_from_stock ("gtk-open");
    gtk_widget_show (button2);
    gtk_dialog_add_action_widget (GTK_DIALOG (filechooserdialog), button2, GTK_RESPONSE_OK);
    GTK_WIDGET_SET_FLAGS (button2, GTK_CAN_DEFAULT);

    gtk_widget_grab_default (button2);
//////////////////////////\\\\\\\\\\\\\\\\\\\\\\
////////////////////////////////////////界面代码\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\//
    if (gtk_dialog_run(filechooserdialog)==GTK_RESPONSE_OK)//按下确定键!
    {
        files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER( filechooserdialog));//返回一个GList并赋值给files
        GList *it = NULL;
        GList *items = NULL;
        for (it = files; it; it = it->next)//循环并添加歌曲到combo的列表里
        {
            items = g_list_append (items, it->data);

        }
        gtk_combo_set_popdown_strings (GTK_COMBO (combo), items);
    }

    gtk_widget_destroy (filechooserdialog);
}
int gtk_combo_index (GtkCombo *combo)//FIXME 这是获取当前的combo的播放列表的index函数很不好,臃肿低效,是我很久以前combobox还没出来的时候写的,懒得改了。
{
    if (combo)
    {
        int index = 0;
        GList *combo_list;
        GtkListItem *combo_list_Item;
        GtkWidget *label;
        char *text = gtk_entry_get_text (GTK_ENTRY(combo->entry));
        char *text2;
        combo_list = GTK_LIST (combo->list)->children;

        while (combo_list)
        {
            combo_list_Item = GTK_LIST_ITEM (combo_list->data);
// 那个 "gtk-combo-string-value"已经 defined 在 gtkcombo.c
            text2 = (char *)gtk_object_get_data(GTK_OBJECT((GtkListItem *)(combo_list->data)),"gtk-combo-string-value");
            if (!text2)
            {
                label = GTK_BIN (combo_list_Item)->child;
                if (label)
                    if (GTK_IS_LABEL(label)) gtk_label_get(GTK_LABEL(label), &text2);
            }
            if (text2)
            {
                if (!strcmp(text2, text)){
                    g_print ("Splay>>>>获取当前的combo的播放列表的index,index的值为%d",index);
                    return index;
                }
            }
            index++;
            combo_list = combo_list->next;
        }
    }else{
        g_print ("Splay>>>>combo错误?");
    }
    g_print ("Splay>>>>到了列表末尾了");
    return -1;
}
gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer user_data)//播放文件的循环函数,调用g_main_loop_quit(loop)便可终止(loop已经弄成全局函数了)
{
    switch (GST_MESSAGE_TYPE (msg))
    {
    case GST_MESSAGE_EOS:
        g_print ("Splay>>>>文件播放完毕,将尝试播放下一首\n");
        if (loop!=NULL)g_main_loop_quit (loop);
        gint a = gtk_combo_index (GTK_COMBO(combo));
        if (a!=-1)
        {
            a++;
            gtk_list_select_item (GTK_COMBO(combo)->list,a);
        }
        else
            g_print ("Splay>>>>整个列表已经播放完毕!");
        break;
    case GST_MESSAGE_ERROR:
        g_print ("Splay>>>>文件播放错误,请检查文件的格式和完整性!\n");
        if (loop!=NULL)g_main_loop_quit (loop);
        g_print ("Splay>>>>尝试播放下一首!\n");
        gint b = gtk_combo_index (GTK_COMBO(combo));
        if (b!=-1)
        {
            b++;
            gtk_list_select_item (GTK_COMBO(combo)->list,b);
        }
        else
            g_print ("Splay>>>>整个列表已经播放完毕!");
        break;
    default:
        break;
    }
    return true;
}

void play_uri ()//很简单,自己看
{
    GstElement *pipeline;
    loop = g_main_loop_new (NULL, FALSE);
    g_print ("Splay>>>>调取play_uri()函数\n");
    pipeline = gst_element_factory_make ("playbin", "player");
    if (file_name)
        g_object_set (G_OBJECT (pipeline), "uri",file_name, NULL);//file_name即要播放的 文件的uri 格式为"file:///home/1.mp3"
    {
        GstBus *bus;
        bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
        gst_bus_add_watch (bus, bus_call, NULL);
        gst_object_unref (bus);
    }
    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
    g_main_loop_run (loop);
    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
    gst_object_unref (GST_OBJECT (pipeline));
}

GdkPixbuf *create_pixbuf (const gchar * filename)
{
    g_print ("Splay>>>>导入程序图标..\n");
    GdkPixbuf *pixbuf;
    GError *error = NULL;
    pixbuf = gdk_pixbuf_new_from_file (filename, &error);
    if (!pixbuf) {
        g_print ("Splay>>>>程序图标导入好像有问题 ...\n");
        fprintf (stderr, "%s\n", error->message);
        g_error_free (error);
    }
    return pixbuf;
}

  评论这张
 
阅读(650)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018