diff options
author | Robin H. Johnson <robbat2@gentoo.org> | 2015-08-08 13:49:04 -0700 |
---|---|---|
committer | Robin H. Johnson <robbat2@gentoo.org> | 2015-08-08 17:38:18 -0700 |
commit | 56bd759df1d0c750a065b8c845e93d5dfa6b549d (patch) | |
tree | 3f91093cdb475e565ae857f1c5a7fd339e2d781e /net-misc/mediatomb | |
download | gentoo-56bd759df1d0c750a065b8c845e93d5dfa6b549d.tar.gz gentoo-56bd759df1d0c750a065b8c845e93d5dfa6b549d.tar.bz2 gentoo-56bd759df1d0c750a065b8c845e93d5dfa6b549d.zip |
proj/gentoo: Initial commit
This commit represents a new era for Gentoo:
Storing the gentoo-x86 tree in Git, as converted from CVS.
This commit is the start of the NEW history.
Any historical data is intended to be grafted onto this point.
Creation process:
1. Take final CVS checkout snapshot
2. Remove ALL ChangeLog* files
3. Transform all Manifests to thin
4. Remove empty Manifests
5. Convert all stale $Header$/$Id$ CVS keywords to non-expanded Git $Id$
5.1. Do not touch files with -kb/-ko keyword flags.
Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
X-Thanks: Alec Warner <antarus@gentoo.org> - did the GSoC 2006 migration tests
X-Thanks: Robin H. Johnson <robbat2@gentoo.org> - infra guy, herding this project
X-Thanks: Nguyen Thai Ngoc Duy <pclouds@gentoo.org> - Former Gentoo developer, wrote Git features for the migration
X-Thanks: Brian Harring <ferringb@gentoo.org> - wrote much python to improve cvs2svn
X-Thanks: Rich Freeman <rich0@gentoo.org> - validation scripts
X-Thanks: Patrick Lauer <patrick@gentoo.org> - Gentoo dev, running new 2014 work in migration
X-Thanks: Michał Górny <mgorny@gentoo.org> - scripts, QA, nagging
X-Thanks: All of other Gentoo developers - many ideas and lots of paint on the bikeshed
Diffstat (limited to 'net-misc/mediatomb')
22 files changed, 2995 insertions, 0 deletions
diff --git a/net-misc/mediatomb/Manifest b/net-misc/mediatomb/Manifest new file mode 100644 index 000000000000..f8cf86b6d40d --- /dev/null +++ b/net-misc/mediatomb/Manifest @@ -0,0 +1,4 @@ +DIST mediatomb-0.12.1.tar.gz 1240612 SHA256 31163c34a7b9d1c9735181737cb31306f29f1f2a0335fb4f53ecccf8f62f11cd SHA512 36e7269a532a79c91b4ea7be36f92cbefa913a1f856e422e46fe2b97ee7a569dd20c38b0cbe651a8e7faacde892ea18f3cac66c3c0737480c44f9b9bc3a45438 WHIRLPOOL 6a9e294aa9f8f40850863a86bae4fd6a81d198d7f4cf34d67a6a0cd568c387ef0f0bd5a3524c7bc05cb304f4e86dd0c12dc773bd1034c1924af6919cc740177b +DIST mediatomb-0.12.2_pre20150118.tar.gz 2413534 SHA256 a892fe02151978433f3604d10f6dca35a935c61ea0988bd10312cdbdb1055a8b SHA512 968b9a91de48396e05ed1c65e77e576fc5b959bce7b2b77cde14f4aa88fbc57ac2b0e6d34f7365a071a01a6c7285f36866097c9e7608eef7e33c3d4d215e0675 WHIRLPOOL c9be68ece751811e9796a5dc43e1852daebbbc7c58fda7867afd23e070e84f8c48d32ca3b2ae2dfc1a422c4443d5d5e74b30841c1dabf35bb00d68336f0287df +DIST mediatomb_0.12.1-4.debian.tar.gz 34161 SHA256 b1e48d01f4f99362ef554c9220df21c48f6b76ad716e29427948a524e5c84d90 SHA512 21f876de3ec0b24bfcb37d387b5337d574f2e62e12944547f0a2e69e34532e296097fd04cce9941e994c3823a7bb863172db4fc3024d490f2a2359b7f0adb079 WHIRLPOOL ad38bc64411f1aac25672c522b862401897f0e4225ea21bab317a1c3311ef87a3e688f6ea1abb5a30eeb4cb3165dabbbff158eb5d4267dba901a54f15017078d +DIST mediatomb_0.12.1-5.debian.tar.gz 36001 SHA256 bfbc971eeaeb09791d4cf1b1102a19ca9ce69d67c97608bba7b8ce3b519a8625 SHA512 420cf0d4fc0aa82337f2893ef18f04f9d079d833f2540d6bee504d423e8acee5e5ae528d97f5cd4228d6648777c62d6186532f7a74d3d0cb04f9226a2de1dd95 WHIRLPOOL 3d826181f97873fc9acb67fa5a3171b9e0c60862066cc0dd29e05a4f793828fbcfb438dd1375d56144933d101824a4f498b5dbf1e269e3bb12e4ee53d9b13d59 diff --git a/net-misc/mediatomb/files/mediatomb-0.12.0.confd b/net-misc/mediatomb/files/mediatomb-0.12.0.confd new file mode 100644 index 000000000000..7f5c00830251 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.0.confd @@ -0,0 +1,28 @@ +# /etc/conf.d/mediatomb: config file for /etc/init.d/mediatomb + +# See the mediatomb(1) manpage for more info. + +# MediaTomb Web UI port. +# NOTE: The minimum value allowed is 49152 +MEDIATOMB_PORT=49152 + +# Run MediaTomb as this user. +# NOTE: For security reasons do not run MediaTomb as root. +MEDIATOMB_USER="mediatomb" + +# Run MediaTomb as this group. +# NOTE: For security reasons do not run MediaTomb as root. +MEDIATOMB_GROUP="mediatomb" + +# Path to MediaTomb config file. +MEDIATOMB_CONFIG="/etc/mediatomb/config.xml" + +# Path to MediaTomb log file. +MEDIATOMB_LOGFILE="/var/log/mediatomb.log" + +# Path to MediaTomb pid file. +MEDIATOMB_PIDFILE="/var/run/mediatomb.pid" + +# Other options you want to pass to MediaTomb. +# Add "--interface ${MEDIATOMB_INTERFACE}" to bind to a named interface. +MEDIATOMB_OPTIONS="" diff --git a/net-misc/mediatomb/files/mediatomb-0.12.0.config b/net-misc/mediatomb/files/mediatomb-0.12.0.config new file mode 100644 index 000000000000..0cd03b15d8e8 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.0.config @@ -0,0 +1,144 @@ +<?xml version="1.0" encoding="UTF-8"?> +<config version="2" xmlns="http://mediatomb.cc/config/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mediatomb.cc/config/2 http://mediatomb.cc/config/2.xsd"> + <server> + <ui enabled="yes" show-tooltips="yes"> + <accounts enabled="no" session-timeout="30"> + <account user="mediatomb" password="mediatomb"/> + </accounts> + </ui> + <name>MediaTomb</name> + <udn></udn> + <home>/var/lib/mediatomb</home> + <webroot>/usr/share/mediatomb/web</webroot> + <storage> + <sqlite3 enabled="yes"> + <database-file>mediatomb.db</database-file> + </sqlite3> + <mysql enabled="no"> + <host>host</host> + <database>database</database> + <username>username</username> + <password>password</password> + </mysql> + </storage> + <protocolInfo extend="yes"/> + <pc-directory upnp-hide="no"/> + <extended-runtime-options> + <ffmpegthumbnailer enabled="no"> + <thumbnail-size>160</thumbnail-size> + <seek-percentage>10</seek-percentage> + <filmstrip-overlay>no</filmstrip-overlay> + <workaround-bugs>no</workaround-bugs> + <image-quality>8</image-quality> + </ffmpegthumbnailer> + <mark-played-items enabled="no" suppress-cds-updates="yes"> + <string mode="prepend">*</string> + <mark> + <content>video</content> + </mark> + </mark-played-items> + <lastfm enabled="no"> + <username>username</username> + <password>password</password> + </lastfm> + </extended-runtime-options> + </server> + <import hidden-files="no"> + <scripting script-charset="UTF-8"> + <common-script>/usr/share/mediatomb/js/common.js</common-script> + <playlist-script>/usr/share/mediatomb/js/playlists.js</playlist-script> + <virtual-layout type="builtin"> + <import-script>/usr/share/mediatomb/js/import.js</import-script> + </virtual-layout> + </scripting> + <mappings> + <extension-mimetype ignore-unknown="no"> + <map from="mp3" to="audio/mpeg"/> + <map from="ogx" to="application/ogg"/> + <map from="ogv" to="video/ogg"/> + <map from="oga" to="audio/ogg"/> + <map from="ogg" to="audio/ogg"/> + <map from="ogm" to="video/ogg"/> + <map from="asf" to="video/x-ms-asf"/> + <map from="asx" to="video/x-ms-asf"/> + <map from="wma" to="audio/x-ms-wma"/> + <map from="wax" to="audio/x-ms-wax"/> + <map from="wmv" to="video/x-ms-wmv"/> + <map from="wvx" to="video/x-ms-wvx"/> + <map from="wm" to="video/x-ms-wm"/> + <map from="wmx" to="video/x-ms-wmx"/> + <map from="m3u" to="audio/x-mpegurl"/> + <map from="pls" to="audio/x-scpls"/> + <map from="flv" to="video/x-flv"/> + <map from="mkv" to="video/x-matroska"/> + <map from="mka" to="audio/x-matroska"/> + <map from="avi" to="video/divx"/> + <map from="m2ts" to="video/avc"/> + <map from="cr2" to="image/raw"/> + <map from="nef" to="image/raw"/> + </extension-mimetype> + <mimetype-upnpclass> + <map from="audio/*" to="object.item.audioItem.musicTrack"/> + <map from="video/*" to="object.item.videoItem"/> + <map from="image/*" to="object.item.imageItem"/> + </mimetype-upnpclass> + <mimetype-contenttype> + <treat mimetype="audio/mpeg" as="mp3"/> + <treat mimetype="application/ogg" as="ogg"/> + <treat mimetype="video/ogg" as="ogg"/> + <treat mimetype="audio/ogg" as="ogg"/> + <treat mimetype="audio/x-flac" as="flac"/> + <treat mimetype="image/jpeg" as="jpg"/> + <treat mimetype="audio/x-mpegurl" as="playlist"/> + <treat mimetype="audio/x-scpls" as="playlist"/> + <treat mimetype="audio/x-wav" as="pcm"/> + <treat mimetype="audio/L16" as="pcm"/> + <treat mimetype="video/x-msvideo" as="avi"/> + <treat mimetype="video/mp4" as="mp4"/> + <treat mimetype="audio/mp4" as="mp4"/> + <treat mimetype="video/divx" as="avi"/> + </mimetype-contenttype> + </mappings> + <online-content> + <YouTube enabled="no" refresh="28800" update-at-start="yes" purge-after="604800" racy-content="exclude" format="mp4" hd="no"> + <favorites user="NationalGeographic"/> + <playlists user="PlayStation"/> + <uploads user="Google"/> + <standardfeed feed="most_viewed" time-range="today"/> + <standardfeed feed="recently_featured" time-range="today"/> + </YouTube> + </online-content> + </import> + <transcoding enabled="no"> + <mimetype-profile-mappings> + <transcode mimetype="audio/ogg" using="audio2pcm"/> + <transcode mimetype="audio/x-flac" using="audio2pcm"/> + <transcode mimetype="video/ogg" using="video2mpeg"/> + <transcode mimetype="video/x-flv" using="video2mpeg"/> + </mimetype-profile-mappings> + <profiles> + <profile name="audio2pcm" enabled="yes" type="external"> + <mimetype>audio/L16</mimetype> + <accept-url>no</accept-url> + <first-resource>yes</first-resource> + <hide-original-resource>yes</hide-original-resource> + <accept-ogg-theora>no</accept-ogg-theora> + <sample-frequency>44100</sample-frequency> + <audio-channels>2</audio-channels> + <agent command="ffmpeg" arguments="-i %in -acodec pcm_s16be -ab 192k -ar 44100 -ac 2 -f s16be -y %out"/> + <buffer size="1048576" chunk-size="131072" fill-size="262144"/> + </profile> + <profile name="video2mpeg" enabled="yes" type="external"> + <mimetype>video/mpeg</mimetype> + <accept-url>no</accept-url> + <first-resource>yes</first-resource> + <hide-original-resource>yes</hide-original-resource> + <accept-ogg-theora>yes</accept-ogg-theora> + <sample-frequency>48000</sample-frequency> + <audio-channels>2</audio-channels> + <agent command="ffmpeg" arguments="-i %in -vcodec mpeg2video -b 4096k -r 25 -acodec mp2 -ab 192k -ar 48000 -ac 2 -async 1 -f dvd -threads 2 -y %out"/> + <buffer size="10485760" chunk-size="262144" fill-size="524288"/> + </profile> + </profiles> + </transcoding> +</config> diff --git a/net-misc/mediatomb/files/mediatomb-0.12.0.initd b/net-misc/mediatomb/files/mediatomb-0.12.0.initd new file mode 100644 index 000000000000..5f6112b3499b --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.0.initd @@ -0,0 +1,22 @@ +#!/sbin/runscript + +depend() { + need net #MYSQL# +} + +start() { + ebegin "Starting MediaTomb" + start-stop-daemon --start --quiet --exec /usr/bin/mediatomb \ + --pidfile ${MEDIATOMB_PIDFILE} -- --daemon \ + --pidfile ${MEDIATOMB_PIDFILE} --user ${MEDIATOMB_USER} \ + --group ${MEDIATOMB_GROUP} --logfile ${MEDIATOMB_LOGFILE} \ + --config ${MEDIATOMB_CONFIG} --port ${MEDIATOMB_PORT} \ + ${MEDIATOMB_OPTIONS} + eend $? +} + +stop () { + ebegin "Stopping MediaTomb" + start-stop-daemon --stop --retry 10 --quiet --pidfile ${MEDIATOMB_PIDFILE} + eend $? +} diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-avformatcontext-pointer.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-avformatcontext-pointer.patch new file mode 100644 index 000000000000..ab3e7cf7e17d --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-avformatcontext-pointer.patch @@ -0,0 +1,19 @@ +When opening a file to check its avformat, the AVFormatContext pointer was +not initialized to NULL before it was passed by reference to the open +function. + +Patch by Bradley Broom <bmbroom@gmail.com> + +https://bugs.gentoo.org/show_bug.cgi?id=446922 + +--- mediatomb-0.12.1/src/metadata/ffmpeg_handler.cc ++++ mediatomb-0.12.1/src/metadata/ffmpeg_handler.cc +@@ -281,7 +281,7 @@ + int x = 0; + int y = 0; + +- AVFormatContext *pFormatCtx; ++ AVFormatContext *pFormatCtx = NULL; + + // Suppress all log messages + av_log_set_callback(FfmpegNoOutputStub); diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-flac-metadata.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-flac-metadata.patch new file mode 100644 index 000000000000..0228dffd08d8 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-flac-metadata.patch @@ -0,0 +1,446 @@ +diff -urpN a/build/Makefile.am b/build/Makefile.am +--- a/build/Makefile.am 2010-03-22 21:39:46.000000000 +1100 ++++ b/build/Makefile.am 2013-12-16 10:16:32.426878578 +1100 +@@ -18,6 +18,7 @@ libmediatomb_a_CXXFLAGS = \ + $(ICONV_CXXFLAGS) \ + $(LIBMAGIC_CFLAGS) \ + $(ID3LIB_CFLAGS) \ ++ $(FLAC_CFLAGS) \ + $(LIBEXIF_CFLAGS) \ + $(ZLIB_CFLAGS) \ + $(PTHREAD_CFLAGS) \ +@@ -44,6 +45,7 @@ mediatomb_CXXFLAGS = -I$(top_srcdir)/src + $(ICONV_CXXFLAGS) \ + $(LIBMAGIC_CFLAGS) \ + $(ID3LIB_CFLAGS) \ ++ $(FLAC_CFLAGS) \ + $(LIBEXIF_CFLAGS) \ + $(ZLIB_CFLAGS) \ + $(PTHREAD_CFLAGS) \ +@@ -78,6 +80,7 @@ mediatomb_LDADD = \ + $(JS_LIBS) \ + $(LIBMAGIC_LIBS) \ + $(ID3LIB_LIBS) \ ++ $(FLAC_LIBS) \ + $(LIBEXIF_LIBS) \ + $(ZLIB_LIBS) \ + $(RT_LIBS) \ +diff -urpN a/build/libmediatomb_src b/build/libmediatomb_src +--- a/build/libmediatomb_src 2010-03-23 04:09:53.000000000 +1100 ++++ b/build/libmediatomb_src 2013-12-16 10:14:49.730356868 +1100 +@@ -98,6 +98,8 @@ libmediatomb_a_SOURCES = \ + ../src/metadata/libmp4v2_handler.h \ + ../src/metadata/taglib_handler.cc \ + ../src/metadata/taglib_handler.h \ ++../src/metadata/flac_handler.cc \ ++../src/metadata/flac_handler.h \ + ../src/mpegdemux/buffer.c \ + ../src/mpegdemux/buffer.h \ + ../src/mpegdemux/mpegdemux.c \ +diff -urpN a/configure.ac b/configure.ac +--- a/configure.ac 2010-04-08 08:38:51.000000000 +1000 ++++ b/configure.ac 2013-12-16 10:24:16.547793225 +1100 +@@ -1314,6 +1314,35 @@ LDFLAGS="$LDFLAGS_SAVE" + LIBS="$LIBS_SAVE" + CXXFLAGS="$CXXFLAGS_SAVE" + CPPFLAGS="$CPPFLAGS_SAVE" ++ ++######### FLAC ++ ++FLAC_STATUS= ++ ++MT_OPTION([FLAC], [enable], ++ [FLAC metadata extraction with the help of FLAC],[],[]) ++ ++if test "x$FLAC_OPTION_ENABLED" = xyes; then ++ MT_CHECK_PACKAGE([FLAC], ++ [FLAC/metadata], ++ [FLAC], [main]) ++else ++ FLAC_STATUS=disabled ++fi ++ ++if test "x$FLAC_STATUS" != xyes; then ++ if (test "x$FLAC_OPTION_REQUESTED" = xyes) && ++ (test "x$FLAC_OPTION_ENABLED" = xyes); then ++ AC_MSG_ERROR([unable to configure FLAC support]) ++ fi ++else ++ CFLAGS="$CFLAGS $FLAC_CFLAGS" ++ CXXFLAGS="$CXXFLAGS $FLAC_CFLAGS" ++ LDFLAGS="$LDFLAGS $FLAC_LDFLAGS $FLAC_LIBS" ++ AC_LANG_SAVE ++ AC_LANG_CPLUSPLUS ++fi ++ + ######## curl + + CURL_PROG_FOUND=0 +@@ -1914,7 +1943,7 @@ if (test "x$SOPCAST_OPTION_ENABLED" = xy + AC_DEFINE([SOPCAST], [1], [Enable support for the SopCast service]) + fi + +-AC_DEFINE_UNQUOTED([COMPILE_INFO], "\thost:\t\t\t$host\n\tsqlite3:\t\t$SQLITE3_STATUS\n\tmysql:\t\t\t$MYSQL_STATUS\n\tlibjs:\t\t\t$JS_OK\n\tlibmagic:\t\t$LIBMAGIC_STATUS\n\tinotify:\t\t$INOTIFY_STATUS\n\tlibexif:\t\t$LIBEXIF_STATUS\n\tid3lib:\t\t\t$ID3LIB_STATUS\n\ttaglib:\t\t\t$TAGLIB_STATUS\n\tffmpeg\t\t\t$FFMPEG_STATUS\n\tlibmp4v2:\t\t$LIBMP4V2_STATUS\n\texternal transcoding:\t$EXTERNAL_TRANSCODING_OPTION_ENABLED\n\tcurl:\t\t\t$CURL_OK\n\tYouTube:\t\t$YOUTUBE_OPTION_ENABLED\n\tlibextractor\t\t$LIBEXTRACTOR_STATUS\n\tdb-autocreate:\t\t$DB_AUTOCREATE_OPTION_ENABLED\n\tdebug log:\t\t$DEBUG_LOG_OPTION_ENABLED\n\tprotocol info extension:$PROTOCOLINFO_EXTENSION_OPTION_ENABLED\n\tffmpegthumbnailer:\t$FFMPEGTHUMBNAILER_STATUS\n\tlastfmlib:\t\t$LASTFMLIB_STATUS\n\tdata directory:\t\t$PACKAGE_DATADIR", [compile option summary]) ++AC_DEFINE_UNQUOTED([COMPILE_INFO], "\thost:\t\t\t$host\n\tsqlite3:\t\t$SQLITE3_STATUS\n\tmysql:\t\t\t$MYSQL_STATUS\n\tlibjs:\t\t\t$JS_OK\n\tlibmagic:\t\t$LIBMAGIC_STATUS\n\tinotify:\t\t$INOTIFY_STATUS\n\tlibexif:\t\t$LIBEXIF_STATUS\n\tid3lib:\t\t\t$ID3LIB_STATUS\n\ttaglib:\t\t\t$TAGLIB_STATUS\n\tFLAC:\t\t\t$FLAC_STATUS\n\tffmpeg\t\t\t$FFMPEG_STATUS\n\tlibmp4v2:\t\t$LIBMP4V2_STATUS\n\texternal transcoding:\t$EXTERNAL_TRANSCODING_OPTION_ENABLED\n\tcurl:\t\t\t$CURL_OK\n\tYouTube:\t\t$YOUTUBE_OPTION_ENABLED\n\tlibextractor\t\t$LIBEXTRACTOR_STATUS\n\tdb-autocreate:\t\t$DB_AUTOCREATE_OPTION_ENABLED\n\tdebug log:\t\t$DEBUG_LOG_OPTION_ENABLED\n\tprotocol info extension:$PROTOCOLINFO_EXTENSION_OPTION_ENABLED\n\tffmpegthumbnailer:\t$FFMPEGTHUMBNAILER_STATUS\n\tlastfmlib:\t\t$LASTFMLIB_STATUS\n\tdata directory:\t\t$PACKAGE_DATADIR", [compile option summary]) + + ############### + AC_CONFIG_FILES([ +@@ -1946,6 +1975,7 @@ echo "inotify : $INOTIFY_S + echo "libexif : $LIBEXIF_STATUS" + echo "id3lib : $ID3LIB_STATUS" + echo "taglib : $TAGLIB_STATUS" ++echo "FLAC : $FLAC_STATUS" + echo "libmp4v2 : $LIBMP4V2_STATUS" + echo "ffmpeg : $FFMPEG_STATUS" + echo "ffmpegthumbnailer : $FFMPEGTHUMBNAILER_STATUS" +diff -urpN a/src/cds_resource_manager.cc b/src/cds_resource_manager.cc +--- a/src/cds_resource_manager.cc 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/cds_resource_manager.cc 2013-12-16 10:25:15.277987292 +1100 +@@ -372,6 +372,7 @@ void CdsResourceManager::addResources(Re + // only add upnp:AlbumArtURI if we have an AA, skip the resource + if ((i > 0) && ((item->getResource(i)->getHandlerType() == CH_ID3) || + (item->getResource(i)->getHandlerType() == CH_MP4) || ++ (item->getResource(i)->getHandlerType() == CH_FLAC) || + (item->getResource(i)->getHandlerType() == CH_EXTURL))) + { + String rct; +diff -urpN a/src/config_manager.cc b/src/config_manager.cc +--- a/src/config_manager.cc 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/config_manager.cc 2013-12-16 10:26:57.220886235 +1100 +@@ -624,6 +624,10 @@ String ConfigManager::createDefaultConfi + _(CONTENT_TYPE_OGG))); + mtcontent->appendElementChild(treat_as(_("audio/x-flac"), + _(CONTENT_TYPE_FLAC))); ++ mtcontent->appendElementChild(treat_as(_("audio/x-ms-wma"), ++ _(CONTENT_TYPE_WMA))); ++ mtcontent->appendElementChild(treat_as(_("audio/x-wavpack"), ++ _(CONTENT_TYPE_WAVPACK))); + mtcontent->appendElementChild(treat_as(_("image/jpeg"), + _(CONTENT_TYPE_JPG))); + mtcontent->appendElementChild(treat_as(_("audio/x-mpegurl"), +diff -urpN a/src/metadata/flac_handler.cc b/src/metadata/flac_handler.cc +--- a/src/metadata/flac_handler.cc 1970-01-01 10:00:00.000000000 +1000 ++++ b/src/metadata/flac_handler.cc 2013-12-16 10:30:19.955604387 +1100 +@@ -0,0 +1,204 @@ ++/*MT* ++ ++ MediaTomb - http://www.mediatomb.cc/ ++ ++ flac_handler.cc - this file is part of MediaTomb. ++ ++ Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> ++ ++ Copyright (C) 2006-2009 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, ++ Leonhard Wimmer <leo@mediatomb.cc> ++ ++ MediaTomb is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 ++ as published by the Free Software Foundation. ++ ++ MediaTomb is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ version 2 along with MediaTomb; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ # $Id$ ++*/ ++ ++/// \file flac_handler.cc ++/// \brief Implementeation of the FlacHandler class. ++ ++#ifdef HAVE_CONFIG_H ++ #include "autoconfig.h" ++#endif ++ ++#ifdef HAVE_FLAC ++ ++#include <FLAC/all.h> ++ ++#include "flac_handler.h" ++#include "string_converter.h" ++#include "config_manager.h" ++#include "common.h" ++#include "tools.h" ++#include "mem_io_handler.h" ++ ++#include "content_manager.h" ++ ++using namespace zmm; ++ ++FlacHandler::FlacHandler() : MetadataHandler() ++{ ++} ++ ++static void addField(metadata_fields_t field, const FLAC__StreamMetadata* tags, Ref<CdsItem> item) ++{ ++ String value; ++ int i; ++ ++ Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure ++ ++ switch (field) ++ { ++ case M_TITLE: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "TITLE"); ++ break; ++ case M_ARTIST: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "ARTIST"); ++ break; ++ case M_ALBUM: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "ALBUM"); ++ break; ++ case M_DATE: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "DATE"); ++ break; ++ case M_GENRE: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "GENRE"); ++ break; ++ case M_DESCRIPTION: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "DESCRIPTION"); ++ break; ++ case M_TRACKNUMBER: ++ i = FLAC__metadata_object_vorbiscomment_find_entry_from(tags, /*offset=*/0, "TRACKNUMBER"); ++ break; ++ default: ++ return; ++ } ++ ++ if( 0 <= i ) ++ value = strchr((const char *)tags->data.vorbis_comment.comments[i].entry, '=') + 1; ++ else ++ return; ++ ++ value = trim_string(value); ++ ++ if (string_ok(value)) ++ { ++ item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); ++ log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str()); ++ } ++} ++ ++void FlacHandler::fillMetadata(Ref<CdsItem> item) ++{ ++ FLAC__StreamMetadata* tags = NULL; ++ FLAC__StreamMetadata streaminfo; ++ Ref<StringConverter> sc = StringConverter::i2i(); // sure is sure ++ ++ if( !FLAC__metadata_get_tags(item->getLocation().c_str(), &tags) ) ++ return; ++ ++ if( FLAC__METADATA_TYPE_VORBIS_COMMENT == tags->type ) ++ { ++ for (int i = 0; i < M_MAX; i++) ++ addField((metadata_fields_t) i, tags, item); ++ } ++ ++ FLAC__metadata_object_delete(tags); ++ tags = NULL; ++ ++ if( !FLAC__metadata_get_streaminfo(item->getLocation().c_str(), &streaminfo) ) ++ return; ++ ++ if( FLAC__METADATA_TYPE_STREAMINFO == streaminfo.type ) ++ { ++ // note: UPnP requires bytes/second ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_BITRATE), String::from((unsigned)((streaminfo.data.stream_info.bits_per_sample * streaminfo.data.stream_info.sample_rate) / 8))); ++ // note: UPnP requires HMS ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_DURATION), secondsToHMS((unsigned)(streaminfo.data.stream_info.total_samples / streaminfo.data.stream_info.sample_rate))); ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_SAMPLEFREQUENCY), String::from(streaminfo.data.stream_info.sample_rate)); ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(R_NRAUDIOCHANNELS), String::from(streaminfo.data.stream_info.channels)); ++ } ++ ++ if( !FLAC__metadata_get_picture(item->getLocation().c_str(), ++ &tags, ++ FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER, ++ NULL, ++ NULL, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1 ) ) ++ return; ++ ++ if( FLAC__METADATA_TYPE_PICTURE == tags->type ) ++ { ++ String art_mimetype = tags->data.picture.mime_type; ++ log_debug("Mime type : %s\n", sc->convert(art_mimetype).c_str()); ++ ++ // saw that simply "PNG" was used with some mp3's, so mimetype setting ++ // was probably invalid ++ if (!string_ok(art_mimetype) || (art_mimetype.index('/') == -1)) ++ { ++#ifdef HAVE_MAGIC ++ art_mimetype = ContentManager::getInstance()->getMimeTypeFromBuffer((void *)tags->data.picture.data, tags->data.picture.data_length); ++ if (!string_ok(art_mimetype)) ++#endif ++ art_mimetype = _(MIMETYPE_DEFAULT); ++ ++ log_debug("Mime type via magic: %s\n", sc->convert(art_mimetype).c_str()); ++ } ++ ++ // if we could not determine the mimetype, then there is no ++ // point to add the resource - it's probably garbage ++ if (art_mimetype != _(MIMETYPE_DEFAULT)) ++ { ++ Ref<CdsResource> resource(new CdsResource(CH_FLAC)); ++ resource->addAttribute(MetadataHandler::getResAttrName(R_PROTOCOLINFO), renderProtocolInfo(art_mimetype)); ++ resource->addParameter(_(RESOURCE_CONTENT_TYPE), _(ID3_ALBUM_ART)); ++ item->addResource(resource); ++ } ++ } ++ ++ FLAC__metadata_object_delete(tags); ++} ++ ++Ref<IOHandler> FlacHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) ++{ ++ FLAC__StreamMetadata* picture = NULL; ++ ++ if( !FLAC__metadata_get_picture(item->getLocation().c_str(), ++ &picture, ++ FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER, ++ NULL, ++ NULL, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1, ++ (unsigned)-1 ) ) ++ throw _Exception(_("FlacHandler: could not exctract cover from: ") + item->getLocation()); ++ ++ if( FLAC__METADATA_TYPE_PICTURE != picture->type ) ++ throw _Exception(_("TagHandler: resource has no album information")); ++ ++ Ref<IOHandler> h(new MemIOHandler((void *)picture->data.picture.data, picture->data.picture.data_length)); ++ *data_size = picture->data.picture.data_length; ++ ++ FLAC__metadata_object_delete(picture); ++ ++ return h; ++} ++ ++#endif // HAVE_FLAC +diff -urpN a/src/metadata/flac_handler.h b/src/metadata/flac_handler.h +--- a/src/metadata/flac_handler.h 1970-01-01 10:00:00.000000000 +1000 ++++ b/src/metadata/flac_handler.h 2013-12-16 10:31:24.061822827 +1100 +@@ -0,0 +1,47 @@ ++/*MT* ++ ++ MediaTomb - http://www.mediatomb.cc/ ++ ++ flac_handler.h - this file is part of MediaTomb. ++ ++ Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> ++ ++ Copyright (C) 2006-2009 Gena Batyan <bgeradz@mediatomb.cc>, ++ Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, ++ Leonhard Wimmer <leo@mediatomb.cc> ++ ++ MediaTomb is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 ++ as published by the Free Software Foundation. ++ ++ MediaTomb is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ version 2 along with MediaTomb; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++ # $Id$ ++*/ ++ ++/// \file flac_handler.h ++/// \brief Definition of the FlacHandler class. ++ ++#ifndef __METADATA_FLAC_H__ ++#define __METADATA_FLAC_H__ ++ ++#include "metadata_handler.h" ++ ++/// \brief This class is responsible for reading FLAC metadata ++class FlacHandler : public MetadataHandler ++{ ++public: ++ FlacHandler(); ++ virtual void fillMetadata(zmm::Ref<CdsItem> item); ++ virtual zmm::Ref<IOHandler> serveContent(zmm::Ref<CdsItem> item, int resNum, off_t *data_size); ++}; ++ ++#endif // __METADATA_FLAC_H__ +diff -urpN a/src/metadata_handler.cc b/src/metadata_handler.cc +--- a/src/metadata_handler.cc 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/metadata_handler.cc 2013-12-16 10:35:48.783540865 +1100 +@@ -51,6 +51,10 @@ + #endif // HAVE_ID3LIB + #endif // HAVE_TAGLIB + ++#ifdef HAVE_FLAC ++#include "metadata/flac_handler.h" ++#endif ++ + #ifdef HAVE_LIBMP4V2 + #include "metadata/libmp4v2_handler.h" + #endif +@@ -140,7 +144,8 @@ void MetadataHandler::setMetadata(Ref<Cd + if ((content_type == CONTENT_TYPE_MP3) || + ((content_type == CONTENT_TYPE_OGG) && + (!item->getFlag(OBJECT_FLAG_OGG_THEORA))) || +- (content_type == CONTENT_TYPE_FLAC)) ++ (content_type == CONTENT_TYPE_WMA) || ++ (content_type == CONTENT_TYPE_WAVPACK)) + { + handler = Ref<MetadataHandler>(new TagHandler()); + break; +@@ -155,7 +160,13 @@ void MetadataHandler::setMetadata(Ref<Cd + #endif // HAVE_ID3LIB + #endif // HAVE_TAGLIB + +- ++#ifdef HAVE_FLAC ++ if (content_type == CONTENT_TYPE_FLAC) ++ { ++ handler = Ref<MetadataHandler>(new FlacHandler()); ++ break; ++ } ++#endif + + #ifdef HAVE_EXIV2 + /* +@@ -277,6 +288,10 @@ Ref<MetadataHandler> MetadataHandler::cr + case CH_FFTH: + return Ref<MetadataHandler>(new FfmpegHandler()); + #endif ++#ifdef HAVE_FLAC ++ case CH_FLAC: ++ return Ref<MetadataHandler>(new FlacHandler()); ++#endif + default: + throw _Exception(_("unknown content handler ID: ") + handlerType); + } +diff -urpN a/src/metadata_handler.h b/src/metadata_handler.h +--- a/src/metadata_handler.h 2010-03-26 01:58:11.000000000 +1100 ++++ b/src/metadata_handler.h 2013-12-16 10:52:23.234353526 +1100 +@@ -45,10 +45,13 @@ + #define CH_EXTURL 4 + #define CH_MP4 5 + #define CH_FFTH 6 ++#define CH_FLAC 7 + + #define CONTENT_TYPE_MP3 "mp3" + #define CONTENT_TYPE_OGG "ogg" + #define CONTENT_TYPE_FLAC "flac" ++#define CONTENT_TYPE_WMA "wma" ++#define CONTENT_TYPE_WAVPACK "wv" + #define CONTENT_TYPE_JPG "jpg" + #define CONTENT_TYPE_PLAYLIST "playlist" + #define CONTENT_TYPE_MP4 "mp4" diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch new file mode 100644 index 000000000000..af9a887befe0 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-inotify-hard-links.patch @@ -0,0 +1,34 @@ +make sure new hard links get processed like new files by handling +the IN_CREATE flag properly + +patch by Mike Frysinger + +--- a/src/autoscan_inotify.cc ++++ b/src/autoscan_inotify.cc +@@ -281,7 +284,7 @@ + } + } + +- if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT)) ++ if (adir != nil && mask & (IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_UNMOUNT | IN_CREATE)) + { + String fullPath; + if (mask & IN_ISDIR) +@@ -289,7 +292,7 @@ + else + fullPath = path; + +- if (! (mask & IN_MOVED_TO)) ++ if (! (mask & (IN_MOVED_TO | IN_CREATE))) + { + log_debug("deleting %s\n", fullPath.c_str()); + +@@ -312,7 +315,7 @@ + if (objectID != INVALID_OBJECT_ID) + cm->removeObject(objectID); + } +- if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO)) ++ if (mask & (IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE)) + { + log_debug("adding %s\n", path.c_str()); + // path, recursive, async, hidden, low priority, cancellable diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-libav9.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-libav9.patch new file mode 100644 index 000000000000..7193b7c03cd4 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-libav9.patch @@ -0,0 +1,42 @@ +diff -burN mediatomb-0.12.1.old//src/metadata/ffmpeg_handler.cc mediatomb-0.12.1/src/metadata/ffmpeg_handler.cc +--- mediatomb-0.12.1.old//src/metadata/ffmpeg_handler.cc 2012-11-25 14:55:05.335753129 +0100 ++++ mediatomb-0.12.1/src/metadata/ffmpeg_handler.cc 2012-11-25 15:29:42.840677486 +0100 +@@ -110,8 +110,8 @@ + return; + for (const mapping_t *m = mapping; m->avname != NULL; m++) + { +- AVMetadataTag *tag = NULL; +- tag = av_metadata_get(pFormatCtx->metadata, m->avname, NULL, 0); ++ AVDictionaryEntry *tag = NULL; ++ tag = av_dict_get(pFormatCtx->metadata, m->avname, NULL, 0); + if (tag && tag->value && tag->value[0]) + { + log_debug("Added metadata %s: %s\n", m->avname, tag->value); +@@ -290,14 +290,14 @@ + av_register_all(); + + // Open video file +- if (av_open_input_file(&pFormatCtx, +- item->getLocation().c_str(), NULL, 0, NULL) != 0) ++ if (avformat_open_input(&pFormatCtx, ++ item->getLocation().c_str(), NULL, NULL) != 0) + return; // Couldn't open file + + // Retrieve stream information +- if (av_find_stream_info(pFormatCtx) < 0) ++ if (avformat_find_stream_info(pFormatCtx, NULL) < 0) + { +- av_close_input_file(pFormatCtx); ++ avformat_close_input(&pFormatCtx); + return; // Couldn't find stream information + } + // Add metadata using ffmpeg library calls +@@ -306,7 +306,7 @@ + addFfmpegResourceFields(item, pFormatCtx, &x, &y); + + // Close the video file +- av_close_input_file(pFormatCtx); ++ avformat_close_input(&pFormatCtx); + } + + static bool _mkdir(const char *path) diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-libextractor.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-libextractor.patch new file mode 100644 index 000000000000..e46aca9c487f --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-libextractor.patch @@ -0,0 +1,675 @@ +http://bugs.gentoo.org/435394 + +port to libextractor-0.6.x + +patch by Mike Frysinger <vapier@gentoo.org> + +--- a/configure.ac ++++ b/configure.ac +@@ -1631,7 +1631,7 @@ MT_CHECK_OPTIONAL_PACKAGE([lastfmlib], [disable], + ######## extractor + + if test "x$LIBEXTRACTOR_OPTION_ENABLED" = xyes; then +- MT_CHECK_PACKAGE([libextractor], [extractor], [extractor], [EXTRACTOR_getKeywords]) ++ MT_CHECK_PACKAGE([libextractor], [extractor], [extractor], [EXTRACTOR_extract]) + fi + + if test "x$LIBEXTRACTOR_STATUS" = xyes; then +--- a/src/metadata/extractor_handler.cc ++++ b/src/metadata/extractor_handler.cc +@@ -55,322 +55,344 @@ ExtractorHandler::ExtractorHandler() : MetadataHandler() + { + } + +-static EXTRACTOR_KeywordType getTagFromString(String tag) ++static EXTRACTOR_MetaType getTagFromString(String tag) + { +- if (tag == "EXTRACTOR_UNKNOWN") +- return EXTRACTOR_UNKNOWN; +- if (tag == "EXTRACTOR_FILENAME") +- return EXTRACTOR_FILENAME; +- if (tag == "EXTRACTOR_MIMETYPE") +- return EXTRACTOR_MIMETYPE; +- if (tag == "EXTRACTOR_TITLE") +- return EXTRACTOR_TITLE; +- if (tag == "EXTRACTOR_AUTHOR") +- return EXTRACTOR_AUTHOR; +- if (tag == "EXTRACTOR_ARTIST") +- return EXTRACTOR_ARTIST; +- if (tag == "EXTRACTOR_DESCRIPTION") +- return EXTRACTOR_DESCRIPTION; +- if (tag == "EXTRACTOR_COMMENT") +- return EXTRACTOR_COMMENT; +- if (tag == "EXTRACTOR_DATE") +- return EXTRACTOR_DATE; +- if (tag == "EXTRACTOR_PUBLISHER") +- return EXTRACTOR_PUBLISHER; +- if (tag == "EXTRACTOR_LANGUAGE") +- return EXTRACTOR_LANGUAGE; +- if (tag == "EXTRACTOR_ALBUM") +- return EXTRACTOR_ALBUM; +- if (tag == "EXTRACTOR_GENRE") +- return EXTRACTOR_GENRE; +- if (tag == "EXTRACTOR_LOCATION") +- return EXTRACTOR_LOCATION; +- if (tag == "EXTRACTOR_VERSIONNUMBER") +- return EXTRACTOR_VERSIONNUMBER; +- if (tag == "EXTRACTOR_ORGANIZATION") +- return EXTRACTOR_ORGANIZATION; +- if (tag == "EXTRACTOR_COPYRIGHT") +- return EXTRACTOR_COPYRIGHT; +- if (tag == "EXTRACTOR_SUBJECT") +- return EXTRACTOR_SUBJECT; +- if (tag == "EXTRACTOR_KEYWORDS") +- return EXTRACTOR_KEYWORDS; +- if (tag == "EXTRACTOR_CONTRIBUTOR") +- return EXTRACTOR_CONTRIBUTOR; +- if (tag == "EXTRACTOR_RESOURCE_TYPE") +- return EXTRACTOR_RESOURCE_TYPE; +- if (tag == "EXTRACTOR_FORMAT") +- return EXTRACTOR_FORMAT; +- if (tag == "EXTRACTOR_RESOURCE_IDENTIFIER") +- return EXTRACTOR_RESOURCE_IDENTIFIER; +- if (tag == "EXTRACTOR_SOURCE") +- return EXTRACTOR_SOURCE; +- if (tag == "EXTRACTOR_RELATION") +- return EXTRACTOR_RELATION; +- if (tag == "EXTRACTOR_COVERAGE") +- return EXTRACTOR_COVERAGE; +- if (tag == "EXTRACTOR_SOFTWARE") +- return EXTRACTOR_SOFTWARE; +- if (tag == "EXTRACTOR_DISCLAIMER") +- return EXTRACTOR_DISCLAIMER; +- if (tag == "EXTRACTOR_WARNING") +- return EXTRACTOR_WARNING; +- if (tag == "EXTRACTOR_TRANSLATED") +- return EXTRACTOR_TRANSLATED; +- if (tag == "EXTRACTOR_CREATION_DATE") +- return EXTRACTOR_CREATION_DATE; +- if (tag == "EXTRACTOR_MODIFICATION_DATE") +- return EXTRACTOR_MODIFICATION_DATE; +- if (tag == "EXTRACTOR_CREATOR") +- return EXTRACTOR_CREATOR; +- if (tag == "EXTRACTOR_PRODUCER") +- return EXTRACTOR_PRODUCER; +- if (tag == "EXTRACTOR_PAGE_COUNT") +- return EXTRACTOR_PAGE_COUNT; +- if (tag == "EXTRACTOR_PAGE_ORIENTATION") +- return EXTRACTOR_PAGE_ORIENTATION; +- if (tag == "EXTRACTOR_PAPER_SIZE") +- return EXTRACTOR_PAPER_SIZE; +- if (tag == "EXTRACTOR_USED_FONTS") +- return EXTRACTOR_USED_FONTS; +- if (tag == "EXTRACTOR_PAGE_ORDER") +- return EXTRACTOR_PAGE_ORDER; +- if (tag == "EXTRACTOR_CREATED_FOR") +- return EXTRACTOR_CREATED_FOR; +- if (tag == "EXTRACTOR_MAGNIFICATION") +- return EXTRACTOR_MAGNIFICATION; +- if (tag == "EXTRACTOR_RELEASE") +- return EXTRACTOR_RELEASE; +- if (tag == "EXTRACTOR_GROUP") +- return EXTRACTOR_GROUP; +- if (tag == "EXTRACTOR_SIZE") +- return EXTRACTOR_SIZE; +- if (tag == "EXTRACTOR_SUMMARY") +- return EXTRACTOR_SUMMARY; +- if (tag == "EXTRACTOR_PACKAGER") +- return EXTRACTOR_PACKAGER; +- if (tag == "EXTRACTOR_VENDOR") +- return EXTRACTOR_VENDOR; +- if (tag == "EXTRACTOR_LICENSE") +- return EXTRACTOR_LICENSE; +- if (tag == "EXTRACTOR_DISTRIBUTION") +- return EXTRACTOR_DISTRIBUTION; +- if (tag == "EXTRACTOR_BUILDHOST") +- return EXTRACTOR_BUILDHOST; +- if (tag == "EXTRACTOR_OS") +- return EXTRACTOR_OS; +- if (tag == "EXTRACTOR_DEPENDENCY") +- return EXTRACTOR_DEPENDENCY; +- if (tag == "EXTRACTOR_HASH_MD4") +- return EXTRACTOR_HASH_MD4; +- if (tag == "EXTRACTOR_HASH_MD5") +- return EXTRACTOR_HASH_MD5; +- if (tag == "EXTRACTOR_HASH_SHA0") +- return EXTRACTOR_HASH_SHA0; +- if (tag == "EXTRACTOR_HASH_SHA1") +- return EXTRACTOR_HASH_SHA1; +- if (tag == "EXTRACTOR_HASH_RMD160") +- return EXTRACTOR_HASH_RMD160; +- if (tag == "EXTRACTOR_RESOLUTION") +- return EXTRACTOR_RESOLUTION; +- if (tag == "EXTRACTOR_CATEGORY") +- return EXTRACTOR_CATEGORY; +- if (tag == "EXTRACTOR_BOOKTITLE") +- return EXTRACTOR_BOOKTITLE; +- if (tag == "EXTRACTOR_PRIORITY") +- return EXTRACTOR_PRIORITY; +- if (tag == "EXTRACTOR_CONFLICTS") +- return EXTRACTOR_CONFLICTS; +- if (tag == "EXTRACTOR_REPLACES") +- return EXTRACTOR_REPLACES; +- if (tag == "EXTRACTOR_PROVIDES") +- return EXTRACTOR_PROVIDES; +- if (tag == "EXTRACTOR_CONDUCTOR") +- return EXTRACTOR_CONDUCTOR; +- if (tag == "EXTRACTOR_INTERPRET") +- return EXTRACTOR_INTERPRET; +- if (tag == "EXTRACTOR_OWNER") +- return EXTRACTOR_OWNER; +- if (tag == "EXTRACTOR_LYRICS") +- return EXTRACTOR_LYRICS; +- if (tag == "EXTRACTOR_MEDIA_TYPE") +- return EXTRACTOR_MEDIA_TYPE; +- if (tag == "EXTRACTOR_CONTACT") +- return EXTRACTOR_CONTACT; +- if (tag == "EXTRACTOR_THUMBNAIL_DATA") +- return EXTRACTOR_THUMBNAIL_DATA; +- +-#ifdef EXTRACTOR_GE_0_5_2 +- if (tag == "EXTRACTOR_PUBLICATION_DATE") +- return EXTRACTOR_PUBLICATION_DATE; +- if (tag == "EXTRACTOR_CAMERA_MAKE") +- return EXTRACTOR_CAMERA_MAKE; +- if (tag == "EXTRACTOR_CAMERA_MODEL") +- return EXTRACTOR_CAMERA_MODEL; +- if (tag == "EXTRACTOR_EXPOSURE") +- return EXTRACTOR_EXPOSURE; +- if (tag == "EXTRACTOR_APERTURE") +- return EXTRACTOR_APERTURE; +- if (tag == "EXTRACTOR_EXPOSURE_BIAS") +- return EXTRACTOR_EXPOSURE_BIAS; +- if (tag == "EXTRACTOR_FLASH") +- return EXTRACTOR_FLASH; +- if (tag == "EXTRACTOR_FLASH_BIAS") +- return EXTRACTOR_FLASH_BIAS; +- if (tag == "EXTRACTOR_FOCAL_LENGTH") +- return EXTRACTOR_FOCAL_LENGTH; +- if (tag == "EXTRACTOR_FOCAL_LENGTH_35MM") +- return EXTRACTOR_FOCAL_LENGTH_35MM; +- if (tag == "EXTRACTOR_ISO_SPEED") +- return EXTRACTOR_ISO_SPEED; +- if (tag == "EXTRACTOR_EXPOSURE_MODE") +- return EXTRACTOR_EXPOSURE_MODE; +- if (tag == "EXTRACTOR_METERING_MODE") +- return EXTRACTOR_METERING_MODE; +- if (tag == "EXTRACTOR_MACRO_MODE") +- return EXTRACTOR_MACRO_MODE; +- if (tag == "EXTRACTOR_IMAGE_QUALITY") +- return EXTRACTOR_IMAGE_QUALITY; +- if (tag == "EXTRACTOR_WHITE_BALANCE") +- return EXTRACTOR_WHITE_BALANCE; +- if (tag == "EXTRACTOR_ORIENTATION") +- return EXTRACTOR_ORIENTATION; +-#endif // EXTRACTOR_GE_0_5_2 ++#define T(x) [EXTRACTOR_METATYPE_##x] = "EXTRACTOR_METATYPE_"#x, ++ /* XXX: should convert to EXTRACTOR_metatype_to_string() somehow */ ++ const char *types[] = ++ { ++ T(RESERVED) ++ T(MIMETYPE) ++ T(FILENAME) ++ T(COMMENT) ++ ++ T(TITLE) ++ T(BOOK_TITLE) ++ T(BOOK_EDITION) ++ T(BOOK_CHAPTER_NUMBER) ++ T(JOURNAL_NAME) ++ T(JOURNAL_VOLUME) ++ T(JOURNAL_NUMBER) ++ T(PAGE_COUNT) ++ T(PAGE_RANGE) ++ T(AUTHOR_NAME) ++ T(AUTHOR_EMAIL) ++ T(AUTHOR_INSTITUTION) ++ T(PUBLISHER) ++ T(PUBLISHER_ADDRESS) ++ T(PUBLISHER_INSTITUTION) ++ T(PUBLISHER_SERIES) ++ T(PUBLICATION_TYPE) ++ T(PUBLICATION_YEAR) ++ T(PUBLICATION_MONTH) ++ T(PUBLICATION_DAY) ++ T(PUBLICATION_DATE) ++ T(BIBTEX_EPRINT) ++ T(BIBTEX_ENTRY_TYPE) ++ T(LANGUAGE) ++ T(CREATION_TIME) ++ T(URL) ++ ++ T(URI) ++ T(ISRC) ++ T(HASH_MD4) ++ T(HASH_MD5) ++ T(HASH_SHA0) ++ T(HASH_SHA1) ++ T(HASH_RMD160) ++ ++ T(GPS_LATITUDE_REF) ++ T(GPS_LATITUDE) ++ T(GPS_LONGITUDE_REF) ++ T(GPS_LONGITUDE) ++ T(LOCATION_CITY) ++ T(LOCATION_SUBLOCATION) ++ T(LOCATION_COUNTRY) ++ T(LOCATION_COUNTRY_CODE) ++ ++ T(UNKNOWN) ++ T(DESCRIPTION) ++ T(COPYRIGHT) ++ T(RIGHTS) ++ T(KEYWORDS) ++ T(ABSTRACT) ++ T(SUMMARY) ++ T(SUBJECT) ++ T(CREATOR) ++ T(FORMAT) ++ T(FORMAT_VERSION) ++ ++ T(CREATED_BY_SOFTWARE) ++ T(UNKNOWN_DATE) ++ T(CREATION_DATE) ++ T(MODIFICATION_DATE) ++ T(LAST_PRINTED) ++ T(LAST_SAVED_BY) ++ T(TOTAL_EDITING_TIME) ++ T(EDITING_CYCLES) ++ T(MODIFIED_BY_SOFTWARE) ++ T(REVISION_HISTORY) ++ ++ T(EMBEDDED_FILE_SIZE) ++ T(FINDER_FILE_TYPE) ++ T(FINDER_FILE_CREATOR) ++ ++ T(PACKAGE_NAME) ++ T(PACKAGE_VERSION) ++ T(SECTION) ++ T(UPLOAD_PRIORITY) ++ T(PACKAGE_DEPENDENCY) ++ T(PACKAGE_CONFLICTS) ++ T(PACKAGE_REPLACES) ++ T(PACKAGE_PROVIDES) ++ T(PACKAGE_RECOMMENDS) ++ T(PACKAGE_SUGGESTS) ++ T(PACKAGE_MAINTAINER) ++ T(PACKAGE_INSTALLED_SIZE) ++ T(PACKAGE_SOURCE) ++ T(PACKAGE_ESSENTIAL) ++ T(TARGET_ARCHITECTURE) ++ T(PACKAGE_PRE_DEPENDENCY) ++ T(LICENSE) ++ T(PACKAGE_DISTRIBUTION) ++ T(BUILDHOST) ++ T(VENDOR) ++ T(TARGET_OS) ++ T(SOFTWARE_VERSION) ++ T(TARGET_PLATFORM) ++ T(RESOURCE_TYPE) ++ T(LIBRARY_SEARCH_PATH) ++ T(LIBRARY_DEPENDENCY) ++ ++ T(CAMERA_MAKE) ++ T(CAMERA_MODEL) ++ T(EXPOSURE) ++ T(APERTURE) ++ T(EXPOSURE_BIAS) ++ T(FLASH) ++ T(FLASH_BIAS) ++ T(FOCAL_LENGTH) ++ T(FOCAL_LENGTH_35MM) ++ T(ISO_SPEED) ++ T(EXPOSURE_MODE) ++ T(METERING_MODE) ++ T(MACRO_MODE) ++ T(IMAGE_QUALITY) ++ T(WHITE_BALANCE) ++ T(ORIENTATION) ++ T(MAGNIFICATION) ++ ++ T(IMAGE_DIMENSIONS) ++ T(PRODUCED_BY_SOFTWARE) ++ T(THUMBNAIL) ++ T(IMAGE_RESOLUTION) ++ T(SOURCE) ++ ++ T(CHARACTER_SET) ++ T(LINE_COUNT) ++ T(PARAGRAPH_COUNT) ++ T(WORD_COUNT) ++ T(CHARACTER_COUNT) ++ T(PAGE_ORIENTATION) ++ T(PAPER_SIZE) ++ T(TEMPLATE) ++ T(COMPANY) ++ T(MANAGER) ++ T(REVISION_NUMBER) ++ ++ T(DURATION) ++ T(ALBUM) ++ T(ARTIST) ++ T(GENRE) ++ T(TRACK_NUMBER) ++ T(DISC_NUMBER) ++ T(PERFORMER) ++ T(CONTACT_INFORMATION) ++ T(SONG_VERSION) ++ T(PICTURE) ++ T(COVER_PICTURE) ++ T(CONTRIBUTOR_PICTURE) ++ T(EVENT_PICTURE) ++ T(LOGO) ++ T(BROADCAST_TELEVISION_SYSTEM) ++ T(SOURCE_DEVICE) ++ T(DISCLAIMER) ++ T(WARNING) ++ T(PAGE_ORDER) ++ T(WRITER) ++ T(PRODUCT_VERSION) ++ T(CONTRIBUTOR_NAME) ++ T(MOVIE_DIRECTOR) ++ T(NETWORK_NAME) ++ T(SHOW_NAME) ++ T(CHAPTER_NAME) ++ T(SONG_COUNT) ++ T(STARTING_SONG) ++ T(PLAY_COUNTER) ++ T(CONDUCTOR) ++ T(INTERPRETATION) ++ T(COMPOSER) ++ T(BEATS_PER_MINUTE) ++ T(ENCODED_BY) ++ T(ORIGINAL_TITLE) ++ T(ORIGINAL_ARTIST) ++ T(ORIGINAL_WRITER) ++ T(ORIGINAL_RELEASE_YEAR) ++ T(ORIGINAL_PERFORMER) ++ T(LYRICS) ++ T(POPULARITY_METER) ++ T(LICENSEE) ++ T(MUSICIAN_CREDITS_LIST) ++ T(MOOD) ++ T(SUBTITLE) ++ ++ T(GNUNET_DISPLAY_TYPE) ++ T(GNUNET_FULL_DATA) ++ T(RATING) ++ T(ORGANIZATION) ++ T(RIPPER) ++ T(PRODUCER) ++ T(GROUP) ++ T(GNUNET_ORIGINAL_FILENAME) ++ }; ++#undef T ++ size_t i; ++ ++ for (i = 0; i < sizeof(types) / sizeof(types[0]); ++i) ++ if (!strcmp(types[i], tag.c_str())) ++ return (EXTRACTOR_MetaType) i; + + log_warning("Ignoring unknown libextractor tag: %s\n", tag.c_str()); +- return EXTRACTOR_UNKNOWN; ++ return EXTRACTOR_METATYPE_UNKNOWN; + } + +-static void addMetaField(metadata_fields_t field, EXTRACTOR_KeywordList *keywords, Ref<CdsItem> item, Ref<StringConverter> sc) ++struct field_state { ++ Ref<CdsItem> item; ++ Ref<StringConverter> sc; ++ Ref<Array<StringBase> > aux; ++}; ++ ++static int addField(void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, ++ enum EXTRACTOR_MetaFormat format, const char *data_mime_type, ++ const char *data, size_t data_len) + { +- String value; +- const char *temp = NULL; +- ++ metadata_fields_t field = M_MAX; ++ resource_attributes_t attr = R_MAX; ++ ++ if (!data) ++ return 0; ++ ++ log_debug("metadata %zu [%s] -> %s\n", (size_t)type, EXTRACTOR_metatype_to_string(type), data); ++ + /// \todo check if UTF-8 conversion is needed, may already be in UTF-8 +- +- switch (field) ++ ++ switch (type) + { +- case M_TITLE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_TITLE, keywords); ++ case EXTRACTOR_METATYPE_TITLE: ++ field = M_TITLE; + break; +- case M_ARTIST: +- temp = EXTRACTOR_extractLast(EXTRACTOR_ARTIST, keywords); ++ case EXTRACTOR_METATYPE_ARTIST: ++ field = M_ARTIST; + break; +- case M_ALBUM: +- temp = EXTRACTOR_extractLast(EXTRACTOR_ALBUM, keywords); ++ case EXTRACTOR_METATYPE_ALBUM: ++ field = M_ALBUM; + break; +- case M_DATE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_DATE, keywords); ++ case EXTRACTOR_METATYPE_PUBLICATION_YEAR: ++ field = M_DATE; + break; +- case M_GENRE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_GENRE, keywords); ++ case EXTRACTOR_METATYPE_GENRE: ++ field = M_GENRE; + break; +- case M_DESCRIPTION: +- temp = EXTRACTOR_extractLast(EXTRACTOR_DESCRIPTION, keywords); +- +- if (temp == NULL) +- temp = EXTRACTOR_extractLast(EXTRACTOR_COMMENT, keywords); ++ case EXTRACTOR_METATYPE_DESCRIPTION: ++ field = M_DESCRIPTION; ++ break; ++ case EXTRACTOR_METATYPE_COMMENT: ++ field = M_DESCRIPTION; ++ break; ++ case EXTRACTOR_METATYPE_IMAGE_DIMENSIONS: ++ attr = R_RESOLUTION; + break; +- default: +- return; + } + +- if (temp != NULL) +- value = temp; ++ String value; ++ struct field_state *field_state = (struct field_state *)cls; ++ Ref<CdsItem> item = field_state->item; ++ Ref<StringConverter> sc = field_state->sc; ++ Ref<Array<StringBase> > aux = field_state->aux; ++ ++ if (field == M_MAX && attr == R_MAX && aux == nil) ++ { ++ log_debug("no match\n"); ++ return 0; ++ } + ++ value = data; + value = trim_string(value); +- +- if (string_ok(value)) ++ if (!string_ok(value)) ++ return 0; ++ ++ if (field != M_MAX) + { + item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); +-// log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str()); ++ log_debug("Setting metadata on item: %d, %s\n", field, sc->convert(value).c_str()); + } +-} + +-static void addResourceField(resource_attributes_t attr, EXTRACTOR_KeywordList *keywords, Ref<CdsItem> item, Ref<StringConverter> sc) +-{ +- String value; +- const char *temp = NULL; +- +- switch (attr) ++ if (attr != R_MAX) + { +- case R_RESOLUTION: +- temp = EXTRACTOR_extractLast(EXTRACTOR_SIZE, keywords); +- break; +-/* case R_SIZE: +- temp = EXTRACTOR_extractLast(EXTRACTOR_SIZE, keywords); +- break; +-*/ +- default: +- return; ++ item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(attr), value); ++ log_debug("Setting attribute on item: %d, %s\n", attr, value.c_str()); + } + +- if (temp != NULL) +- value = temp; +- +- if (string_ok(value)) ++ if (aux != nil) + { +- item->getResource(0)->addAttribute(MetadataHandler::getResAttrName(attr), value); ++ String tmp; ++ for (int j = 0; j < aux->size(); j++) ++ { ++ tmp = aux->get(j); ++ if (string_ok(tmp)) ++ { ++ if (type == getTagFromString(tmp)) ++ { ++ value = sc->convert(value); ++ item->setAuxData(tmp, value); ++ log_debug(("Adding tag: %s with value %s\n", tmp.c_str(), value.c_str())); ++ } ++ } ++ } + } ++ ++ return 0; + } + + + +-Ref<RExp> ReAudioFormat; +-EXTRACTOR_ExtractorList *extractors = NULL; +-bool load_libraries_failed = false; ++static Ref<RExp> ReAudioFormat; ++static EXTRACTOR_PluginList *plugins = NULL; ++static bool load_libraries_failed = false; + + void ExtractorHandler::fillMetadata(Ref<CdsItem> item) + { + if (load_libraries_failed) + return; +- Ref<Array<StringBase> > aux; +- Ref<StringConverter> sc = StringConverter::i2i(); +- +- if (! extractors) ++ if (! plugins) + { +- extractors = EXTRACTOR_loadDefaultLibraries(); +- if (! extractors) ++ plugins = EXTRACTOR_plugin_add_defaults(EXTRACTOR_OPTION_DEFAULT_POLICY); ++ if (! plugins) ++ { + load_libraries_failed = true; ++ return; ++ } + } +- EXTRACTOR_KeywordList *keywords = EXTRACTOR_getKeywords(extractors, item->getLocation().c_str()); +- +- //EXTRACTOR_printKeywords(stdout, keywords); + +- for (int i = 0; i < M_MAX; i++) +- addMetaField((metadata_fields_t)i, keywords, item, sc); +- +- for (int i = 0; i < R_MAX; i++) +- addResourceField((resource_attributes_t)i, keywords, item, sc); ++ log_debug("processing %s\n", item->getLocation().c_str()); + + Ref<ConfigManager> cm = ConfigManager::getInstance(); +- aux = cm->getStringArrayOption(CFG_IMPORT_LIBOPTS_EXTRACTOR_AUXDATA_TAGS_LIST); +- if (aux != nil) +- { +- String value; +- String tmp; +- const char *temp = NULL; +- +- for (int j = 0; j < aux->size(); j++) +- { +- +- tmp = aux->get(j); +- if (string_ok(tmp)) +- { +- temp = EXTRACTOR_extractLast(getTagFromString(tmp), keywords); +- if (temp != NULL) +- { +- value = temp; +- if (string_ok(value)) +- { +- value = sc->convert(value); +- item->setAuxData(tmp, value); +-// log_debug(("Adding tag: %s with value %s\n", tmp.c_str(), value.c_str())); +- } +- } +- } +- } +- } ++ struct field_state field_state = { ++ .item = item, ++ .sc = StringConverter::i2i(), ++ .aux = cm->getStringArrayOption(CFG_IMPORT_LIBOPTS_EXTRACTOR_AUXDATA_TAGS_LIST), ++ }; ++ EXTRACTOR_extract(plugins, item->getLocation().c_str(), NULL, 0, addField, &field_state); + + if (ReAudioFormat == nil) + { +@@ -379,35 +401,9 @@ void ExtractorHandler::fillMetadata(Ref<CdsItem> item) + ReAudioFormat->compile(_("([0-9]+)\\s+kbps,\\s*([0-9]+)\\s+hz,\\s*" + "(([0-9]+)h)?([0-9]+)m([0-9]+)\\s(\\S+)"), "i"); + } +- +- /* +- temp = EXTRACTOR_extractLast(EXTRACTOR_FORMAT, keywords); +- log_debug("EXTRACTOR_FORMAT: %s\n", temp); +- +- if (temp) +- { +- Ref<Matcher> matcher = ReAudioFormat->match((char *)temp); +- if (matcher != nil) +- { +- log_debug(("BR:%s FR:%s H:%s M:%s S:%s TYPE:%s\n", +- matcher->group(1).c_str(), +- matcher->group(2).c_str(), +- matcher->group(4).c_str(), +- matcher->group(5).c_str(), +- matcher->group(6).c_str(), +- matcher->group(7).c_str())); +- } +- else +- { +- log_debug(("format pattern unmatched!")); +- } +- } +- +- */ +- EXTRACTOR_freeKeywords(keywords); + + // commented out for the sake of efficiency +- // EXTRACTOR_removeAll(extractors); ++ // EXTRACTOR_plugin_remove_all(plugins); + } + + Ref<IOHandler> ExtractorHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-libmp4v2.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-libmp4v2.patch new file mode 100644 index 000000000000..6a6b51e1e05a --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-libmp4v2.patch @@ -0,0 +1,187 @@ +diff -urN old/src/metadata/libmp4v2_handler.cc new/src/metadata/libmp4v2_handler.cc +--- old/src/metadata/libmp4v2_handler.cc 2012-04-05 01:46:26.000000000 +0200 ++++ new/src/metadata/libmp4v2_handler.cc 2012-04-05 02:01:24.000000000 +0200 +@@ -65,29 +65,28 @@ + static void addMetaField(metadata_fields_t field, MP4FileHandle mp4, Ref<CdsItem> item) + { + String value; +- char* mp4_retval = NULL; +- u_int16_t track; +- u_int16_t total_tracks; +- + Ref<StringConverter> sc = StringConverter::i2i(); + ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ ++ if (!MP4TagsFetch(new_tags, mp4)) ++ return; ++ + switch (field) + { + case M_TITLE: +- MP4GetMetadataName(mp4, &mp4_retval); ++ value = new_tags->name; + break; + case M_ARTIST: +- MP4GetMetadataArtist(mp4, &mp4_retval); ++ value = new_tags->artist; + break; + case M_ALBUM: +- MP4GetMetadataAlbum(mp4, &mp4_retval); ++ value = new_tags->album; + break; + case M_DATE: +- MP4GetMetadataYear(mp4, &mp4_retval); +- if (mp4_retval) ++ value = new_tags->releaseDate; ++ if (value.length() > 0) + { +- value = mp4_retval; +- free(mp4_retval); + if (string_ok(value)) + value = value + "-01-01"; + else +@@ -95,34 +94,31 @@ + } + break; + case M_GENRE: +- MP4GetMetadataGenre(mp4, &mp4_retval); ++ value = new_tags->genre; + break; + case M_DESCRIPTION: +- MP4GetMetadataComment(mp4, &mp4_retval); ++ value = new_tags->comments; + break; + case M_TRACKNUMBER: +- MP4GetMetadataTrack(mp4, &track, &total_tracks); +- if (track > 0) ++ if (new_tags->track) + { +- value = String::from(track); +- item->setTrackNumber((int)track); ++ value = String::from(new_tags->track->index); ++ item->setTrackNumber((int)new_tags->track->index); + } + else ++ { ++ MP4TagsFree( new_tags ); + return; ++ } + break; + default: ++ MP4TagsFree( new_tags ); + return; + } + +- if ((field != M_DATE) && (field != M_TRACKNUMBER) && +- (mp4_retval)) +- { +- value = mp4_retval; +- free(mp4_retval); +- } +- ++ MP4TagsFree( new_tags ); + value = trim_string(value); +- ++ + if (string_ok(value)) + { + item->setMetadata(MT_KEYS[field].upnp, sc->convert(value)); +@@ -190,14 +186,19 @@ + } + + #if defined(HAVE_MAGIC) +- u_int8_t *art_data; +- u_int32_t art_data_len; ++ void *art_data = 0; ++ u_int32_t art_data_len = 0; + String art_mimetype; ++ ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ MP4TagsFetch(new_tags, mp4); ++ if (new_tags->artworkCount) ++ { ++ art_data = new_tags->artwork->data; ++ art_data_len = new_tags->artwork->size; ++ } + #ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT +- if (MP4GetMetadataCoverArtCount(mp4) && +- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len)) +-#else +- MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len); ++ if (new_tags->artworkCount && art_data_len > 0) + #endif + { + if (art_data) +@@ -211,11 +212,10 @@ + } + catch (Exception ex) + { +- free(art_data); ++ MP4TagsFree(new_tags); + throw ex; + } + +- free(art_data); + if (art_mimetype != _(MIMETYPE_DEFAULT)) + { + Ref<CdsResource> resource(new CdsResource(CH_MP4)); +@@ -225,6 +225,7 @@ + } + } + } ++ MP4TagsFree(new_tags); + #endif + MP4Close(mp4); + } +@@ -249,26 +250,35 @@ + + if (ctype != ID3_ALBUM_ART) + throw _Exception(_("LibMP4V2Handler: got unknown content type: ") + ctype); ++ ++ const MP4Tags* new_tags = MP4TagsAlloc(); ++ if (MP4TagsFetch(new_tags, mp4)) ++ { + #ifdef HAVE_MP4_GET_METADATA_COVER_ART_COUNT +- if (!MP4GetMetadataCoverArtCount(mp4)) +- throw _Exception(_("LibMP4V2Handler: resource has no album art information")); ++ if (!new_tags->artworkCount) ++ throw _Exception(_("LibMP4V2Handler: resource has no album art information")); + #endif +- u_int8_t *art_data; +- u_int32_t art_data_len; +- if (MP4GetMetadataCoverArt(mp4, &art_data, &art_data_len)) +- { +- if (art_data) ++ void *art_data = 0; ++ u_int32_t art_data_len; ++ ++ const MP4TagArtwork* art = new_tags->artwork; ++ art_data = art->data; ++ art_data_len = art->size; ++ if (art) + { +- *data_size = (off_t)art_data_len; +- Ref<IOHandler> h(new MemIOHandler((void *)art_data, art_data_len)); +- free(art_data); +- return h; ++ if (art_data) ++ { ++ *data_size = (off_t)art_data_len; ++ Ref<IOHandler> h(new MemIOHandler(art_data, art_data_len)); ++ MP4TagsFree(new_tags); ++ return h; ++ } + } ++ MP4TagsFree(new_tags); + } +- + throw _Exception(_("LibMP4V2Handler: could not serve album art " +- "for file") + item->getLocation() + +- " - embedded image not found"); ++ "for file") + item->getLocation() + ++ " - embedded image not found"); + } + + #endif // HAVE_LIBMP4V2 +De binära filerna old/src/metadata/.libmp4v2_handler.cc.swp och new/src/metadata/.libmp4v2_handler.cc.swp skiljer diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-mozjs187.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-mozjs187.patch new file mode 100644 index 000000000000..c4b080a3656b --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-mozjs187.patch @@ -0,0 +1,260 @@ +maybe this is correct, maybe it's not. spidermonkey's documentation blows, so +who is to say! + +https://bugs.gentoo.org/423991 + +--- a/src/scripting/dvd_image_import_script.cc ++++ b/src/scripting/dvd_image_import_script.cc +@@ -232,8 +232,6 @@ DVDImportScript::DVDImportScript(Ref<Runtime> runtime) : Script(runtime) + + String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_DVD_SCRIPT); + load(scriptPath); +- root = JS_NewScriptObject(cx, script); +- JS_AddNamedRoot(cx, &root, "DVDImportScript"); + log_info("Loaded %s\n", scriptPath.c_str()); + + Ref<Dictionary> mappings = +@@ -296,21 +294,4 @@ void DVDImportScript::processDVDObject(Ref<CdsObject> obj) + #endif + } + +-DVDImportScript::~DVDImportScript() +-{ +-#ifdef JS_THREADSAFE +- JS_SetContextThread(cx); +- JS_BeginRequest(cx); +-#endif +- +- if (root) +- JS_RemoveRoot(cx, &root); +- +-#ifdef JS_THREADSAFE +- JS_EndRequest(cx); +- JS_ClearContextThread(cx); +-#endif +- +-} +- + #endif // HAVE_JS +--- a/src/scripting/dvd_image_import_script.h ++++ b/src/scripting/dvd_image_import_script.h +@@ -41,7 +41,6 @@ class DVDImportScript : public Script + { + public: + DVDImportScript(zmm::Ref<Runtime> runtime); +- ~DVDImportScript(); + /// \brief Adds a DVD object to the database + /// + /// \param title DVD title number +--- a/src/scripting/import_script.cc ++++ b/src/scripting/import_script.cc +@@ -53,8 +53,6 @@ ImportScript::ImportScript(Ref<Runtime> runtime) : Script(runtime) + try + { + load(scriptPath); +- root = JS_NewObject(cx, NULL, script, NULL); +- JS_AddNamedObjectRoot(cx, &root, "ImportScript"); + } + catch (Exception ex) + { +@@ -109,21 +107,4 @@ void ImportScript::processCdsObject(Ref<CdsObject> obj, String rootpath) + #endif + } + +-ImportScript::~ImportScript() +-{ +-#ifdef JS_THREADSAFE +- JS_SetContextThread(cx); +- JS_BeginRequest(cx); +-#endif +- +- if (root) +- JS_RemoveObjectRoot(cx, &root); +- +-#ifdef JS_THREADSAFE +- JS_EndRequest(cx); +- JS_ClearContextThread(cx); +-#endif +- +-} +- + #endif // HAVE_JS +--- a/src/scripting/import_script.h ++++ b/src/scripting/import_script.h +@@ -41,11 +41,8 @@ class ImportScript : public Script + { + public: + ImportScript(zmm::Ref<Runtime> runtime); +- ~ImportScript(); + void processCdsObject(zmm::Ref<CdsObject> obj, zmm::String rootpath); + virtual script_class_t whoami() { return S_IMPORT; } +-private: +- JSObject *root; + }; + + #endif // __SCRIPTING_IMPORT_SCRIPT_H__ +--- a/src/scripting/playlist_parser_script.cc ++++ b/src/scripting/playlist_parser_script.cc +@@ -93,8 +93,6 @@ PlaylistParserScript::PlaylistParserScript(Ref<Runtime> runtime) : Script(runtim + + String scriptPath = ConfigManager::getInstance()->getOption(CFG_IMPORT_SCRIPTING_PLAYLIST_SCRIPT); + load(scriptPath); +- root = JS_NewObject(cx, NULL, script, NULL); +- JS_AddNamedObjectRoot(cx, &root, "PlaylistScript"); + } + catch (Exception ex) + { +@@ -236,21 +234,4 @@ void PlaylistParserScript::processPlaylistObject(zmm::Ref<CdsObject> obj, Ref<Ge + + } + +- +-PlaylistParserScript::~PlaylistParserScript() +-{ +-#ifdef JS_THREADSAFE +- JS_SetContextThread(cx); +- JS_BeginRequest(cx); +-#endif +- +- if (root) +- JS_RemoveObjectRoot(cx, &root); +- +-#ifdef JS_THREADSAFE +- JS_EndRequest(cx); +- JS_ClearContextThread(cx); +-#endif +- +-} + #endif // HAVE_JS +--- a/src/scripting/playlist_parser_script.h ++++ b/src/scripting/playlist_parser_script.h +@@ -42,7 +42,6 @@ class PlaylistParserScript : public Script + { + public: + PlaylistParserScript(zmm::Ref<Runtime> runtime); +- ~PlaylistParserScript(); + zmm::String readln(); + void processPlaylistObject(zmm::Ref<CdsObject> obj, zmm::Ref<GenericTask> task); + virtual script_class_t whoami() { return S_PLAYLIST; } +@@ -52,7 +51,6 @@ private: + int currentObjectID; + char *currentLine; + zmm::Ref<GenericTask> currentTask; +- JSObject *root; + }; + + #endif // __SCRIPTING_PLAYLIST_PARSER_SCRIPT_H__ +--- a/src/scripting/script.cc ++++ b/src/scripting/script.cc +@@ -427,15 +427,10 @@ static JSFunctionSpec js_global_functions[] = { + try + { + common_script = _load(common_scr_path); +- common_root = JS_NewObject(cx, NULL, common_script, NULL); +- JS_AddNamedObjectRoot(cx, &common_root, "common-script"); + _execute(common_script); + } + catch (Exception e) + { +- if (common_root) +- JS_RemoveObjectRoot(cx, &common_root); +- + log_js("Unable to load %s: %s\n", common_scr_path.c_str(), + e.getMessage().c_str()); + } +@@ -459,8 +454,6 @@ Script::~Script() + JS_SetContextThread(cx); + JS_BeginRequest(cx); + #endif +- if (common_root) +- JS_RemoveObjectRoot(cx, &common_root); + + /* + * scripts are unrooted and will be cleaned up by GC +@@ -532,12 +532,12 @@ void Script::defineFunctions(JSFunctionSpec *functions) + throw _Exception(_("Scripting: JS_DefineFunctions failed")); + } + +-JSObject *Script::_load(zmm::String scriptPath) ++JSScript *Script::_load(zmm::String scriptPath) + { + if (glob == NULL) + initGlobalObject(); + +- JSObject *scr; ++ JSScript *scr; + + String scriptText = read_text_file(scriptPath); + +@@ -568,7 +568,7 @@ void Script::load(zmm::String scriptPath) + } + + +-void Script::_execute(JSObject *scr) ++void Script::_execute(JSScript *scr) + { + jsval ret_val; + +--- a/src/scripting/script.h ++++ b/src/scripting/script.h +@@ -66,8 +66,8 @@ public: + JSRuntime *rt; + JSContext *cx; + JSObject *glob; +- JSObject *script; +- JSObject *common_script; ++ JSScript *script; ++ JSScript *common_script; + + public: + Script(zmm::Ref<Runtime> runtime); +@@ -112,11 +112,9 @@ protected: + zmm::Ref<CdsObject> processed; + + private: +- JSObject *common_root; +- + void initGlobalObject(); +- JSObject *_load(zmm::String scriptPath); +- void _execute(JSObject *scr); ++ JSScript *_load(zmm::String scriptPath); ++ void _execute(JSScript *scr); + zmm::Ref<StringConverter> _p2i; + zmm::Ref<StringConverter> _j2i; + zmm::Ref<StringConverter> _f2i; +--- a/configure.ac ++++ b/configure.ac +@@ -1036,13 +1036,13 @@ + ], + [ + unset ac_cv_lib_smjs_JS_NewObject +- AC_CHECK_LIB(mozjs185, JS_NewObject, ++ AC_CHECK_LIB(mozjs187, JS_NewObject, + [ +- MOZLIB=mozjs185 +- JS_LIBS="-lmozjs185" ++ MOZLIB=mozjs187 ++ JS_LIBS="-lmozjs187" + ], + [ +- unset ac_cv_lib_mozjs185_JS_NewObject ++ unset ac_cv_lib_mozjs187_JS_NewObject + AC_CHECK_LIB(mozjs, JS_NewObject, + [ + MOZLIB=mozjs +@@ -1064,11 +1064,11 @@ + MOZLIB=smjs + ], + [ +- unset ac_cv_lib_mozjs185_JS_NewObject +- AC_CHECK_LIB(mozjs185, JS_NewObject, ++ unset ac_cv_lib_mozjs187_JS_NewObject ++ AC_CHECK_LIB(mozjs187, JS_NewObject, + [ +- JS_LIBS="-L$SEARCH_DIR_LIBS -lmozjs185" +- MOZLIB=mozjs185 ++ JS_LIBS="-L$SEARCH_DIR_LIBS -lmozjs187" ++ MOZLIB=mozjs187 + ], + [ + LDFLAGS="-L$SEARCH_DIR_LIBS $LDFLAGS_SAVE -lmozjs" diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-system-ar.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-system-ar.patch new file mode 100644 index 000000000000..349bf7d8da74 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-system-ar.patch @@ -0,0 +1,35 @@ +--- configure.ac 2010-04-08 00:38:51.000000000 +0200 ++++ configure.ac 2013-05-30 12:27:55.620514386 +0200 +@@ -318,6 +318,10 @@ + AC_PROG_CC + AC_PROG_RANLIB + AC_PROG_GCC_TRADITIONAL ++AN_MAKEVAR([AR], [AC_PROG_AR]) ++AN_PROGRAM([ar], [AC_PROG_AR]) ++AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)]) ++AC_PROG_AR + AC_HEADER_DIRENT + AC_HEADER_STDC + AC_HEADER_SYS_WAIT +--- build/Makefile.in 2010-04-08 00:40:15.000000000 +0200 ++++ build/Makefile.in 2013-05-30 12:25:55.310337928 +0200 +@@ -50,7 +50,7 @@ + CONFIG_CLEAN_FILES = + CONFIG_CLEAN_VPATH_FILES = + LIBRARIES = $(noinst_LIBRARIES) +-AR = ar ++AR = @AR@ + ARFLAGS = cru + libmediatomb_a_AR = $(AR) $(ARFLAGS) + libmediatomb_a_LIBADD = +--- tombupnp/build/Makefile.in 2010-04-08 00:40:16.000000000 +0200 ++++ tombupnp/build/Makefile.in 2013-05-30 12:26:18.420371823 +0200 +@@ -48,7 +48,7 @@ + CONFIG_CLEAN_FILES = + CONFIG_CLEAN_VPATH_FILES = + LIBRARIES = $(noinst_LIBRARIES) +-AR = ar ++AR = @AR@ + ARFLAGS = cru + libtombupnp_a_AR = $(AR) $(ARFLAGS) + libtombupnp_a_LIBADD = diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-system-uuid.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-system-uuid.patch new file mode 100644 index 000000000000..053f18cea879 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-system-uuid.patch @@ -0,0 +1,36 @@ +use libuuid from the system rather than local bundled code + +http://bugs.gentoo.org/270830 + +--- a/build/Makefile.am ++++ b/build/Makefile.am +@@ -58,6 +58,7 @@ mediatomb_CXXFLAGS = -I$(top_srcdir)/src \ + mediatomb_LDADD = \ + libmediatomb.a \ + $(top_srcdir)/tombupnp/build/libtombupnp.a \ ++ -luuid \ + $(LIBEXIF_LDFLAGS) \ + $(ZLIB_LDFLAGS) \ + $(EXPAT_LDFLAGS) \ +--- a/build/libmediatomb_src ++++ b/build/libmediatomb_src +@@ -231,19 +231,6 @@ libmediatomb_a_SOURCES = \ + ../src/url.h \ + ../src/url_request_handler.cc \ + ../src/url_request_handler.h \ +-../src/uuid/clear.c \ +-../src/uuid/compare.c \ +-../src/uuid/copy.c \ +-../src/uuid/gen_uuid.c \ +-../src/uuid/isnull.c \ +-../src/uuid/pack.c \ +-../src/uuid/parse.c \ +-../src/uuid/unpack.c \ +-../src/uuid/unparse.c \ +-../src/uuid/uuid.h \ +-../src/uuid/uuidP.h \ +-../src/uuid/uuid_time.c \ +-../src/uuid/uuid_types.h \ + ../src/web/action.cc \ + ../src/web/add.cc \ + ../src/web/add_object.cc \ diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch new file mode 100644 index 000000000000..3d357b4392aa --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-thumb-cache.patch @@ -0,0 +1,237 @@ +http://sourceforge.net/tracker/?func=detail&aid=3291468&group_id=129766&atid=715782 + +[PATCH] Add the cache feature of ffmpegthumbnailer. + +I want the cache feature of ffmpegthumbnailer because my machine +is not powerful :-( +So I created this patch for the cache feature. + +This patch adds a new option "cache-dir" in config.xml. +If not specifying any string, the cache feature is disable. +And specifying some directory, the cache feature is enable +and the cache files will be created under the directory. + +Signed-off-by: Ken'ichi Ohmichi <ken1ohmichi@gmail.com> +--- +diff --git a/src/common.h b/src/common.h +index d1998b3..358f4d1 100644 +--- a/src/common.h ++++ b/src/common.h +@@ -367,6 +367,8 @@ + #define DEFAULT_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY YES + #define DEFAULT_FFMPEGTHUMBNAILER_WORKAROUND_BUGS NO + #define DEFAULT_FFMPEGTHUMBNAILER_IMAGE_QUALITY 8 ++ #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED YES ++ #define DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR "" + #endif + + #if defined(HAVE_LASTFMLIB) +diff --git a/src/config_manager.cc b/src/config_manager.cc +index 8c975f8..2902090 100644 +--- a/src/config_manager.cc ++++ b/src/config_manager.cc +@@ -1873,6 +1873,24 @@ void ConfigManager::validate(String serverhome) + + NEW_INT_OPTION(temp_int); + SET_INT_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY); ++ ++ temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/" ++ "cache-dir", DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR); ++ ++ NEW_OPTION(temp); ++ SET_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR); ++ ++ temp = getOption("/server/extended-runtime-options/ffmpegthumbnailer/" ++ "cache-dir/attribute::enabled", ++ DEFAULT_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED); ++ ++ if (!validateYesNo(temp)) ++ throw _Exception(_("Error in config file: " ++ "invalid \"enabled\" attribute value in " ++ "ffmpegthumbnailer <cache-dir> tag")); ++ ++ NEW_BOOL_OPTION(temp == YES ? true : false); ++ SET_BOOL_OPTION(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED); + } + #endif + +diff --git a/src/config_manager.h b/src/config_manager.h +index 52b9842..a447a60 100644 +--- a/src/config_manager.h ++++ b/src/config_manager.h +@@ -110,6 +110,8 @@ typedef enum + CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_FILMSTRIP_OVERLAY, + CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_WORKAROUND_BUGS, + CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_IMAGE_QUALITY, ++ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED, ++ CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR, + #endif + CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_ENABLED, + CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND, +diff --git a/src/metadata/ffmpeg_handler.cc b/src/metadata/ffmpeg_handler.cc +index a637d9c..8e7ef23 100644 +--- a/src/metadata/ffmpeg_handler.cc ++++ b/src/metadata/ffmpeg_handler.cc +@@ -50,6 +50,9 @@ + // INT64_C is not defined in ffmpeg/avformat.h but is needed + // macro defines included via autoconfig.h + #include <stdint.h> ++#include <sys/stat.h> ++#include <errno.h> ++#include <string.h> + + //#ifdef FFMPEG_NEEDS_EXTERN_C + extern "C" +@@ -279,6 +282,122 @@ void FfmpegHandler::fillMetadata(Ref<CdsItem> item) + av_close_input_file(pFormatCtx); + } + ++#ifdef HAVE_FFMPEGTHUMBNAILER ++ ++static int _mkdir(const char *path) ++{ ++ int ret = mkdir(path, 0777); ++ ++ if (ret == 0) { ++ // Make sure we are +x in case of restrictive umask that strips +x. ++ struct stat st; ++ if (stat(path, &st)) { ++ log_warning("could not stat(%s): %s\n", path, strerror(errno)); ++ return -1; ++ } ++ mode_t xbits = S_IXUSR | S_IXGRP | S_IXOTH; ++ if (!(st.st_mode & xbits)) { ++ if (chmod(path, st.st_mode | xbits)) { ++ log_warning("could not chmod(%s, +x): %s\n", path, strerror(errno)); ++ return -1; ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++static bool makeThumbnailCacheDir(String& path) ++{ ++ char *path_temp = strdup(path.c_str()); ++ char *last_slash = strrchr(path_temp, '/'); ++ char *slash = last_slash; ++ bool ret = false; ++ ++ if (!last_slash) ++ return ret; ++ ++ // Assume most dirs exist, so scan backwards first. ++ // Avoid stat/access checks due to TOCTOU races. ++ errno = 0; ++ for (slash = last_slash; slash > path_temp; --slash) { ++ if (*slash != '/') ++ continue; ++ *slash = '\0'; ++ if (_mkdir(path_temp) == 0) { ++ // Now we can forward scan. ++ while (slash < last_slash) { ++ *slash = DIR_SEPARATOR; ++ if (_mkdir(path_temp) < 0) ++ // Allow EEXIST in case of someone else doing `mkdir`. ++ if (errno != EEXIST) ++ goto done; ++ slash += strlen(slash); ++ } ++ if (slash == last_slash) ++ ret = true; ++ break; ++ } else if (errno == EEXIST) { ++ ret = true; ++ break; ++ } else if (errno != ENOENT) { ++ break; ++ } ++ } ++ ++ done: ++ free(path_temp); ++ return ret; ++} ++ ++static String getThumbnailCacheFilePath(String& movie_filename, bool create) ++{ ++ Ref<ConfigManager> cfg = ConfigManager::getInstance(); ++ String cache_dir = cfg->getOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR); ++ ++ if (cache_dir.length() == 0) { ++ String home_dir = cfg->getOption(CFG_SERVER_HOME); ++ cache_dir = home_dir + "/cache-dir"; ++ } ++ ++ cache_dir = cache_dir + movie_filename + "-thumb.jpg"; ++ if (create && !makeThumbnailCacheDir(cache_dir)) ++ cache_dir = ""; ++ return cache_dir; ++} ++ ++static bool readThumbnailCacheFile(String movie_filename, uint8_t **ptr_img, size_t *size_img) ++{ ++ String path = getThumbnailCacheFilePath(movie_filename, false); ++ FILE *fp = fopen(path.c_str(), "rb"); ++ if (!fp) ++ return false; ++ ++ size_t bytesRead; ++ uint8_t buffer[1024]; ++ *ptr_img = NULL; ++ *size_img = 0; ++ while ((bytesRead = fread(buffer, 1, sizeof(buffer), fp)) > 0) { ++ *ptr_img = (uint8_t *)realloc(*ptr_img, *size_img + bytesRead); ++ memcpy(*ptr_img + *size_img, buffer, bytesRead); ++ *size_img += bytesRead; ++ } ++ fclose(fp); ++ return true; ++} ++ ++static void writeThumbnailCacheFile(String movie_filename, uint8_t *ptr_img, int size_img) ++{ ++ String path = getThumbnailCacheFilePath(movie_filename, true); ++ FILE *fp = fopen(path.c_str(), "wb"); ++ if (!fp) ++ return; ++ fwrite(ptr_img, sizeof(uint8_t), size_img, fp); ++ fclose(fp); ++} ++ ++#endif ++ + Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t *data_size) + { + *data_size = -1; +@@ -288,6 +407,18 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + if (!cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_ENABLED)) + return nil; + ++ if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) { ++ uint8_t *ptr_image; ++ size_t size_image; ++ if (readThumbnailCacheFile(item->getLocation(), ++ &ptr_image, &size_image)) { ++ *data_size = (off_t)size_image; ++ Ref<IOHandler> h(new MemIOHandler(ptr_image, size_image)); ++ free(ptr_image); ++ log_debug("Returning cached thumbnail for file: %s\n", item->getLocation().c_str()); ++ return h; ++ } ++ } + #ifdef FFMPEGTHUMBNAILER_OLD_API + video_thumbnailer *th = create_thumbnailer(); + image_data *img = create_image_data(); +@@ -318,6 +449,10 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + #endif // old api + throw _Exception(_("Could not generate thumbnail for ") + + item->getLocation()); ++ if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) { ++ writeThumbnailCacheFile(item->getLocation(), ++ img->image_data_ptr, img->image_data_size); ++ } + + *data_size = (off_t)img->image_data_size; + Ref<IOHandler> h(new MemIOHandler((void *)img->image_data_ptr, diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-thumbnail-locking.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-thumbnail-locking.patch new file mode 100644 index 000000000000..70658c495d25 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-thumbnail-locking.patch @@ -0,0 +1,71 @@ +if you try to generate a bunch of thumbnails at once, it can crash: + +Program received signal SIGABRT, Aborted. +[Switching to Thread 0x7fdb7a6cb700 (LWP 17295)] +0x00007fdb8031c899 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 +56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. +(gdb) bt +#0 0x00007fdb8031c899 in __GI_raise (sig=sig@entry=0x6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56 +#1 0x00007fdb8031de27 in __GI_abort () at abort.c:89 +#2 0x00007fdb7f6b9222 in ff_unlock_avcodec () at /var/tmp/portage/media-video/ffmpeg-1.2.6/work/ffmpeg-1.2.6/libavcodec/utils.c:2767 +#3 0x00007fdb7f6b9662 in avcodec_open2 (avctx=0x7fdb64032080, codec=<optimized out>, options=0x0) at /var/tmp/portage/media-video/ffmpeg-1.2.6/work/ffmpeg-1.2.6/libavcodec/utils.c:1132 +#4 0x00007fdb81be57bb in ffmpegthumbnailer::MovieDecoder::initializeVideo (this=this@entry=0x7fdb7a6ca000) at libffmpegthumbnailer/moviedecoder.cpp:176 +#5 0x00007fdb81be599c in ffmpegthumbnailer::MovieDecoder::initialize (this=0x7fdb7a6ca000, filename=...) at libffmpegthumbnailer/moviedecoder.cpp:86 +#6 0x00007fdb81be92cc in ffmpegthumbnailer::VideoThumbnailer::generateThumbnail (this=this@entry=0x7fdb6402af90, videoFile=..., imageWriter=..., pAvContext=pAvContext@entry=0x0) at libffmpegthumbnailer/videothumbnailer.cpp:118 +#7 0x00007fdb81be97b4 in ffmpegthumbnailer::VideoThumbnailer::generateThumbnail (this=this@entry=0x7fdb6402af90, videoFile=..., type=<optimized out>, type@entry=Jpeg, buffer=..., pAvContext=pAvContext@entry=0x0) at libffmpegthumbnailer/videothumbnailer.cpp:191 +#8 0x00007fdb81bea23e in video_thumbnailer_generate_thumbnail_to_buffer (thumbnailer=<optimized out>, movie_filename=0x7fdb7003abc0 "........mp4", generated_image_data=0x7fdb64022680) at libffmpegthumbnailer/videothumbnailerc.cpp:113 +#9 0x00000000004ebfed in FfmpegHandler::serveContent (this=this@entry=0x7fdb64020ff0, item=..., resNum=resNum@entry=0x1, data_size=data_size@entry=0x7fdb7a6caaf0) at ../src/metadata/ffmpeg_handler.cc:475 +#10 0x00000000004e48d7 in FileRequestHandler::open (this=<optimized out>, filename=<optimized out>, info=0x7fdb7a6caaf0, mode=<optimized out>) at ../src/file_request_handler.cc:575 +#11 0x00000000004bba74 in web_open (filename=0x7fdb640175f0 "/content/media/object_id/16634/res_id/1/rh/6/ext/file.jpg", info=0x7fdb7a6caaf0, mode=UPNP_READ) at ../src/web_callbacks.cc:198 +#12 0x000000000052674b in process_request (Fp=<synthetic pointer>, RespInstr=0x7fdb7a6cab70, alias=0x7fdb7a6cab20, filename=0x7fdb7a6caad0, headers=0x7fdb7a6caab0, rtype=<synthetic pointer>, req=0x7fdb7a6cacd0) at ../upnp/src/genlib/net/http/webserver.c:1343 +#13 web_server_callback (parser=0x7fdb7a6cacd0, req=0x7fdb7a6cacd0, info=0x7fdb7a6cacc0) at ../upnp/src/genlib/net/http/webserver.c:1803 +#14 0x000000000051f29a in dispatch_request (hparser=0x7fdb7a6cacd0, info=0x7fdb7a6cacc0) at ../upnp/src/genlib/miniserver/miniserver.c:236 +#15 handle_request (args=0x7fdb6c000c40) at ../upnp/src/genlib/miniserver/miniserver.c:339 +#16 0x000000000052cc66 in WorkerThread (arg=0x7a80e0 <gRecvThreadPool>) at ../threadutil/src/ThreadPool.c:594 +#17 0x00007fdb80697333 in start_thread (arg=0x7fdb7a6cb700) at pthread_create.c:309 +#18 0x00007fdb803d226d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111 +(gdb) + +--- a/src/metadata/ffmpeg_handler.cc ++++ b/src/metadata/ffmpeg_handler.cc +@@ -311,6 +311,10 @@ void FfmpegHandler::fillMetadata(Ref<CdsItem> item) + + #ifdef HAVE_FFMPEGTHUMBNAILER + ++// The ffmpegthumbnailer code (ffmpeg?) is not threading safe. ++// Add a lock around the usage to avoid crashing randomly. ++static pthread_mutex_t thumb_lock; ++ + static int _mkdir(const char *path) + { + int ret = mkdir(path, 0777); +@@ -446,6 +450,9 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + return h; + } + } ++ ++ pthread_mutex_lock(&thumb_lock); ++ + #ifdef FFMPEGTHUMBNAILER_OLD_API + video_thumbnailer *th = create_thumbnailer(); + image_data *img = create_image_data(); +@@ -474,8 +481,11 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + if (video_thumbnailer_generate_thumbnail_to_buffer(th, + item->getLocation().c_str(), img) != 0) + #endif // old api ++ { ++ pthread_mutex_unlock(&thumb_lock); + throw _Exception(_("Could not generate thumbnail for ") + + item->getLocation()); ++ } + if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_FFMPEGTHUMBNAILER_CACHE_DIR_ENABLED)) { + writeThumbnailCacheFile(item->getLocation(), + img->image_data_ptr, img->image_data_size); +@@ -491,6 +501,7 @@ Ref<IOHandler> FfmpegHandler::serveContent(Ref<CdsItem> item, int resNum, off_t + video_thumbnailer_destroy_image_data(img); + video_thumbnailer_destroy(th); + #endif// old api ++ pthread_mutex_unlock(&thumb_lock); + return h; + #else + return nil; diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1-youtube-dl.patch b/net-misc/mediatomb/files/mediatomb-0.12.1-youtube-dl.patch new file mode 100644 index 000000000000..6001d2fc5661 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1-youtube-dl.patch @@ -0,0 +1,141 @@ +--- mediatomb-0.12.1.orig/src/youtube_video_url.cc 2013-12-17 22:46:24.272442249 +0000 ++++ mediatomb-0.12.1/src/youtube_video_url.cc 2013-12-17 22:57:25.968039083 +0000 +@@ -117,89 +117,68 @@ String YouTubeVideoURL::getVideoURL(Stri + + watch = _(YOUTUBE_URL_WATCH) + video_id; + +- Ref<URL> url(new URL(YOUTUBE_PAGESIZE)); ++ /* ++ * NOTE ON PATCH: ++ * ++ * The original code does not seem to work anymore. ++ * ++ * I have commented-out all the original code, and instead ++ * replaced it with a call/exec to youtube-dl (this is a separate/stand-alone python script). ++ * ++ * Available at http://rg3.github.io/youtube-dl/ ++ * ++ * ++ * The current code works on a/my samsung TV. I have not tested it further on other devices. ++ * (I needed a quick fix, because I wanted to watch some video's. :) ) ++ * ++ * I thought I would share the results. ++ * ++ * Suggestions / feedback -> bas-patch@tcfaa.nl ++ * ++ * Regards, Bas Nedermeijer ++ */ ++ ++ int pipefd[2]; ++ pipe(pipefd); ++ ++ if (fork() == 0) ++ { ++ // close reading end in the child ++ close(pipefd[0]); ++ ++ // send stdout to the pipe ++ dup2(pipefd[1], 1); ++ // send stderr to the pipe ++ dup2(pipefd[1], 2); + +- Ref<StringBuffer> buffer = url->download(watch, &retcode, curl_handle, +- false, verbose, true); +- if (retcode != 200) +- { +- throw _Exception(_("Failed to get URL for video with id ") +- + watch + _("HTTP response code: ") + +- String::from(retcode)); +- } ++ // this descriptor is no longer needed ++ close(pipefd[1]); + +- log_debug("------> GOT BUFFER %s\n", buffer->toString().c_str()); +- +- Ref<Matcher> matcher = reVideoURLParams->matcher(buffer->toString()); +- String params; +- if (matcher->next()) +- { +-// params = trim_string(matcher->group(1)); +- params = trim_string( matcher->group( 0 ) ); +- /* +- int brace = params.index( '{' ); +- if ( brace > 0 ) +- params = params.substring( brace ); +- brace = params.index( '}' ); +- if ( brace > 0 ) +- params = params.substring( 0, brace + 1 ); +- */ +- Ref<Matcher> m2 = param_t->matcher(params); +- if (m2->next()) +- { +- String hmm = m2->group(1); +- if (string_ok(hmm)) +- params = hmm; +- else +- { +- throw _Exception(_("Could not retrieve \"t\" parameter.")); +- } +- } ++ // This code assumes youtube-dl is available for usage. ++ execl("/usr/bin/youtube-dl", "/usr/bin/youtube-dl","-g",watch.c_str(),NULL); + } + else + { +- throw _Exception(_("Failed to get URL for video with id (step 1)") + video_id); +- } ++ // parent ++ char buffery[8192]; ++ memset(&buffery[0], 0, sizeof(buffery)); + +- params = _(YOUTUBE_URL_GET) + YOUTUBE_URL_PARAM_VIDEO_ID + '=' + +- video_id + '&' + YOUTUBE_URL_PARAM_T + '=' + params; ++ close(pipefd[1]); // close the write end of the pipe in the parent + +- if (mp4) +- { +- String format = _("&fmt=18"); +- +- if (hd) ++ // Hopefully the read is never called twice, otherwise the buffer will become corrupt. ++ while (read(pipefd[0], buffery, sizeof(buffery)) != 0) + { +- matcher = HD->matcher(buffer->toString()); +- if (matcher->next()) +- { +- if (trim_string(matcher->group(1)) == "true") +- format = _("&fmt=22"); +- } + } +- +- params = params + format; +- } + +- buffer = url->download(params, &retcode, curl_handle, true, verbose, true); ++ log_debug("------> GOT BUFFER %s\n", buffery); ++ String result = _(buffery); + +- matcher = redirectLocation->matcher(buffer->toString()); +- if (matcher->next()) +- { +- if (string_ok(trim_string(matcher->group(1)))) +- return trim_string(matcher->group(1)); +- else +- throw _Exception(_("Failed to get URL for video with id (step 2)")+ +- video_id); +- } ++ result = trim_string(result); + +- if (retcode != 303) +- { +- throw _Exception(_("Unexpected reply from YouTube: ") + +- String::from(retcode)); +- } ++ log_debug("------> GOT BUFFER (after trimming) %s\n", result.c_str()); + +- throw _Exception(_("Could not retrieve YouTube video URL")); ++ return result; ++ } + } + + #endif//YOUTUBE diff --git a/net-misc/mediatomb/files/mediatomb-0.12.1.initd b/net-misc/mediatomb/files/mediatomb-0.12.1.initd new file mode 100644 index 000000000000..49ea8fa2c559 --- /dev/null +++ b/net-misc/mediatomb/files/mediatomb-0.12.1.initd @@ -0,0 +1,29 @@ +#!/sbin/runscript +# Copyright 1999-2012 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +depend() { + need net + # In order to properly support this (need vs use), we would have to + # parse ${MEDIATOMB_CONFIG} and see if mysql is enabled and if it is + # pointing to the local system. #368409 + use mysql +} + +start() { + ebegin "Starting MediaTomb" + start-stop-daemon --start --quiet --exec /usr/bin/mediatomb \ + --pidfile ${MEDIATOMB_PIDFILE} -- --daemon \ + --pidfile ${MEDIATOMB_PIDFILE} --user ${MEDIATOMB_USER} \ + --group ${MEDIATOMB_GROUP} --logfile ${MEDIATOMB_LOGFILE} \ + --config ${MEDIATOMB_CONFIG} --port ${MEDIATOMB_PORT} \ + ${MEDIATOMB_OPTIONS} + eend $? +} + +stop () { + ebegin "Stopping MediaTomb" + start-stop-daemon --stop --retry 10 --quiet --pidfile ${MEDIATOMB_PIDFILE} + eend $? +} diff --git a/net-misc/mediatomb/mediatomb-0.12.1-r7.ebuild b/net-misc/mediatomb/mediatomb-0.12.1-r7.ebuild new file mode 100644 index 000000000000..7ab5e96d1c24 --- /dev/null +++ b/net-misc/mediatomb/mediatomb-0.12.1-r7.ebuild @@ -0,0 +1,161 @@ +# Copyright 1999-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +EAPI=5 +inherit autotools eutils linux-info user + +DEB_VER="4" +DESCRIPTION="MediaTomb is an open source UPnP MediaServer" +HOMEPAGE="http://www.mediatomb.cc/" + +SRC_URI="mirror://sourceforge/mediatomb/${P}.tar.gz + mirror://debian/pool/main/${PN:0:1}/${PN}/${PN}_${PV}-${DEB_VER}.debian.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="amd64 ~arm ~ppc x86" + +IUSE="curl debug +exif +ffmpeg flac id3tag +inotify +javascript lastfm + libextractor +magic +mp4 mysql +sqlite +taglib thumbnail +zlib" +REQUIRED_USE=" + || ( mysql sqlite ) + taglib? ( !id3tag ) + id3tag? ( !taglib ) + thumbnail? ( ffmpeg !libextractor ) + ffmpeg? ( !libextractor ) + libextractor? ( !ffmpeg !thumbnail ) +" + +DEPEND="mysql? ( virtual/mysql ) + dev-libs/expat + id3tag? ( media-libs/id3lib ) + javascript? ( >=dev-lang/spidermonkey-1.8.5:0 ) + taglib? ( media-libs/taglib ) + sqlite? ( >=dev-db/sqlite-3 ) + lastfm? ( >=media-libs/lastfmlib-0.4 ) + exif? ( media-libs/libexif ) + libextractor? ( media-libs/libextractor ) + mp4? ( >=media-libs/libmp4v2-1.9.1_p479:0 ) + ffmpeg? ( virtual/ffmpeg ) + flac? ( media-libs/flac ) + thumbnail? ( media-video/ffmpegthumbnailer[jpeg] ) + curl? ( net-misc/curl net-misc/youtube-dl ) + magic? ( sys-apps/file ) + sys-apps/util-linux + zlib? ( sys-libs/zlib ) + virtual/libiconv +" +RDEPEND="${DEPEND}" + +CONFIG_CHECK="~INOTIFY_USER" + +pkg_setup() { + enewgroup mediatomb + enewuser mediatomb -1 -1 /dev/null mediatomb +} + +src_prepare() { + + # Apply Debians patchset + local p dd="${WORKDIR}"/debian/patches + sed -i -r '/^[-+]{3} /s:[.][.]/::' "${dd}"/* || die + for p in $(<"${dd}"/series) ; do + epatch "${dd}"/${p} + done + + # libmp4v2 API breakage #410235 + epatch "${FILESDIR}"/${P}-libmp4v2.patch + + # Use system libuuid #270830 + epatch "${FILESDIR}"/${P}-system-uuid.patch + + # Support spidermonkey-187 #423991 #482392 + if has_version "~dev-lang/spidermonkey-1.8.7" ; then + epatch "${FILESDIR}"/${P}-mozjs187.patch + fi + + # Support libextractor-0.6.0 #435394 + epatch "${FILESDIR}"/${P}-libextractor.patch + + # Fix inotify and hard links + epatch "${FILESDIR}"/${P}-inotify-hard-links.patch + + # Add support for caching thumbnails + epatch "${FILESDIR}"/${P}-thumb-cache.patch + + # Support libav-9 #443178 + epatch "${FILESDIR}"/${P}-libav9.patch + + # Fix Crash due to Uninitalized AVFormatContext pointer #446922 + epatch "${FILESDIR}"/${P}-avformatcontext-pointer.patch + + # Respect AR #464710 + epatch "${FILESDIR}"/${P}-system-ar.patch + + # Add flac metadata support #494398 + epatch "${FILESDIR}"/${P}-flac-metadata.patch + + # Work around broken youtube support by using youtube-dl #467110 + epatch "${FILESDIR}"/${P}-youtube-dl.patch + + epatch_user + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable curl) \ + $(use_enable curl youtube) \ + $(use_enable debug tombdebug) \ + $(use_enable exif libexif) \ + $(use_enable ffmpeg) \ + $(use_enable flac FLAC) \ + $(use_enable id3tag id3lib) \ + $(use_enable inotify) \ + $(use_enable javascript libjs) \ + $(use_enable lastfm lastfmlib) \ + $(use_enable libextractor) \ + $(use_enable magic libmagic) \ + $(use_enable mp4 libmp4v2) \ + $(use_enable mysql) \ + $(use_enable sqlite sqlite3) \ + $(use_enable taglib) \ + $(use_enable thumbnail ffmpegthumbnailer) \ + $(use_enable zlib) \ + --enable-external-transcoding \ + --enable-protocolinfo-extension +} + +src_install() { + default + + newinitd "${FILESDIR}"/${PN}-0.12.1.initd ${PN} + use mysql || sed -i -e "/use mysql/d" "${ED}"/etc/init.d/${PN} + newconfd "${FILESDIR}"/${PN}-0.12.0.confd ${PN} + + insinto /etc/mediatomb + newins "${FILESDIR}/${PN}-0.12.0.config" config.xml + fperms 0600 /etc/mediatomb/config.xml + fowners mediatomb:mediatomb /etc/mediatomb/config.xml + + keepdir /var/lib/mediatomb + fowners mediatomb:mediatomb /var/lib/mediatomb +} + +pkg_postinst() { + if use mysql ; then + elog "MediaTomb has been built with MySQL support and needs" + elog "to be configured before being started." + elog "For more information, please consult the MediaTomb" + elog "documentation: http://mediatomb.cc/pages/documentation" + elog + fi + + elog "To configure MediaTomb edit:" + elog "/etc/mediatomb/config.xml" + elog + elog "The MediaTomb web interface can be reached at (after the service is started):" + elog "http://localhost:49152/" +} diff --git a/net-misc/mediatomb/mediatomb-0.12.1-r8.ebuild b/net-misc/mediatomb/mediatomb-0.12.1-r8.ebuild new file mode 100644 index 000000000000..e0d46477e307 --- /dev/null +++ b/net-misc/mediatomb/mediatomb-0.12.1-r8.ebuild @@ -0,0 +1,157 @@ +# Copyright 1999-2014 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +EAPI=5 +inherit autotools eutils linux-info user + +DEB_VER="5" +DESCRIPTION="MediaTomb is an open source UPnP MediaServer" +HOMEPAGE="http://www.mediatomb.cc/" + +SRC_URI="mirror://sourceforge/mediatomb/${P}.tar.gz + mirror://debian/pool/main/${PN:0:1}/${PN}/${PN}_${PV}-${DEB_VER}.debian.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="amd64 ~arm ~ppc x86" + +IUSE="curl debug +exif +ffmpeg flac id3tag +inotify +javascript lastfm + libextractor +magic +mp4 mysql +sqlite +taglib thumbnail +zlib" +REQUIRED_USE=" + || ( mysql sqlite ) + taglib? ( !id3tag ) + id3tag? ( !taglib ) + thumbnail? ( ffmpeg !libextractor ) + ffmpeg? ( !libextractor ) + libextractor? ( !ffmpeg !thumbnail ) +" + +DEPEND="mysql? ( virtual/mysql ) + dev-libs/expat + id3tag? ( media-libs/id3lib ) + javascript? ( >=dev-lang/spidermonkey-1.8.5:0 ) + taglib? ( media-libs/taglib ) + sqlite? ( >=dev-db/sqlite-3 ) + lastfm? ( >=media-libs/lastfmlib-0.4 ) + exif? ( media-libs/libexif ) + libextractor? ( media-libs/libextractor ) + mp4? ( >=media-libs/libmp4v2-1.9.1_p479:0 ) + ffmpeg? ( virtual/ffmpeg ) + flac? ( media-libs/flac ) + thumbnail? ( media-video/ffmpegthumbnailer[jpeg] ) + curl? ( net-misc/curl net-misc/youtube-dl ) + magic? ( sys-apps/file ) + sys-apps/util-linux + zlib? ( sys-libs/zlib ) + virtual/libiconv +" +RDEPEND="${DEPEND}" + +CONFIG_CHECK="~INOTIFY_USER" + +pkg_setup() { + enewgroup mediatomb + enewuser mediatomb -1 -1 /dev/null mediatomb +} + +src_prepare() { + # Apply Debians patchset + local p dd="${WORKDIR}"/debian/patches + sed -i -r '/^[-+]{3} /s:[.][.]/::' "${dd}"/* || die + # We use our version as it seems to be more complete. + sed -i '/^0010_fix_libmp4v2_build.patch/d' "${dd}"/series || die + for p in $(<"${dd}"/series) ; do + epatch "${dd}"/${p} + done + + # libmp4v2 API breakage #410235 + epatch "${FILESDIR}"/${P}-libmp4v2.patch + + # Use system libuuid #270830 + epatch "${FILESDIR}"/${P}-system-uuid.patch + + # Support spidermonkey-187 #423991 #482392 + if has_version "~dev-lang/spidermonkey-1.8.7" ; then + epatch "${FILESDIR}"/${P}-mozjs187.patch + fi + + # Support libextractor-0.6.0 #435394 + epatch "${FILESDIR}"/${P}-libextractor.patch + + # Fix inotify and hard links + epatch "${FILESDIR}"/${P}-inotify-hard-links.patch + + # Add support for caching thumbnails + epatch "${FILESDIR}"/${P}-thumb-cache.patch + epatch "${FILESDIR}"/${P}-thumbnail-locking.patch + + # Respect AR #464710 + epatch "${FILESDIR}"/${P}-system-ar.patch + + # Add flac metadata support #494398 + epatch "${FILESDIR}"/${P}-flac-metadata.patch + + # Work around broken youtube support by using youtube-dl #467110 + epatch "${FILESDIR}"/${P}-youtube-dl.patch + + epatch_user + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable curl) \ + $(use_enable curl youtube) \ + $(use_enable debug tombdebug) \ + $(use_enable exif libexif) \ + $(use_enable ffmpeg) \ + $(use_enable flac FLAC) \ + $(use_enable id3tag id3lib) \ + $(use_enable inotify) \ + $(use_enable javascript libjs) \ + $(use_enable lastfm lastfmlib) \ + $(use_enable libextractor) \ + $(use_enable magic libmagic) \ + $(use_enable mp4 libmp4v2) \ + $(use_enable mysql) \ + $(use_enable sqlite sqlite3) \ + $(use_enable taglib) \ + $(use_enable thumbnail ffmpegthumbnailer) \ + $(use_enable zlib) \ + --enable-external-transcoding \ + --enable-protocolinfo-extension +} + +src_install() { + default + + newinitd "${FILESDIR}"/${PN}-0.12.1.initd ${PN} + use mysql || sed -i -e "/use mysql/d" "${ED}"/etc/init.d/${PN} + newconfd "${FILESDIR}"/${PN}-0.12.0.confd ${PN} + + insinto /etc/mediatomb + newins "${FILESDIR}/${PN}-0.12.0.config" config.xml + fperms 0600 /etc/mediatomb/config.xml + fowners mediatomb:mediatomb /etc/mediatomb/config.xml + + keepdir /var/lib/mediatomb + fowners mediatomb:mediatomb /var/lib/mediatomb +} + +pkg_postinst() { + if use mysql ; then + elog "MediaTomb has been built with MySQL support and needs" + elog "to be configured before being started." + elog "For more information, please consult the MediaTomb" + elog "documentation: http://mediatomb.cc/pages/documentation" + elog + fi + + elog "To configure MediaTomb edit:" + elog "/etc/mediatomb/config.xml" + elog + elog "The MediaTomb web interface can be reached at (after the service is started):" + elog "http://localhost:49152/" +} diff --git a/net-misc/mediatomb/mediatomb-0.12.2_pre20150118-r1.ebuild b/net-misc/mediatomb/mediatomb-0.12.2_pre20150118-r1.ebuild new file mode 100644 index 000000000000..a2081aaa5108 --- /dev/null +++ b/net-misc/mediatomb/mediatomb-0.12.2_pre20150118-r1.ebuild @@ -0,0 +1,123 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +EAPI=5 +inherit autotools eutils linux-info systemd user vcs-snapshot + +DESCRIPTION="MediaTomb is an open source UPnP MediaServer" +HOMEPAGE="http://www.mediatomb.cc/" +SRC_URI="https://github.com/v00d00/${PN}/archive/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~arm ~x86" + +IUSE="curl debug +exif +ffmpeg flac id3tag +inotify +javascript lastfm + libav +magic +mp4 mysql +sqlite +taglib thumbnail +zlib" +REQUIRED_USE=" + || ( mysql sqlite ) + taglib? ( !id3tag ) + id3tag? ( !taglib ) + thumbnail? ( ffmpeg ) +" + +DEPEND="mysql? ( virtual/mysql ) + dev-libs/expat + id3tag? ( media-libs/id3lib ) + javascript? ( >=dev-lang/spidermonkey-1.8.5:0 ) + taglib? ( media-libs/taglib ) + sqlite? ( >=dev-db/sqlite-3 ) + lastfm? ( >=media-libs/lastfmlib-0.4 ) + exif? ( media-libs/libexif ) + mp4? ( >=media-libs/libmp4v2-1.9.1_p479:0 ) + ffmpeg? ( + libav? ( >=media-video/libav-10:0= ) + !libav? ( >=media-video/ffmpeg-2.2:0= ) + ) + flac? ( media-libs/flac ) + thumbnail? ( media-video/ffmpegthumbnailer[jpeg] ) + curl? ( net-misc/curl net-misc/youtube-dl ) + magic? ( sys-apps/file ) + sys-apps/util-linux + zlib? ( sys-libs/zlib ) + virtual/libiconv +" +RDEPEND="${DEPEND}" + +CONFIG_CHECK="~INOTIFY_USER" + +pkg_setup() { + use inotify && linux-info_pkg_setup + + enewgroup mediatomb + enewuser mediatomb -1 -1 /dev/null mediatomb +} + +src_prepare() { + # Support spidermonkey-187 #423991 #482392 + if has_version "~dev-lang/spidermonkey-1.8.7" ; then + epatch "${FILESDIR}"/${PN}-0.12.1-mozjs187.patch + fi + + epatch_user + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable curl) \ + $(use_enable curl youtube) \ + $(use_enable debug tombdebug) \ + $(use_enable exif libexif) \ + $(use_enable ffmpeg) \ + $(use_enable flac) \ + $(use_enable id3tag id3lib) \ + $(use_enable inotify) \ + $(use_enable javascript libjs) \ + $(use_enable lastfm lastfm) \ + $(use_enable magic libmagic) \ + $(use_enable mp4 libmp4v2) \ + $(use_enable mysql) \ + $(use_enable sqlite sqlite3) \ + $(use_enable taglib) \ + $(use_enable thumbnail ffmpegthumbnailer) \ + --enable-external-transcoding \ + --enable-protocolinfo-extension +} + +src_install() { + default + + systemd_dounit "${S}"/scripts/systemd/"${PN}".service + use mysql && systemd_dounit "${S}"/scripts/systemd/"${PN}"-mysql.service + + newinitd "${FILESDIR}"/${PN}-0.12.1.initd ${PN} + use mysql || sed -i -e "/use mysql/d" "${ED}"/etc/init.d/${PN} + newconfd "${FILESDIR}"/${PN}-0.12.0.confd ${PN} + + insinto /etc/mediatomb + newins "${FILESDIR}/${PN}-0.12.0.config" config.xml + fperms 0600 /etc/mediatomb/config.xml + fowners mediatomb:mediatomb /etc/mediatomb/config.xml + + keepdir /var/lib/mediatomb + fowners mediatomb:mediatomb /var/lib/mediatomb +} + +pkg_postinst() { + if use mysql ; then + elog "MediaTomb has been built with MySQL support and needs" + elog "to be configured before being started." + elog "For more information, please consult the MediaTomb" + elog "documentation: http://mediatomb.cc/pages/documentation" + elog + fi + + elog "To configure MediaTomb edit:" + elog "/etc/mediatomb/config.xml" + elog + elog "The MediaTomb web interface can be reached at (after the service is started):" + elog "http://localhost:49152/" +} diff --git a/net-misc/mediatomb/mediatomb-0.12.2_pre20150118.ebuild b/net-misc/mediatomb/mediatomb-0.12.2_pre20150118.ebuild new file mode 100644 index 000000000000..c835557f0cb4 --- /dev/null +++ b/net-misc/mediatomb/mediatomb-0.12.2_pre20150118.ebuild @@ -0,0 +1,120 @@ +# Copyright 1999-2015 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Id$ + +EAPI=5 +inherit autotools eutils linux-info systemd user vcs-snapshot + +DESCRIPTION="MediaTomb is an open source UPnP MediaServer" +HOMEPAGE="http://www.mediatomb.cc/" +SRC_URI="https://github.com/v00d00/${PN}/archive/${P}.tar.gz" + +LICENSE="GPL-2" +SLOT="0" +KEYWORDS="~amd64 ~arm ~x86" + +IUSE="curl debug +exif +ffmpeg flac id3tag +inotify +javascript lastfm + +magic +mp4 mysql +sqlite +taglib thumbnail +zlib" +REQUIRED_USE=" + || ( mysql sqlite ) + taglib? ( !id3tag ) + id3tag? ( !taglib ) + thumbnail? ( ffmpeg ) +" + +DEPEND="mysql? ( virtual/mysql ) + dev-libs/expat + id3tag? ( media-libs/id3lib ) + javascript? ( >=dev-lang/spidermonkey-1.8.5:0 ) + taglib? ( media-libs/taglib ) + sqlite? ( >=dev-db/sqlite-3 ) + lastfm? ( >=media-libs/lastfmlib-0.4 ) + exif? ( media-libs/libexif ) + mp4? ( >=media-libs/libmp4v2-1.9.1_p479:0 ) + ffmpeg? ( || ( >=media-video/libav-10 >=media-video/ffmpeg-2.2 ) ) + flac? ( media-libs/flac ) + thumbnail? ( media-video/ffmpegthumbnailer[jpeg] ) + curl? ( net-misc/curl net-misc/youtube-dl ) + magic? ( sys-apps/file ) + sys-apps/util-linux + zlib? ( sys-libs/zlib ) + virtual/libiconv +" +RDEPEND="${DEPEND}" + +CONFIG_CHECK="~INOTIFY_USER" + +pkg_setup() { + use inotify && linux-info_pkg_setup + + enewgroup mediatomb + enewuser mediatomb -1 -1 /dev/null mediatomb +} + +src_prepare() { + # Support spidermonkey-187 #423991 #482392 + if has_version "~dev-lang/spidermonkey-1.8.7" ; then + epatch "${FILESDIR}"/${PN}-0.12.1-mozjs187.patch + fi + + epatch_user + + eautoreconf +} + +src_configure() { + econf \ + $(use_enable curl) \ + $(use_enable curl youtube) \ + $(use_enable debug tombdebug) \ + $(use_enable exif libexif) \ + $(use_enable ffmpeg) \ + $(use_enable flac) \ + $(use_enable id3tag id3lib) \ + $(use_enable inotify) \ + $(use_enable javascript libjs) \ + $(use_enable lastfm lastfm) \ + $(use_enable magic libmagic) \ + $(use_enable mp4 libmp4v2) \ + $(use_enable mysql) \ + $(use_enable sqlite sqlite3) \ + $(use_enable taglib) \ + $(use_enable thumbnail ffmpegthumbnailer) \ + --enable-external-transcoding \ + --enable-protocolinfo-extension +} + +src_install() { + default + + systemd_dounit "${S}"/scripts/systemd/"${PN}".service + use mysql && systemd_dounit "${S}"/scripts/systemd/"${PN}"-mysql.service + + newinitd "${FILESDIR}"/${PN}-0.12.1.initd ${PN} + use mysql || sed -i -e "/use mysql/d" "${ED}"/etc/init.d/${PN} + newconfd "${FILESDIR}"/${PN}-0.12.0.confd ${PN} + + insinto /etc/mediatomb + newins "${FILESDIR}/${PN}-0.12.0.config" config.xml + fperms 0600 /etc/mediatomb/config.xml + fowners mediatomb:mediatomb /etc/mediatomb/config.xml + + keepdir /var/lib/mediatomb + fowners mediatomb:mediatomb /var/lib/mediatomb +} + +pkg_postinst() { + if use mysql ; then + elog "MediaTomb has been built with MySQL support and needs" + elog "to be configured before being started." + elog "For more information, please consult the MediaTomb" + elog "documentation: http://mediatomb.cc/pages/documentation" + elog + fi + + elog "To configure MediaTomb edit:" + elog "/etc/mediatomb/config.xml" + elog + elog "The MediaTomb web interface can be reached at (after the service is started):" + elog "http://localhost:49152/" +} diff --git a/net-misc/mediatomb/metadata.xml b/net-misc/mediatomb/metadata.xml new file mode 100644 index 000000000000..e72dfea052a7 --- /dev/null +++ b/net-misc/mediatomb/metadata.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> +<pkgmetadata> + <herd>video</herd> + <maintainer> + <email>thev00d00@gentoo.org</email> + <name>Ian Whyman</name> + </maintainer> + <use> + <flag name="curl">Support YouTube and external media sources (e.g. internet radio)</flag> + <flag name="flac">Enable FLAC metadata/artwork support</flag> + <flag name="id3tag">Use <pkg>media-libs/libid3tag</pkg> for reading files' metadata rather than taglib</flag> + <flag name="inotify">Enable inotify filesystem monitoring support</flag> + <flag name="lastfm">Enable last.fm support</flag> + <flag name="libextractor">Use libextractor to gather files' metadata</flag> + <flag name="magic">Use libmagic to determine file types</flag> + <flag name="mysql">Use <pkg>dev-db/mysql</pkg> as backend rather than SQLite3</flag> + <flag name="taglib">Use <pkg>media-libs/taglib</pkg> for reading files' metadata rather than id3lib</flag> + <flag name="thumbnail">Enables video thumbnails generation through <pkg>media-video/ffmpegthumbnailer</pkg></flag> + </use> + <upstream> + <remote-id type="github">v00d00/mediatomb</remote-id> + </upstream> +</pkgmetadata> |