ref: 4d4850f5de853099d2e2883057458ad48ccec477
parent: cc021be2f301154f53385861a13856a33aec05bb
author: menno <menno>
date: Sun Oct 17 16:44:51 EDT 2004
Updated XMMS plugin Adds song info window
--- a/plugins/xmms/src/libmp4.c
+++ b/plugins/xmms/src/libmp4.c
@@ -32,6 +32,7 @@
static void mp4_seek(int);
static int mp4_getTime(void);
static void mp4_cleanup(void);
+static void mp4_getSongTitle(char *, char **, int *);
static void mp4_getSongInfo(char *);
static int mp4_isFile(char *);
static void* mp4Decode(void *);
@@ -59,7 +60,7 @@
0, // send visualisation data
0, // set player window info
0, // set song title text
- 0, // get song title text
+ mp4_getSongTitle, // get song title text
mp4_getSongInfo, // info box
0, // to output plugin
};
@@ -77,8 +78,11 @@
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int seekPosition = -1;
-
+// Functions from mp4_utils.c
extern int getAACTrack(mp4ff_t *infile);
+extern mp4ff_callback_t *getMP4FF_cb(FILE *mp4file);
+extern char *getMP4title(mp4ff_t *infile, char *filename);
+extern void getMP4info(char* filename, FILE *mp4file);
InputPlugin *get_iplugin_info(void)
{
@@ -167,32 +171,77 @@
{
}
-static void mp4_getSongInfo(char *filename)
+void mp4_get_file_type(FILE *mp4file)
{
- if(mp4cfg.file_type == FILE_MP4)
- getMP4info(filename);
- else if(mp4cfg.file_type == FILE_AAC)
- /*
- * check the id3tagv2
- */
- ;
+ unsigned char header[10] = {0};
+
+ fseek(mp4file, 0, SEEK_SET);
+ fread(header, 1, 8, mp4file);
+ if(header[4]=='f' &&
+ header[5]=='t' &&
+ header[6]=='y' &&
+ header[7]=='p'){
+ mp4cfg.file_type = FILE_MP4;
+ }else{
+ mp4cfg.file_type = FILE_AAC;
+ }
}
-uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
-{
- return fread(buffer, 1, length, (FILE*)user_data);
+static void mp4_getSongTitle(char *filename, char **title, int *len) {
+ FILE* mp4file;
+
+ (*title) = NULL;
+ (*len) = -1;
+
+ if((mp4file = fopen(filename, "rb"))){
+ mp4_get_file_type(mp4file);
+ fseek(mp4file, 0, SEEK_SET);
+ if(mp4cfg.file_type == FILE_MP4){
+ mp4ff_callback_t* mp4cb;
+ mp4ff_t* infile;
+ gint mp4track;
+
+ mp4cb = getMP4FF_cb(mp4file);
+ if ((infile = mp4ff_open_read_metaonly(mp4cb)) &&
+ ((mp4track = getAACTrack(infile)) >= 0)){
+ (*title) = getMP4title(infile, filename);
+
+ double track_duration = mp4ff_get_track_duration(infile, mp4track);
+ unsigned long time_scale = mp4ff_time_scale(infile, mp4track);
+ unsigned long length = (track_duration * 1000 / time_scale);
+ (*len) = length;
+ }
+ if(infile) mp4ff_close(infile);
+ if(mp4cb) g_free(mp4cb);
+ }
+ else{
+ // Check AAC ID3 tag...
+ }
+ fclose(mp4file);
+ }
}
-uint32_t seek_callback(void *user_data, uint64_t position)
+static void mp4_getSongInfo(char *filename)
{
- return fseek((FILE*)user_data, position, SEEK_SET);
+ FILE* mp4file;
+ if((mp4file = fopen(filename, "rb"))){
+ if (mp4cfg.file_type == FILE_UNKNOW)
+ mp4_get_file_type(mp4file);
+ fseek(mp4file, 0, SEEK_SET);
+ if(mp4cfg.file_type == FILE_MP4)
+ getMP4info(filename, mp4file);
+ else if(mp4cfg.file_type == FILE_AAC)
+ /*
+ * check the id3tagv2
+ */
+ ;
+ fclose(mp4file);
+ }
}
-
static void *mp4Decode(void *args)
{
FILE* mp4file;
- unsigned char header[10] = {0};
pthread_mutex_lock(&mutex);
seekPosition = -1;
@@ -206,26 +255,17 @@
pthread_exit(NULL);
}
- fread(header, 1, 8, mp4file);
- if(header[4]=='f' &&
- header[5]=='t' &&
- header[6]=='y' &&
- header[7]=='p'){
- mp4cfg.file_type = FILE_MP4;
- }else{
- mp4cfg.file_type = FILE_AAC;
- }
- fseek(mp4file, SEEK_SET, 0);
+ mp4_get_file_type(mp4file);
+ fseek(mp4file, 0, SEEK_SET);
if(mp4cfg.file_type == FILE_MP4){// We are reading a MP4 file
+ mp4ff_callback_t* mp4cb;
mp4ff_t* infile;
gint mp4track;
- mp4ff_callback_t* mp4cb = malloc(sizeof(mp4ff_callback_t));
- mp4cb->read = read_callback;
- mp4cb->seek = seek_callback;
- mp4cb->user_data = mp4file;
+ mp4cb = getMP4FF_cb(mp4file);
if(!(infile = mp4ff_open_read(mp4cb))){
g_print("MP4 - Can't open file\n");
+ goto end;
}
if((mp4track = getAACTrack(infile)) < 0){
@@ -245,7 +285,7 @@
guint bufferSize = 0;
gulong samplerate;
guchar channels;
- guint avgBitrate;
+ //guint avgBitrate;
//MP4Duration duration;
int msDuration;
int numSamples;
@@ -252,6 +292,7 @@
int sampleID = 0;
unsigned int framesize;
mp4AudioSpecificConfig mp4ASC;
+ gchar *xmmstitle;
decoder = NeAACDecOpen();
mp4ff_get_decoder_config(infile, mp4track, &buffer, &bufferSize);
@@ -287,10 +328,11 @@
msDuration = ((float)numSamples*(float)(f-1.0)/
(float)samplerate)*1000;
}
+ xmmstitle = getMP4title(infile, args);
mp4_ip.output->open_audio(FMT_S16_NE, samplerate, channels);
mp4_ip.output->flush(0);
- mp4_ip.set_info(args, msDuration, -1, samplerate/1000, channels);
- g_print("MP4 - %d channels @ %d Hz\n", channels, samplerate);
+ mp4_ip.set_info(xmmstitle, msDuration, -1, samplerate/1000, channels);
+ g_print("MP4 - %d channels @ %ld Hz\n", channels, samplerate);
while(bPlaying){
void* sampleBuffer;
@@ -304,9 +346,13 @@
seekPosition*1000,
MP4_MSECS_TIME_SCALE);
sampleID = MP4GetSampleIdFromTime(mp4file, mp4track, duration, 0);
+ */
+ float f = 1024.0;
+ if(mp4ASC.sbr_present_flag == 1)
+ f = f * 2.0;
+ sampleID = (float)seekPosition*(float)samplerate/(float)(f-1.0);
mp4_ip.output->flush(seekPosition*1000);
seekPosition = -1;
- */
}
buffer=NULL;
bufferSize=0;
@@ -349,7 +395,7 @@
mp4_ip.output->close_audio();
g_free(args);
NeAACDecClose(decoder);
- mp4ff_close(infile);
+ if(infile) mp4ff_close(infile);
if(mp4cb) g_free(mp4cb);
bPlaying = FALSE;
fclose(mp4file);
--- a/plugins/xmms/src/mp4_utils.c
+++ b/plugins/xmms/src/mp4_utils.c
@@ -5,7 +5,14 @@
#include "mp4ff.h"
#include "faad.h"
+#include <gtk/gtk.h>
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <xmms/plugin.h>
+#include <xmms/titlestring.h>
+#include <xmms/util.h>
+
const char *mp4AudioNames[]=
{
"MPEG-1 Audio Layers 1,2 or 3",
@@ -35,6 +42,8 @@
"MPEG-4 Algorithmic Synthesis and Audio FX profile"
};
+static GtkWidget *mp4_info_dialog = NULL;
+
/*
* find AAC track
*/
@@ -54,7 +63,7 @@
mp4ff_get_decoder_config(infile, i, &buff, &buff_size);
if(buff){
rc = NeAACDecAudioSpecificConfig(buff, buff_size, &mp4ASC);
- free(buff);
+ g_free(buff);
if(rc < 0)
continue;
return(i);
@@ -63,47 +72,398 @@
return(-1);
}
+uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
+{
+ return fread(buffer, 1, length, (FILE*)user_data);
+}
-void getMP4info(char* file)
+uint32_t seek_callback(void *user_data, uint64_t position)
{
- /*
- MP4FileHandle mp4file;
- MP4Duration trackDuration;
- int numTracks;
- int i=0;
+ return fseek((FILE*)user_data, position, SEEK_SET);
+}
- if(!(mp4file = MP4Read(file,0)))
- return;
- //MP4Dump(mp4file, 0, 0);
- numTracks = MP4GetNumberOfTracks(mp4file, NULL, 0);
- g_print("there are %d track(s)\n", numTracks);
- for(i=0;i<numTracks;i++){
- MP4TrackId trackID = MP4FindTrackId(mp4file, i, NULL, 0);
- const char *trackType = MP4GetTrackType(mp4file, trackID);
- printf("Track %d, %s", trackID, trackType);
- if(!strcmp(trackType, MP4_AUDIO_TRACK_TYPE)){//we found audio track !
- int j=0;
- u_int8_t audiotype = MP4GetTrackAudioType(mp4file, trackID);
- while(mp4AudioTypes[j]){ // what kind of audio is ?
- if(mp4AudioTypes[j] == audiotype){
- if(mp4AudioTypes[j] == MP4_MPEG4_AUDIO_TYPE){
- audiotype = MP4GetTrackAudioMpeg4Type(mp4file, trackID);
- g_print(" %s", mpeg4AudioNames[audiotype]);
- }
- else{
- printf(" %s", mp4AudioNames[j]);
- }
- g_print(" duration :%d",
- MP4ConvertFromTrackDuration(mp4file, trackID,
- MP4GetTrackDuration(mp4file,
- trackID),
- MP4_MSECS_TIME_SCALE));
- }
- j++;
- }
+mp4ff_callback_t *getMP4FF_cb(FILE *mp4file)
+{
+ mp4ff_callback_t* mp4cb = malloc(sizeof(mp4ff_callback_t));
+ mp4cb->read = read_callback;
+ mp4cb->seek = seek_callback;
+ mp4cb->user_data = mp4file;
+ return mp4cb;
+}
+
+/*
+ * Function to display an info box for an mp4 file.
+ * This code is based heavily on fileinfo.c from the xmms mpg123
+ * plugin, and the info box layout mimics that plugin.
+*/
+void create_mp4_info_dialog (char *filename, FILE *mp4file, mp4ff_t *infile, gint mp4track)
+{
+ char *window_title, *value, *value2;
+ static GtkWidget *filename_entry, *title_entry, *artist_entry, *album_entry;
+ static GtkWidget *genre_entry, *year_entry, *track_entry, *comment_entry;
+ static GtkWidget *mp4_info_label;
+
+ if (!mp4_info_dialog)
+ {
+ GtkWidget *dialog_vbox1, *vbox1, *hbox2, *hbox3, *hbox4;
+ GtkWidget *frame2, *frame3, *table1, *dialog_action_area1;
+ GtkWidget *filename_label, *title_label, *artist_label, *album_label;
+ GtkWidget *genre_label, *year_label, *track_label, *comment_label;
+ GtkWidget *close_button;
+
+ mp4_info_dialog = gtk_dialog_new ();
+ gtk_object_set_data (GTK_OBJECT (mp4_info_dialog), "mp4_info_dialog", mp4_info_dialog);
+ gtk_window_set_policy (GTK_WINDOW (mp4_info_dialog), TRUE, TRUE, FALSE);
+ gtk_signal_connect(GTK_OBJECT (mp4_info_dialog), "destroy",
+ gtk_widget_destroyed, &mp4_info_dialog);
+
+ dialog_vbox1 = GTK_DIALOG (mp4_info_dialog)->vbox;
+ gtk_object_set_data (GTK_OBJECT (mp4_info_dialog), "dialog_vbox1", dialog_vbox1);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog_vbox1), 3);
+
+ hbox2 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_ref (hbox2);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "hbox2", hbox2,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox1), hbox2, FALSE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox2), 3);
+
+ filename_label = gtk_label_new ("Filename: ");
+ gtk_widget_ref (filename_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "filename_label", filename_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox2), filename_label, FALSE, FALSE, 0);
+
+ filename_entry = gtk_entry_new ();
+ gtk_widget_ref (filename_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "filename_entry", filename_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox2), filename_entry, TRUE, TRUE, 0);
+ gtk_entry_set_editable (GTK_ENTRY (filename_entry), FALSE);
+
+ hbox3 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_ref (hbox3);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "hbox3", hbox3,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (dialog_vbox1), hbox3, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox3), 3);
+
+ frame2 = gtk_frame_new ("Tag Info: ");
+ gtk_widget_ref (frame2);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "frame2", frame2,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox3), frame2, TRUE, TRUE, 0);
+
+ table1 = gtk_table_new (6, 2, FALSE);
+ gtk_widget_ref (table1);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "table1", table1,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add (GTK_CONTAINER (frame2), table1);
+ gtk_container_set_border_width (GTK_CONTAINER (table1), 5);
+
+ comment_label = gtk_label_new ("Comment: ");
+ gtk_widget_ref (comment_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "comment_label", comment_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), comment_label, 0, 1, 5, 6,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (comment_label), 1, 0.5);
+
+ genre_label = gtk_label_new ("Genre: ");
+ gtk_widget_ref (genre_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "genre_label", genre_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), genre_label, 0, 1, 4, 5,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (genre_label), 1, 0.5);
+
+ album_label = gtk_label_new ("Album: ");
+ gtk_widget_ref (album_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "album_label", album_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), album_label, 0, 1, 2, 3,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (album_label), 1, 0.5);
+
+ title_label = gtk_label_new ("Title: ");
+ gtk_widget_ref (title_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "title_label", title_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), title_label, 0, 1, 0, 1,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (title_label), 1, 0.5);
+
+ artist_label = gtk_label_new ("Artist: ");
+ gtk_widget_ref (artist_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "artist_label", artist_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), artist_label, 0, 1, 1, 2,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (artist_label), 1, 0.5);
+
+ year_label = gtk_label_new ("Year: ");
+ gtk_widget_ref (year_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "year_label", year_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), year_label, 0, 1, 3, 4,
+ (GtkAttachOptions) (GTK_FILL),
+ (GtkAttachOptions) (GTK_EXPAND), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (year_label), 1, 0.5);
+
+ hbox4 = gtk_hbox_new (FALSE, 0);
+ gtk_widget_ref (hbox4);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "hbox4", hbox4,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), hbox4, 1, 2, 3, 4,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (GTK_FILL), 0, 0);
+
+ year_entry = gtk_entry_new ();
+ gtk_widget_ref (year_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "year_entry", year_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox4), year_entry, FALSE, FALSE, 0);
+ gtk_widget_set_usize (year_entry, 60, -2);
+ gtk_entry_set_editable (GTK_ENTRY (year_entry), FALSE);
+
+ track_label = gtk_label_new (" Track: ");
+ gtk_widget_ref (track_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "track_label", track_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox4), track_label, FALSE, FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (track_label), 1, 0.5);
+
+ track_entry = gtk_entry_new ();
+ gtk_widget_ref (track_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "track_entry", track_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox4), track_entry, FALSE, FALSE, 0);
+ gtk_widget_set_usize (track_entry, 60, -2);
+ gtk_entry_set_editable (GTK_ENTRY (track_entry), FALSE);
+
+ title_entry = gtk_entry_new ();
+ gtk_widget_ref (title_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "title_entry", title_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), title_entry, 1, 2, 0, 1,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_editable (GTK_ENTRY (title_entry), FALSE);
+
+ artist_entry = gtk_entry_new ();
+ gtk_widget_ref (artist_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "artist_entry", artist_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), artist_entry, 1, 2, 1, 2,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_editable (GTK_ENTRY (artist_entry), FALSE);
+
+ album_entry = gtk_entry_new ();
+ gtk_widget_ref (album_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "album_entry", album_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), album_entry, 1, 2, 2, 3,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_editable (GTK_ENTRY (album_entry), FALSE);
+
+ genre_entry = gtk_entry_new ();
+ gtk_widget_ref (genre_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "genre_entry", genre_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), genre_entry, 1, 2, 4, 5,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_editable (GTK_ENTRY (genre_entry), FALSE);
+
+ comment_entry = gtk_entry_new ();
+ gtk_widget_ref (comment_entry);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "comment_entry", comment_entry,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_table_attach (GTK_TABLE (table1), comment_entry, 1, 2, 5, 6,
+ (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+ (GtkAttachOptions) (0), 0, 0);
+ gtk_entry_set_editable (GTK_ENTRY (comment_entry), FALSE);
+
+ frame3 = gtk_frame_new ("MP4 Info: ");
+ gtk_widget_ref (frame3);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "frame3", frame3,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (hbox3), frame3, FALSE, TRUE, 0);
+
+ vbox1 = gtk_vbox_new (FALSE, 0);
+ gtk_widget_ref (vbox1);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "vbox1", vbox1,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_container_add (GTK_CONTAINER (frame3), vbox1);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5);
+
+ mp4_info_label = gtk_label_new ("");
+ gtk_widget_ref (mp4_info_label);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "mp4_info_label", mp4_info_label,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (vbox1), mp4_info_label, TRUE, TRUE, 0);
+ gtk_label_set_justify (GTK_LABEL (mp4_info_label), GTK_JUSTIFY_LEFT);
+ gtk_misc_set_alignment (GTK_MISC (mp4_info_label), 0, 0);
+
+ dialog_action_area1 = GTK_DIALOG (mp4_info_dialog)->action_area;
+ gtk_object_set_data (GTK_OBJECT (mp4_info_dialog), "dialog_action_area1", dialog_action_area1);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area1), 4);
+
+ close_button = gtk_button_new_with_label ("Close");
+ gtk_widget_ref (close_button);
+ gtk_object_set_data_full (GTK_OBJECT (mp4_info_dialog), "close_button", close_button,
+ (GtkDestroyNotify) gtk_widget_unref);
+ gtk_box_pack_start (GTK_BOX (dialog_action_area1), close_button, FALSE, FALSE, 0);
+
+ gtk_signal_connect_object (GTK_OBJECT (close_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_widget_destroy), GTK_OBJECT (mp4_info_dialog));
+
+ }
+
+ window_title = g_strdup_printf("File Info - %s", g_basename(filename));
+ gtk_window_set_title (GTK_WINDOW (mp4_info_dialog), window_title);
+ g_free(window_title);
+
+ gtk_entry_set_text (GTK_ENTRY (filename_entry), filename);
+
+ gtk_entry_set_text (GTK_ENTRY (title_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (artist_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (album_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (year_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (track_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (genre_entry), "");
+ gtk_entry_set_text (GTK_ENTRY (comment_entry), "");
+
+ if ((mp4ff_meta_get_title(infile, &value)) && value != NULL) {
+ gtk_entry_set_text (GTK_ENTRY(title_entry), value);
+ g_free(value);
+ }
+ if ((mp4ff_meta_get_artist(infile, &value)) && value != NULL) {
+ gtk_entry_set_text (GTK_ENTRY(artist_entry), value);
+ g_free(value);
+ }
+ if ((mp4ff_meta_get_album(infile, &value)) && value != NULL) {
+ gtk_entry_set_text (GTK_ENTRY(album_entry), value);
+ g_free(value);
+ }
+ if ((mp4ff_meta_get_date(infile, &value)) && value != NULL) {
+ gtk_entry_set_text (GTK_ENTRY(year_entry), value);
+ g_free(value);
+ }
+ if ((mp4ff_meta_get_track(infile, &value)) && value != NULL) {
+ if ((mp4ff_meta_get_totaltracks(infile, &value2)) && value2 != NULL) {
+ char *tmp = g_strdup_printf("%s of %s", value, value2);
+ g_free(value2);
+ g_free(value);
+ value = tmp;
}
- printf("\n");
+ gtk_entry_set_text (GTK_ENTRY(track_entry), value);
+ g_free(value);
}
- MP4Close(mp4file);
- */
+ if ((mp4ff_meta_get_genre(infile, &value)) && value != NULL) {
+ gtk_entry_set_text (GTK_ENTRY(genre_entry), value);
+ g_free(value);
+ }
+ if ((mp4ff_meta_get_comment(infile, &value)) && value != NULL) {
+ gtk_entry_set_text (GTK_ENTRY(comment_entry), value);
+ g_free(value);
+ }
+
+ // Get the length of the track.
+ double track_duration = mp4ff_get_track_duration(infile, mp4track);
+ unsigned long time_scale = mp4ff_time_scale(infile, mp4track);
+ unsigned long length = (track_duration / time_scale);
+ int min = length / 60;
+ int sec = length % 60;
+
+ // Get other info about the track.
+ unsigned long bitrate = mp4ff_get_avg_bitrate(infile, mp4track) / 1000;
+ unsigned long samplerate = mp4ff_get_sample_rate(infile, mp4track);
+ unsigned long channels = mp4ff_get_channel_count(infile, mp4track);
+ unsigned long audio_type = mp4ff_get_audio_type(infile, mp4track);
+ fseek(mp4file, 0, SEEK_END);
+ int filesize = ftell(mp4file) / 1024;
+
+ value = g_strdup_printf("Length: %d:%d\nAvg. Bitrate: %ld kbps\nSample Rate: %ld Hz\nChannels: %ld\nAudio Type: %ld\nFile Size: %d KB", min, sec, bitrate, samplerate, channels, audio_type, filesize);
+ gtk_label_set_text (GTK_LABEL(mp4_info_label), value);
+ g_free(value);
+
+ gtk_widget_show_all(mp4_info_dialog);
+}
+
+
+void getMP4info(char* filename, FILE* mp4file)
+{
+ mp4ff_callback_t* mp4cb;
+ mp4ff_t* infile;
+ gint mp4track;
+
+ mp4cb = getMP4FF_cb(mp4file);
+ if ((infile = mp4ff_open_read_metaonly(mp4cb)) &&
+ ((mp4track = getAACTrack(infile)) >= 0)){
+ create_mp4_info_dialog (filename, mp4file, infile, mp4track);
+ }
+ if(infile) mp4ff_close(infile);
+ if(mp4cb) g_free(mp4cb);
+}
+
+/* Get the xmms titlestring for the file based on metadata.
+The following code was adapted from the gtkpod project, specifically
+mp4file.c (C) Jorg Schuler, but written to use the mp4ff library. The
+mpg123 input plugin for xmms was used as a guide for this function.
+ --Jason Arroyo, 2004 */
+char *getMP4title(mp4ff_t *infile, char *filename) {
+ char *ret=NULL;
+ gchar *value, *path, *temp;
+
+ TitleInput *input;
+ XMMS_NEW_TITLEINPUT(input);
+
+ // Fill in the TitleInput with the relevant data
+ // from the mp4 file that can be used to display the title.
+ mp4ff_meta_get_title(infile, &input->track_name);
+ mp4ff_meta_get_artist(infile, &input->performer);
+ mp4ff_meta_get_album(infile, &input->album_name);
+ if (mp4ff_meta_get_track(infile, &value) && value != NULL) {
+ input->track_number = atoi(value);
+ g_free(value);
+ }
+ if (mp4ff_meta_get_date(infile, &value) && value != NULL) {
+ input->year = atoi(value);
+ g_free(value);
+ }
+ mp4ff_meta_get_genre(infile, &input->genre);
+ mp4ff_meta_get_comment(infile, &input->comment);
+ input->file_name = g_strdup(g_basename(filename));
+ path = g_strdup(filename);
+ temp = strrchr(path, '.');
+ if (temp != NULL) {++temp;}
+ input->file_ext = g_strdup_printf("%s", temp);
+ temp = strrchr(path, '/');
+ if (temp) {*temp = '\0';}
+ input->file_path = g_strdup_printf("%s/", path);
+
+ // Use the default xmms title format to format the
+ // title from the above info.
+ ret = xmms_get_titlestring(xmms_get_gentitle_format(), input);
+
+ g_free(input->track_name);
+ g_free(input->performer);
+ g_free(input->album_name);
+ g_free(input->genre);
+ g_free(input->comment);
+ g_free(input->file_name);
+ g_free(input->file_ext);
+ g_free(input->file_path);
+ g_free(input);
+ g_free(path);
+
+ return ret;
}