Merge branch 'master' into toys

This commit is contained in:
Vincent Riquer 2013-04-30 02:36:58 +02:00
commit 6982d8d26a
12 changed files with 208 additions and 240 deletions

23
README
View File

@ -19,21 +19,25 @@ Required:
Optional:
* vorbis-tools
http://www.vorbis.com/
* ogginfo (Ogg Vorbis tags support)
* oggenc (Ogg Vorbis destination)
* ogginfo (Ogg Vorbis metadata)
* oggenc (Ogg Vorbis encoding)
* opus-tools
http://opus-codec.org/
* opusinfo (Opus tags support)
* opusenc (Opus destination)
* opusinfo (Opus metadata)
* opusenc (Opus encoding)
* LAME MP3 Encoder
http://lame.sourceforge.net/
* lame (MP3 destination)
* lame (MP3 encoding)
* FLAC
http://flac.sourceforge.net/
* metaflac (FLAC tags support)
* metaflac (FLAC metadata)
* Musepack
http://www.musepack.net/
* mpcdec (Musepack decoding)
* FFmpeg
http://ffmpeg.org/
* ffprobe (ID3v2, Musepack, Windows Media and video metadata)
* ffmpeg (Windows Media and video decoding)
==================
Using the software
@ -41,3 +45,10 @@ Using the software
Configuration:
Please read doc/config before anything else.
====
Toys
----
AtOM requires a database to function. Now that we have a database containing
various information about our media files, why not use it?
AtOM comes with a small set of tools in the toys/ directory. These are
documented in toys/README.

79
atom
View File

@ -268,7 +268,7 @@ do
fi
done
echo 'COMMIT;' >&3
echo -e "\rRead tags from ${count:-0} files."
echo -e "\rRead tags from ${count:-0} files.\033[K"
unset count tagfiles
echo '
@ -420,75 +420,7 @@ do
rest=${rest#*|}
performer=${rest%%|*}
unset rest
case "$mimetype" in
'audio/mpeg')
if [[ ${destinationformat[$destination]} = mp3 ]] \
&& checkCopy
then
copied=1
else
decodeSox
fi
;;
'application/ogg opus')
if [[ ${destinationformat[$destination]} = opus ]] \
&& checkCopy
then
copied=1
else
decodeOpusdec
if (( ${destinationnormalize["$destination"]}))\
|| (
[ -n "${destinationfrequency["$destination"]}" ]\
&& (( ${rate:-0} != ${destinationfrequency["$destination"]}))\
) || (
[ -n "${destinationchannels["$destination"]}" ]\
&& (( ${channels:-0} != ${destinationchannels["$destination"]} ))
)
then
sox_needed=1
fi
fi
;;
'application/ogg'*)
if [[ ${destinationformat[$destination]} = vorbis ]] \
&& checkCopy
then
copied=1
else
decodeSox
fi
;;
'audio/x-flac')
decodeSox
;;
*)
extendedtype=$(file -b "$sourcepath/$filename")
case "$extendedtype" in
*'Musepack '*)
decodeMpcdec
if (( ${destinationnormalize["$destination"]}))\
|| (
[ -n "${destinationfrequency["$destination"]}" ]\
&& (( ${rate:-0} != ${destinationfrequency["$destination"]}))\
) || (
[ -n "${destinationchannels["$destination"]}" ]\
&& (( ${channels:-0} != ${destinationchannels["$destination"]} ))
)
then
sox_needed=1
fi
;;
*)
decodeSox
;;
esac
;;
esac
if ! (( copied ))
then
decodeFile
fi
getDestDir
getDestFile
if (( copied ))
@ -769,6 +701,7 @@ copyFiles_action
echo '
SELECT id,
filename,
old_filename
FROM destination_files
WHERE old_filename IS NOT NULL;
@ -788,10 +721,12 @@ echo 'BEGIN TRANSACTION;' >&3
for line in "${lines[@]}"
do
id=${line%%|*}
filename=${line#*|}
if [ -f "$filename" ]
rest=${line#*|}
filename=${rest%%|*}
oldfilename=${rest#*|}
if [[ $oldfilename != $filename ]] && [ -f "$oldfilename" ]
then
rm -f "$filename"
rm -f "$oldfilename"
fi
Update destination_files old_filename NULL <<<"id = $id"
(( count++ ))

View File

@ -12,7 +12,6 @@ openDatabase() {
then
mkdir -p "${database%/*}"
fi
sqlite3 "$database" < $schema
fi
sqlite3 -bail "$database" \
< "$tempdir/sqlite.in" \
@ -24,5 +23,6 @@ openDatabase() {
exec 5>&3
exec 3> >(tee -a $tempdir/debug.log >&5)
fi
cat $schema >&3
echo 'PRAGMA foreign_keys = ON;' >&3
}

View File

@ -1,5 +1,76 @@
#!/bin/bash
decodeFile() {
case "$mimetype" in
'video/'*)
extractAudio
sox_needed=1
;;
'audio/mpeg')
if [[ ${destinationformat[$destination]} = mp3 ]] \
&& checkCopy
then
copied=1
else
decodeSox
fi
;;
'application/ogg opus')
if [[ ${destinationformat[$destination]} = opus ]] \
&& checkCopy
then
copied=1
else
decodeOpusdec
if (( ${destinationnormalize["$destination"]}))\
|| (
[ -n "${destinationfrequency["$destination"]}" ]\
&& (( ${rate:-0} != ${destinationfrequency["$destination"]}))\
) || (
[ -n "${destinationchannels["$destination"]}" ]\
&& (( ${channels:-0} != ${destinationchannels["$destination"]} ))
)
then
sox_needed=1
fi
fi
;;
'application/ogg'*)
if [[ ${destinationformat[$destination]} = vorbis ]] \
&& checkCopy
then
copied=1
else
decodeSox
fi
;;
'audio/x-flac')
decodeSox
;;
*)
extendedtype=$(file -b "$sourcepath/$filename")
case "$extendedtype" in
*'Musepack '*)
decodeMpcdec
if (( ${destinationnormalize["$destination"]}))\
|| (
[ -n "${destinationfrequency["$destination"]}" ]\
&& (( ${rate:-0} != ${destinationfrequency["$destination"]}))\
) || (
[ -n "${destinationchannels["$destination"]}" ]\
&& (( ${channels:-0} != ${destinationchannels["$destination"]} ))
)
then
sox_needed=1
fi
;;
*)
decodeSox
;;
esac
;;
esac
if ! (( copied ))
then
if ! decodetaskid=$(
Select tasks id <<<"key = $tmpfile"
)
@ -46,4 +117,5 @@ decodeFile() {
progressSpin
fi
fi
fi
}

View File

@ -1,55 +0,0 @@
#!/bin/bash
getInfosAPE_version='APE-1'
tagreaders+=( "$getInfosAPE_version" )
getInfos::APE() {
# I was not able to find a decent cli tool to read APE tags.
# This is raw but works for the very few MusePack files I got.
#
# Please tell me if you know of any good tool.
tagreader="$getInfosAPE_version"
IFS='='
while read tag value
do
IFS="$oldIFS"
case $tag in
[Aa][Ll][Bb][Uu][Mm]' '[Aa][Rr][Tt][Ii][Ss][Tt])
albumartist="$value"
;;
[Aa][Rr][Tt][Ii][Ss][Tt])
artist="$value"
;;
[Yy][Ee][Aa][Rr])
year="$value"
;;
[Aa][Ll][Bb][Uu][Mm])
album="$value"
;;
[Tt][Ii][Tt][Ll][Ee])
title="$value"
;;
[Tt][Rr][Aa][Cc][Kk])
tracknum="$value"
;;
[Gg][Ee][Nn][Rr][Ee])
genre="$value"
;;
[Cc][Oo][Mm][Pp][Oo][Ss][Ee][Rr])
composer="$value"
;;
[Pp][Ee][Rr][Ff][Oo][Rr][Mm][Ee][Rr])
performer="$value"
;;
*)
;;
esac
IFS='='
done < <(
IFS="$oldIFS"
sed \
's/APETAGEX/\n/;s/[\x00\-\x1F]\x00\+/\n/g;s/\x00/=/g' \
"$sourcepath/$filename" \
| egrep -i \
'^(Album Artist|Artist|Year|Album|Title|Track|Genre|Composer|Performer)='
)
IFS="$oldIFS"
}

View File

@ -1,29 +0,0 @@
#!/bin/bash
getInfosMP3_version='ID3-2'
tagreaders+=( "$getInfosMP3_version" )
getInfos::MP3() {
tagreader="$getInfosMP3_version"
infos=$(
soxi "$sourcepath/$filename" 2>/dev/null \
| sed 's/ *: /=/'
)
album=$(gettag album)
artist=$(gettag artist)
genre=$(gettag genre)
title=$(gettag title)
tracknum=$(gettag tracknumber)
year=$(gettag year)
expr='^\([0-9]*\)$'
if [[ $genre =~ $expr ]]
then
genre=${genre%)}
genre=${genre#(}
genre="${id3genres[$genre]}"
fi
infos="${infos/: /=}"
channels=$(gettag channels)
rate=$(gettag 'sample rate')
bitrate=$(gettag 'bit rate')
bitrate=${bitrate%%.*}
bitrate=${bitrate%k}
}

51
lib/tags/getInfos::ffmpeg Normal file
View File

@ -0,0 +1,51 @@
#!/bin/bash
getInfosffmpeg_version='ffmpeg-1'
tagreaders+=( "$getInfosffmpeg_version" )
getInfos::ffmpeg() {
tagreader="$getInfosffmpeg_version"
local allinfos=$(
ffprobe -show_streams \
-i "$sourcepath/$filename" 2>&1 \
|sed '
/^Input/,/.* Audio: /{s/ *: */=/}
s/^[[:space:]]*//'
)
local metadata=$(
echo -e "$allinfos" \
|sed -n '/Metadata=/,/\[STREAM\]/p'
)
local fmt_infos=$(
echo -e "$allinfos" \
|sed -n \
'/codec_type=audio/,/\[STREAM\]/{
/^\(sample_rate\|bit_rate\|channels\)=/{
p
}
}'
)
local infos="$metadata"
albumartist=$(gettag album_artist)
album=$(gettag album)
artist=$(gettag artist)
composer=$(gettag composer)
genre=$(gettag genre)
performer=$(gettag TOPE)
title=$(gettag title)
tracknum=$(gettag tracknumber)
year=$(gettag year)
expr='^[0-9]*$'
if [ -n "$genre" ] && [[ $genre =~ $expr ]]
then
genre="${id3genres[$genre]}"
fi
infos="$fmt_infos"
channels=$(gettag channels)
rate=$(gettag 'sample_rate')
bitrate=$(gettag 'bit_rate')
if [[ $bitrate == N/A ]]
then
unset bitrate
else
bitrate=$((bitrate / 1000))
fi
}

View File

@ -1,16 +0,0 @@
#!/bin/bash
getRateChannelMPC() {
while read key value garbage
do
case $key in
'samplerate:')
rate=$value
;;
'channels:')
channels=$value
;;
esac
done < <(
mpcdec "$sourcepath/$filename" -i 2>&1
)
}

View File

@ -1,5 +0,0 @@
#!/bin/bash
getRateChannelSoxi() {
rate=$(soxi -r "$sourcepath/$filename" 2>/dev/null)
channels=$(soxi -c "$sourcepath/$filename" 2>/dev/null)
}

View File

@ -1,11 +1,11 @@
#!/bin/bash
getTags_version='unknown-2'
getTags_version='unknown-4'
tagreaders+=( "$getTags_version" )
getTags() {
unset type
case "$mimetype" in
audio/mpeg)
type=MP3
type=ffmpeg
;;
'application/ogg opus')
type=Opus
@ -16,21 +16,11 @@ getTags() {
audio/x-flac)
type=FLAC
;;
*)
extendedtype=$(file -b "$sourcepath/$filename")
case "$extendedtype" in
*' ID3 '*)
type=MP3
;;
*'Musepack '*)
getRateChannelMPC
tryAPE
video/*)
type=ffmpeg
;;
*)
getRateChannelSoxi
tryAPE
;;
esac
type=ffmpeg
;;
esac
if [ -n "$type" ]

6
lib/video/extractaudio Normal file
View File

@ -0,0 +1,6 @@
#!/bin/bash
extractAudio() {
tmpfile="${fileid}ffmpeg"
commandline=(${ionice}ffmpeg -v 0 -vn -y)
commandline+=(-i "$sourcepath/$filename" "$tempdir/$tmpfile.wav")
}

View File

@ -1,5 +1,5 @@
BEGIN TRANSACTION;
CREATE TABLE source_files (
CREATE TABLE IF NOT EXISTS source_files (
id INTEGER PRIMARY KEY,
filename TEXT UNIQUE NOT NULL,
size INTEGER NOT NULL,
@ -10,11 +10,11 @@ CREATE TABLE source_files (
FOREIGN KEY (mime_type) REFERENCES mime_types(id)
ON DELETE SET NULL
);
CREATE TABLE destinations (
CREATE TABLE IF NOT EXISTS destinations (
id INTEGER PRIMARY KEY,
name TEXT UNIQUE NOT NULL
);
CREATE TABLE destination_files (
CREATE TABLE IF NOT EXISTS destination_files (
id INTEGER PRIMARY KEY,
filename TEXT,
old_filename TEXT,
@ -27,11 +27,11 @@ CREATE TABLE destination_files (
FOREIGN KEY (destination_id) REFERENCES destinations(id)
ON DELETE CASCADE
);
CREATE TABLE mime_types (
CREATE TABLE IF NOT EXISTS mime_types (
id INTEGER PRIMARY KEY,
mime_text TEXT UNIQUE NOT NULL
);
CREATE TABLE mime_actions (
CREATE TABLE IF NOT EXISTS mime_actions (
id INTEGER PRIMARY KEY,
mime_type INTEGER,
destination_id INTEGER,
@ -40,7 +40,7 @@ CREATE TABLE mime_actions (
FOREIGN KEY (destination_id) REFERENCES destinations(id)
ON DELETE CASCADE
);
CREATE TABLE tags (
CREATE TABLE IF NOT EXISTS tags (
source_file INTEGER PRIMARY KEY,
genre TEXT,
albumartist TEXT,
@ -61,13 +61,14 @@ CREATE TABLE tags (
ON DELETE CASCADE
);
CREATE VIEW mime_type_actions AS
CREATE VIEW IF NOT EXISTS mime_type_actions AS
SELECT
mime_types.id,mime_types.mime_text,
mime_actions.destination_id,mime_actions.action
FROM mime_types INNER JOIN mime_actions
ON mime_actions.mime_type = mime_types.id;
CREATE TRIGGER update_mime_actions INSTEAD OF UPDATE OF action ON mime_type_actions
CREATE TRIGGER IF NOT EXISTS update_mime_actions
INSTEAD OF UPDATE OF action ON mime_type_actions
BEGIN
UPDATE mime_actions
SET action=new.action
@ -75,7 +76,8 @@ BEGIN
AND destination_id=old.destination_id;
END;
CREATE TRIGGER create_dest_files_and_mime_actions AFTER INSERT ON destinations
CREATE TRIGGER IF NOT EXISTS create_dest_files_and_mime_actions
AFTER INSERT ON destinations
BEGIN
INSERT INTO mime_actions
(mime_type,destination_id)
@ -87,7 +89,7 @@ BEGIN
FROM source_files;
END;
CREATE TRIGGER create_mime_actions AFTER INSERT ON mime_types
CREATE TRIGGER IF NOT EXISTS create_mime_actions AFTER INSERT ON mime_types
BEGIN
INSERT INTO mime_actions (mime_type,destination_id)
SELECT mime_types.id,destinations.id
@ -95,18 +97,24 @@ BEGIN
WHERE mime_types.id=new.id;
END;
CREATE INDEX sourcefiles_by_name ON source_files (filename,id);
CREATE INDEX IF NOT EXISTS sourcefiles_by_name ON source_files (filename,id);
CREATE TRIGGER create_destinations AFTER INSERT ON source_files
CREATE TRIGGER IF NOT EXISTS create_destinations AFTER INSERT ON source_files
BEGIN
INSERT INTO destination_files (source_file_id,destination_id)
SELECT source_files.id,destinations.id FROM source_files
INNER JOIN destinations
WHERE source_files.id=new.id;
END;
CREATE TRIGGER create_tags AFTER INSERT ON source_files
CREATE TRIGGER IF NOT EXISTS create_tags AFTER INSERT ON source_files
BEGIN
INSERT INTO tags (source_file,last_change) VALUES (new.id,0);
END;
CREATE TRIGGER IF NOT EXISTS force_destination_update_on_tag_update
AFTER UPDATE ON tags
BEGIN
UPDATE destination_files SET last_change=0
WHERE source_file_id=old.source_file;
END;
COMMIT;