📄 libmp4.c
字号:
/* * MP4/AAC decoder for xmms * * OPTIONNAL need * -------------- * libid3 (3.8.x - www.id3.org)*/#include <pthread.h>#include <gtk/gtk.h>#include <stdio.h>#include <string.h>#if defined(HAVE_BMP)#include <bmp/plugin.h>#include <bmp/util.h>#include <bmp/configfile.h>#include <bmp/titlestring.h>#else#include <xmms/plugin.h>#include <xmms/util.h>#include <xmms/configfile.h>#include <xmms/titlestring.h>#endif /*HAVE_BMP*/#include "neaacdec.h"#include "mp4ff.h"#define MP4_DESCRIPTION "MP4 & MPEG2/4-AAC audio player - 1.2.x"#define MP4_VERSION "ver. 0.5-faad2-version - 22 August 2004"#define MP4_ABOUT "Written by ciberfred"#define BUFFER_SIZE FAAD_MIN_STREAMSIZE*64static void mp4_init(void);static void mp4_about(void);static void mp4_play(char *);static void mp4_stop(void);static void mp4_pause(short);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 *);InputPlugin mp4_ip = { 0, // handle 0, // filename MP4_DESCRIPTION, mp4_init, mp4_about, 0, // configuration mp4_isFile, 0, //scandir mp4_play, mp4_stop, mp4_pause, mp4_seek, 0, // set equalizer mp4_getTime, 0, // get volume 0, mp4_cleanup, 0, // obsolete 0, // send visualisation data 0, // set player window info 0, // set song title text mp4_getSongTitle, // get song title text mp4_getSongInfo, // info box 0, // to output plugin };typedef struct _mp4cfg{ gshort file_type;#define FILE_UNKNOW 0#define FILE_MP4 1#define FILE_AAC 2} Mp4Config;static Mp4Config mp4cfg;static gboolean bPlaying = FALSE;static pthread_t decodeThread;static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;static int seekPosition = -1;// Functions from mp4_utils.cextern 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){ return(&mp4_ip);}static void mp4_init(void){ memset(&decodeThread, 0, sizeof(pthread_t)); mp4cfg.file_type = FILE_UNKNOW; seekPosition = -1; return;}static void mp4_play(char *filename){ bPlaying = TRUE; pthread_create(&decodeThread, 0, mp4Decode, g_strdup(filename)); return;}static void mp4_stop(void){ if(bPlaying){ bPlaying = FALSE; pthread_join(decodeThread, NULL); memset(&decodeThread, 0, sizeof(pthread_t)); mp4_ip.output->close_audio(); }}static int mp4_isFile(char *filename){ if(filename){ gchar* extention; extention = strrchr(filename, '.'); if(extention && (!strncasecmp(extention, ".mp4", 4) || // official extention !strncasecmp(extention, ".m4a", 4) || // Apple mp4 extention !strncasecmp(extention, ".aac", 4) // old MPEG2/4-AAC extention )){ return (1); } } return(0);}static void mp4_about(void){ static GtkWidget *aboutbox; if(aboutbox!=NULL) return; aboutbox = xmms_show_message("About MP4 AAC player plugin", "libfaad2-" FAAD2_VERSION "\n" "plugin version: " MP4_VERSION "\n" MP4_ABOUT, "Ok", FALSE, NULL, NULL); gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &aboutbox);}static void mp4_pause(short flag){ mp4_ip.output->pause(flag);}static void mp4_seek(int time){ seekPosition = time; while(bPlaying && seekPosition!=-1) xmms_usleep(10000);}static int mp4_getTime(void){ if(!bPlaying) return (-1); else return (mp4_ip.output->output_time());}static void mp4_cleanup(void){}void mp4_get_file_type(FILE *mp4file){ 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; }}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); }}static void mp4_getSongInfo(char *filename){ 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; pthread_mutex_lock(&mutex); seekPosition = -1; bPlaying = TRUE; if(!(mp4file = fopen(args, "rb"))){ g_print("MP4!AAC - Can't open file\n"); g_free(args); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); } 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; 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){ /* * TODO: check here for others Audio format..... * */ g_print("Unsupported Audio track type\n"); g_free(args); fclose(mp4file); bPlaying = FALSE; pthread_mutex_unlock(&mutex); pthread_exit(NULL); }else{ NeAACDecHandle decoder; unsigned char *buffer = NULL; guint bufferSize = 0; gulong samplerate; guchar channels;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -