diff options
author | Radek Doulik <rodo@ximian.com> | 2004-10-25 20:19:05 +0800 |
---|---|---|
committer | Radek Doulik <rodo@src.gnome.org> | 2004-10-25 20:19:05 +0800 |
commit | de21f75ccf3eeff05a874b02a5221d003134f15c (patch) | |
tree | cc5bbff35aaaaa6a4c1053dfb10ce78afc24cb2d /plugins | |
parent | 0ea79651b85c4acdb49ddd6b5c9bc0c021e977e3 (diff) | |
download | gsoc2013-evolution-de21f75ccf3eeff05a874b02a5221d003134f15c.tar.gz gsoc2013-evolution-de21f75ccf3eeff05a874b02a5221d003134f15c.tar.zst gsoc2013-evolution-de21f75ccf3eeff05a874b02a5221d003134f15c.zip |
imported audio inline plugin
2004-10-25 Radek Doulik <rodo@ximian.com>
* audio-inline.c: imported audio inline plugin
svn path=/trunk/; revision=27714
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/audio-inline/ChangeLog | 4 | ||||
-rw-r--r-- | plugins/audio-inline/Makefile.am | 13 | ||||
-rw-r--r-- | plugins/audio-inline/audio-inline.c | 290 | ||||
-rw-r--r-- | plugins/audio-inline/org-gnome-audio-inline.eplug.in | 19 |
4 files changed, 326 insertions, 0 deletions
diff --git a/plugins/audio-inline/ChangeLog b/plugins/audio-inline/ChangeLog new file mode 100644 index 0000000000..f7eb2cd666 --- /dev/null +++ b/plugins/audio-inline/ChangeLog @@ -0,0 +1,4 @@ +2004-10-25 Radek Doulik <rodo@ximian.com> + + * audio-inline.c: imported audio inline plugin + diff --git a/plugins/audio-inline/Makefile.am b/plugins/audio-inline/Makefile.am new file mode 100644 index 0000000000..ffb8d8ddab --- /dev/null +++ b/plugins/audio-inline/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = \ + -I$(top_srcdir) \ + $(EVOLUTION_MAIL_CFLAGS) \ + $(GSTREAMER_CFLAGS) + +@EVO_PLUGIN_RULE@ + +plugin_DATA = org-gnome-audio-inline.eplug +plugin_LTLIBRARIES = liborg-gnome-audio-inline.la + +liborg_gnome_audio_inline_la_SOURCES = audio-inline.c +liborg_gnome_audio_inline_la_LDFLAGS = -module -avoid-version +liborg_gnome_audio_inline_la_LIBADD = $(GSTREAMER_LIBS) diff --git a/plugins/audio-inline/audio-inline.c b/plugins/audio-inline/audio-inline.c new file mode 100644 index 0000000000..f2264b230b --- /dev/null +++ b/plugins/audio-inline/audio-inline.c @@ -0,0 +1,290 @@ +/* + Copyright (C) 2004 Novell, Inc. + Author: Radek Doulik + + */ + +/* This file is licensed under the GNU GPL v2 or later */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> /* for unlink */ +#include <string.h> +#include "e-util/e-icon-factory.h" +#include "e-util/e-mktemp.h" +#include "camel/camel-medium.h" +#include "camel/camel-mime-part.h" +#include "camel/camel-stream.h" +#include "camel/camel-stream-fs.h" +#include "mail/em-format-hook.h" +#include "mail/em-format-html.h" +#include "gtk/gtkbutton.h" +#include "gtk/gtkbox.h" +#include "gtk/gtkimage.h" +#include "gtk/gtkhbbox.h" +#include "gtkhtml/gtkhtml-embedded.h" +#include "gst/gst.h" + +#define d(x) x + +void org_gnome_audio_inline_format (void *ep, EMFormatHookTarget *t); + +volatile static int org_gnome_audio_class_id_counter = 0; + +enum _org_gnome_audio_inline_button_type { + ORG_GNOME_AUDIO_INLINE_BUTTON_PLAY, + ORG_GNOME_AUDIO_INLINE_BUTTON_PAUSE, + ORG_GNOME_AUDIO_INLINE_BUTTON_STOP +}; + +struct _org_gnome_audio_inline_pobject { + EMFormatHTMLPObject object; + + CamelMimePart *part; + char *filename; + GstElement *thread; +}; + +static void +org_gnome_audio_inline_pobject_free (EMFormatHTMLPObject *o) +{ + struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) o; + + d(printf ("audio inline formatter: pobject free\n")); + + if (po->part) { + camel_object_unref (po->part); + po->part = NULL; + } + if (po->filename) { + unlink (po->filename); + g_free (po->filename); + po->filename = NULL; + } + if (po->thread) { + gst_element_set_state (po->thread, GST_STATE_NULL); + gst_object_unref (GST_OBJECT (po->thread)); + po->thread = NULL; + } +} + +static void +org_gnome_audio_inline_pause_clicked (GtkWidget *button, EMFormatHTMLPObject *pobject) +{ + struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + + if (po->thread) { + /* start playing */ + gst_element_set_state (po->thread, GST_STATE_PAUSED); + } +} + +static void +org_gnome_audio_inline_stop_clicked (GtkWidget *button, EMFormatHTMLPObject *pobject) +{ + struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + + if (po->thread) { + /* start playing */ + gst_element_set_state (po->thread, GST_STATE_READY); + } +} + +static GstElement * +org_gnome_audio_inline_gst_mpeg_thread (GstElement *filesrc) +{ + GstElement *thread, *decoder, *audiosink; + + /* create a new thread to hold the elements */ + thread = gst_thread_new ("org-gnome-audio-inline-mpeg-thread"); + + /* now it's time to get the decoder */ + decoder = gst_element_factory_make ("mad", "decoder"); + + /* and an audio sink */ + audiosink = gst_element_factory_make ("osssink", "play_audio"); + + /* add objects to the main pipeline */ + gst_bin_add_many (GST_BIN (thread), filesrc, decoder, audiosink, NULL); + + /* link src to sink */ + gst_element_link_many (filesrc, decoder, audiosink, NULL); + + return thread; +} + +static GstElement * +org_gnome_audio_inline_gst_ogg_thread (GstElement *filesrc) +{ + GstElement *thread, *demuxer, *decoder, *converter, *audiosink; + + /* create a new thread to hold the elements */ + thread = gst_thread_new ("org-gnome-audio-inline-mpeg-thread"); + + /* create an ogg demuxer */ + demuxer = gst_element_factory_make ("oggdemux", "demuxer"); + g_assert (demuxer != NULL); + + /* create a vorbis decoder */ + decoder = gst_element_factory_make ("vorbisdec", "decoder"); + g_assert (decoder != NULL); + + /* create an audio converter */ + converter = gst_element_factory_make ("audioconvert", "converter"); + g_assert (decoder != NULL); + + /* and an audio sink */ + audiosink = gst_element_factory_make ("osssink", "play_audio"); + g_assert (audiosink != NULL); + + /* add objects to the thread */ + gst_bin_add_many (GST_BIN (thread), filesrc, demuxer, decoder, converter, audiosink, NULL); + /* link them in the logical order */ + gst_element_link_many (filesrc, demuxer, decoder, converter, audiosink, NULL); + + return thread; +} + +static GstElement * +org_gnome_audio_inline_gst_flac_thread (GstElement *filesrc) +{ + GstElement *thread, *decoder, *audiosink; + + /* create a new thread to hold the elements */ + thread = gst_thread_new ("org-gnome-audio-inline-flac-thread"); + + /* now it's time to get the decoder */ + decoder = gst_element_factory_make ("flacdec", "decoder"); + + /* and an audio sink */ + audiosink = gst_element_factory_make ("osssink", "play_audio"); + + /* add objects to the main pipeline */ + gst_bin_add_many (GST_BIN (thread), filesrc, decoder, audiosink, NULL); + + /* link src to sink */ + gst_element_link_many (filesrc, decoder, audiosink, NULL); + + return thread; +} + +static void +org_gnome_audio_inline_play_clicked (GtkWidget *button, EMFormatHTMLPObject *pobject) +{ + struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + + d(printf ("audio inline formatter: play\n")); + + if (!po->filename) { + CamelStream *stream; + CamelDataWrapper *data; + int argc = 1; + char *argv [] = { "org_gnome_audio_inline", NULL }; + + po->filename = e_mktemp ("org-gnome-audio-inline-file-XXXXXX"); + + d(printf ("audio inline formatter: write to temp file %s\n", po->filename)); + + stream = camel_stream_fs_new_with_name (po->filename, O_RDWR | O_CREAT | O_TRUNC, 0600); + data = camel_medium_get_content_object (CAMEL_MEDIUM (po->part)); + camel_data_wrapper_decode_to_stream (data, stream); + camel_stream_flush (stream); + camel_object_unref (stream); + + d(printf ("audio inline formatter: init gst thread\n")); + + if (gst_init_check (&argc, &argv)) { + CamelContentType *type; + GstElement *filesrc; + + /* create a disk reader */ + filesrc = gst_element_factory_make ("filesrc", "disk_source"); + g_object_set (G_OBJECT (filesrc), "location", po->filename, NULL); + + type = camel_mime_part_get_content_type (po->part); + if (type) { + if (!strcasecmp (type->type, "audio")) { + if (!strcasecmp (type->subtype, "mpeg")) { + po->thread = org_gnome_audio_inline_gst_mpeg_thread (filesrc); + } else if (!strcasecmp (type->subtype, "x-flac")) { + po->thread = org_gnome_audio_inline_gst_flac_thread (filesrc); + } + } else if (!strcasecmp (type->type, "application")) { + if (!strcasecmp (type->subtype, "ogg")) { + po->thread = org_gnome_audio_inline_gst_ogg_thread (filesrc); + } + } + } + } + } + + if (po->thread) { + /* start playing */ + gst_element_set_state (po->thread, GST_STATE_PLAYING); + + /* do whatever you want here, the thread will be playing */ + g_print ("thread is playing\n"); + } +} + +static void +org_gnome_audio_inline_add_button (GtkWidget *box, char *icon_name, GCallback cb, gpointer data) +{ + GtkWidget *icon, *button; + GdkPixbuf *pixbuf; + + pixbuf = e_icon_factory_get_icon (icon_name, E_ICON_SIZE_LARGE_TOOLBAR); + + icon = gtk_image_new_from_pixbuf (pixbuf); + g_object_unref (pixbuf); + gtk_widget_show (icon); + + button = gtk_button_new (); + g_signal_connect (button, "clicked", cb, data); + + gtk_container_add ((GtkContainer *) button, icon); + gtk_widget_show (button); + gtk_box_pack_end_defaults (GTK_BOX (box), button); +} + +static gboolean +org_gnome_audio_inline_button_panel (EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject) +{ + GtkWidget *box; + struct _org_gnome_audio_inline_pobject *po = (struct _org_gnome_audio_inline_pobject *) pobject; + + /* it is OK to call UI functions here, since we are called from UI thread */ + + box = gtk_hbutton_box_new (); + org_gnome_audio_inline_add_button (box, "stock_media-play", G_CALLBACK (org_gnome_audio_inline_play_clicked), po); + org_gnome_audio_inline_add_button (box, "stock_media-pause", G_CALLBACK (org_gnome_audio_inline_pause_clicked), po); + org_gnome_audio_inline_add_button (box, "stock_media-stop", G_CALLBACK (org_gnome_audio_inline_stop_clicked), po); + + gtk_widget_show (box); + gtk_container_add ((GtkContainer *) eb, box); + + return TRUE; +} + +void +org_gnome_audio_inline_format (void *ep, EMFormatHookTarget *t) +{ + struct _org_gnome_audio_inline_pobject *pobj; + char *classid = g_strdup_printf ("org-gnome-audio-inline-button-panel-%d", org_gnome_audio_class_id_counter); + + org_gnome_audio_class_id_counter ++; + + d(printf ("audio inline formatter: format classid %s\n", classid)); + + pobj = (struct _org_gnome_audio_inline_pobject *) em_format_html_add_pobject ((EMFormatHTML *) t->format, sizeof(*pobj), classid, + t->part, org_gnome_audio_inline_button_panel); + camel_object_ref (t->part); + pobj->part = t->part; + pobj->filename = NULL; + pobj->thread = NULL; + pobj->object.free = org_gnome_audio_inline_pobject_free; + + camel_stream_printf (t->stream, "<object classid=%s></object>\n", classid); +} diff --git a/plugins/audio-inline/org-gnome-audio-inline.eplug.in b/plugins/audio-inline/org-gnome-audio-inline.eplug.in new file mode 100644 index 0000000000..d61bf70538 --- /dev/null +++ b/plugins/audio-inline/org-gnome-audio-inline.eplug.in @@ -0,0 +1,19 @@ +<?xml version="1.0"?> +<e-plugin-list> + <e-plugin + type="shlib" + id="org.gnome.evolution.plugin.audioInline" + location="@PLUGINDIR@/liborg-gnome-audio-inline.la" + name="Audio inline plugin" + description="A formatter plugin which displays audio attachments inline and allows you to play them directly from evolution"> + + <hook class="org.gnome.evolution.mail.format:1.0"> + <group id="EMFormatHTMLDisplay"> + <item mime_type="audio/mpeg" format="org_gnome_audio_inline_format" flags="inline_disposition"/> + <item mime_type="audio/x-flac" format="org_gnome_audio_inline_format" flags="inline_disposition"/> + <item mime_type="application/ogg" format="org_gnome_audio_inline_format" flags="inline_disposition"/> + </group> + </hook> + + </e-plugin> +</e-plugin-list> |