readline_cppflags := @readline_cppflags@
alsa_cppflags := @alsa_cppflags@
oss_cppflags := @oss_cppflags@
+mp4v2_cppflags := @mp4v2_cppflags@
clock_gettime_ldflags := @clock_gettime_ldflags@
id3tag_ldflags := @id3tag_ldflags@
core_audio_ldflags := @core_audio_ldflags@
crypto_ldflags := @crypto_ldflags@
iconv_ldflags := @iconv_ldflags@
+mp4v2_ldflags := @mp4v2_ldflags@
include Makefile.real
$(object_dir)/mp3_afh.o $(dep_dir)/mp3_afh.d: CPPFLAGS += $(id3tag_cppflags)
$(object_dir)/crypt.o $(dep_dir)/crypt.d: CPPFLAGS += $(openssl_cppflags)
$(object_dir)/gcrypt.o $(dep_dir)/gcrypt.d: CPPFLAGS += $(gcrypt_cppflags)
+$(object_dir)/ao_write.o $(dep_dir)/ao_write.d: CPPFLAGS += $(ao_cppflags)
+$(object_dir)/aac_afh.o $(dep_dir)/aac_afh.d: CPPFLAGS += $(mp4v2_cppflags)
$(object_dir)/alsa%.o $(dep_dir)/alsa%.d: CPPFLAGS += $(alsa_cppflags)
$(object_dir)/interactive.o $(dep_dir)/interactive.d \
para_play \
: LDFLAGS += \
$(mad_ldflags) \
+ $(faad_ldflags) \
$(samplerate_ldflags) \
-lm
$(faad_ldflags) \
$(flac_ldflags)
+para_server \
+para_play \
+para_afh \
+para_recv \
+: LDFLAGS += \
+ $(mp4v2_ldflags)
+
para_server \
para_client \
para_audioc \
/** \file aac_afh.c para_server's aac audio format handler. */
#include <regex.h>
+#include <mp4v2/mp4v2.h>
#include "para.h"
#include "error.h"
#include "afh.h"
#include "string.h"
#include "aac.h"
+#include "fd.h"
static int aac_find_stsz(unsigned char *buf, size_t buflen, off_t *skip)
{
return ret;
}
+static int aac_rewrite_tags(const char *map, size_t mapsize,
+ struct taginfo *tags, int fd, const char *filename)
+{
+ MP4FileHandle h;
+ const MP4Tags *mdata;
+ int ret = write_all(fd, map, mapsize);
+
+ if (ret < 0)
+ return ret;
+ lseek(fd, 0, SEEK_SET);
+ h = MP4Modify(filename, 0);
+ if (!h) {
+ PARA_ERROR_LOG("MP4Modify() failed, fd = %d\n", fd);
+ return -E_MP4V2;
+ }
+ mdata = MP4TagsAlloc();
+ assert(mdata);
+ if (!MP4TagsFetch(mdata, h)) {
+ PARA_ERROR_LOG("MP4Tags_Fetch() failed\n");
+ ret = -E_MP4V2;
+ goto close;
+ }
+
+ if (!MP4TagsSetAlbum(mdata, tags->album)) {
+ PARA_ERROR_LOG("Could not set album\n");
+ ret = -E_MP4V2;
+ goto tags_free;
+ }
+ if (!MP4TagsSetArtist(mdata, tags->artist)) {
+ PARA_ERROR_LOG("Could not set album\n");
+ ret = -E_MP4V2;
+ goto tags_free;
+ }
+ if (!MP4TagsSetComments(mdata, tags->comment)) {
+ PARA_ERROR_LOG("Could not set comment\n");
+ ret = -E_MP4V2;
+ goto tags_free;
+ }
+ if (!MP4TagsSetName(mdata, tags->title)) {
+ PARA_ERROR_LOG("Could not set title\n");
+ ret = -E_MP4V2;
+ goto tags_free;
+ }
+ if (!MP4TagsSetReleaseDate(mdata, tags->year)) {
+ PARA_ERROR_LOG("Could not set release date\n");
+ ret = -E_MP4V2;
+ goto tags_free;
+ }
+
+ if (!MP4TagsStore(mdata, h)) {
+ PARA_ERROR_LOG("Could not store tags\n");
+ ret = -E_MP4V2;
+ goto tags_free;
+ }
+ ret = 1;
+tags_free:
+ MP4TagsFree(mdata);
+close:
+ MP4Close(h, 0);
+ return ret;
+}
+
static const char* aac_suffixes[] = {"m4a", "mp4", NULL};
/**
* the init function of the aac audio format handler
{
afh->get_file_info = aac_get_file_info,
afh->suffixes = aac_suffixes;
+ afh->rewrite_tags = aac_rewrite_tags;
}
AC_CHECK_LIB([samplerate], [src_process], [], HAVE_SAMPLERATE=no)
LIB_SUBST_FLAGS(samplerate)
UNSTASH_FLAGS
+########################################################################## mp4v2
+STASH_FLAGS
+LIB_ARG_WITH([mp4v2], [-lmp4v2])
+HAVE_MP4V2=yes
+AC_CHECK_HEADER([mp4v2/mp4v2.h], [], [HAVE_MP4V2=no])
+AC_CHECK_LIB([mp4v2], [MP4Read], [], [HAVE_MP4V2=no])
+LIB_SUBST_FLAGS(mp4v2)
+UNSTASH_FLAGS
######################################################################### server
if test -n "$CRYPTOLIB" && test $HAVE_OSL = yes; then
build_server="yes"
NEED_SPEEX_OBJECTS() && server_errlist_objs="$server_errlist_objs spx_afh spx_common"
NEED_OPUS_OBJECTS() && server_errlist_objs="$server_errlist_objs opus_afh opus_common"
NEED_FLAC_OBJECTS && server_errlist_objs="$server_errlist_objs flac_afh"
- test $HAVE_FAAD = yes && server_errlist_objs="$server_errlist_objs aac_afh aac_common"
+ if test $HAVE_FAAD = yes && test $HAVE_MP4V2 = yes; then
+ server_errlist_objs="$server_errlist_objs aac_afh aac_common"
+ fi
server_objs="add_cmdline($server_cmdline_objs) $server_errlist_objs"
AC_SUBST(server_objs, add_dot_o($server_objs))
AC_DEFINE_UNQUOTED(INIT_SERVER_ERRLISTS,
NEED_OPUS_OBJECTS && recv_errlist_objs="$recv_errlist_objs opus_afh opus_common"
NEED_FLAC_OBJECTS && recv_errlist_objs="$recv_errlist_objs flac_afh"
-if test $HAVE_FAAD = yes; then
+if test $HAVE_FAAD = yes -a $HAVE_MP4V2 = yes; then
recv_errlist_objs="$recv_errlist_objs aac_afh aac_common"
fi
recv_objs="add_cmdline($recv_cmdline_objs) $recv_errlist_objs"
afh_errlist_objs="$afh_errlist_objs flac_afh"
audio_format_handlers="$audio_format_handlers flac"
}
-if test $HAVE_FAAD = yes; then
- afh_errlist_objs="$afh_errlist_objs aac_common aac_afh"
+if test $HAVE_FAAD = yes -a $HAVE_MP4V2 = yes; then
+ afh_errlist_objs="$afh_errlist_objs aac_afh aac_common"
audio_format_handlers="$audio_format_handlers aac"
fi
NEED_FLAC_OBJECTS && {
play_errlist_objs="$play_errlist_objs flacdec_filter flac_afh"
}
-if test $HAVE_FAAD = yes; then
+if test $HAVE_FAAD = yes && test $HAVE_MP4V2 = yes; then
play_errlist_objs="$play_errlist_objs aacdec_filter aac_afh aac_common"
fi
if test $HAVE_MAD = yes; then
crypto lib: ${CRYPTOLIB:-[none]}
unix socket credentials: $have_ucred
readline (interactive CLIs): $HAVE_READLINE
-audio formats handlers: $audio_format_handlers
id3 version 2 support: $HAVE_ID3TAG
-filters: $filters
+faad: $HAVE_FAAD
+mp4v2: $HAVE_MP4V2
+
+audio format handlers: $audio_format_handlers
+filters: $(echo $filters)
writers: $writers
para_fade: $build_fade
PARA_ERROR(STSZ, "did not find stcz atom"), \
PARA_ERROR(MP4ASC, "audio spec config error"), \
PARA_ERROR(AAC_AFH_INIT, "failed to init aac decoder"), \
-
+ PARA_ERROR(MP4V2, "mp4v2 library error"), \
+ PARA_ERROR(NO_AUDIO_TRACK, "file contains no valid audio track"), \
#define AAC_COMMON_ERRORS \
PARA_ERROR(ESDS, "did not find esds atom"), \
PARA_ERROR(AACDEC_INIT, "failed to init aac decoder"), \
PARA_ERROR(AAC_DECODE, "aac decode error"), \
-
#define CHUNK_QUEUE_ERRORS \
PARA_ERROR(QUEUE, "packet queue overrun"), \