Init
This commit is contained in:
commit
138ffbbba3
|
@ -0,0 +1,29 @@
|
|||
================================================================================
|
||||
SONGATTR
|
||||
================================================================================
|
||||
songattr.sh uses FFMPEG to fill the Audio:* & Media:* attributes for audio
|
||||
files. It will populate Audio:Artist, Audio:Album, Audio:Track, Media:Title,
|
||||
and Media:Year, as possible. Additionally, if lyrics are embedded in the file,
|
||||
it will set the non-standard Audio:Lyrics attribute.
|
||||
|
||||
In addition, it can set the Album:Artist and Media:Year attributes for the
|
||||
parent directory (assumed to be the Album folder), using a custom audio/x-album
|
||||
filetype. You can add the Album type to your system by building and running
|
||||
album_attr/ once.
|
||||
|
||||
========================================
|
||||
USAGE
|
||||
========================================
|
||||
usage: songattr [-ha] file
|
||||
-h print more detailed help info
|
||||
-a treat the parent directory as an Album file
|
||||
|
||||
Since songattr can only take one file at a time, you'll probably end up using
|
||||
it like this:
|
||||
$ for file in ./*.mp3; do songattr "$file"; done
|
||||
|
||||
========================================
|
||||
BORING STUFF
|
||||
========================================
|
||||
MIT License
|
||||
Jaidyn Ann, jadedctrl@teknik.io
|
|
@ -0,0 +1,131 @@
|
|||
## Haiku Generic Makefile v2.6 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
## Makefile-Engine will do all of the hard work for you. This handles any
|
||||
## architecture of Haiku.
|
||||
##
|
||||
## For more information, see:
|
||||
## file:///system/develop/documentation/makefile-engine.html
|
||||
|
||||
# The name of the binary.
|
||||
NAME = album_attr
|
||||
|
||||
# The type of binary, must be one of:
|
||||
# APP: Application
|
||||
# SHARED: Shared library or add-on
|
||||
# STATIC: Static library archive
|
||||
# DRIVER: Kernel driver
|
||||
TYPE = APP
|
||||
|
||||
# If you plan to use localization, specify the application's MIME signature.
|
||||
APP_MIME_SIG =
|
||||
|
||||
# The following lines tell Pe and Eddie where the SRCS, RDEFS, and RSRCS are
|
||||
# so that Pe and Eddie can fill them in for you.
|
||||
#%{
|
||||
# @src->@
|
||||
|
||||
# Specify the source files to use. Full paths or paths relative to the
|
||||
# Makefile can be included. All files, regardless of directory, will have
|
||||
# their object files created in the common object directory. Note that this
|
||||
# means this Makefile will not work correctly if two source files with the
|
||||
# same name (source.c or source.cpp) are included from different directories.
|
||||
# Also note that spaces in folder names do not work well with this Makefile.
|
||||
SRCS = main.cpp
|
||||
|
||||
# Specify the resource definition files to use. Full or relative paths can be
|
||||
# used.
|
||||
RDEFS =
|
||||
|
||||
# Specify the resource files to use. Full or relative paths can be used.
|
||||
# Both RDEFS and RSRCS can be utilized in the same Makefile.
|
||||
RSRCS =
|
||||
|
||||
# End Pe/Eddie support.
|
||||
# @<-src@
|
||||
#%}
|
||||
|
||||
# Specify libraries to link against.
|
||||
# There are two acceptable forms of library specifications:
|
||||
# - if your library follows the naming pattern of libXXX.so or libXXX.a,
|
||||
# you can simply specify XXX for the library. (e.g. the entry for
|
||||
# "libtracker.so" would be "tracker")
|
||||
#
|
||||
# - for GCC-independent linking of standard C++ libraries, you can use
|
||||
# $(STDCPPLIBS) instead of the raw "stdc++[.r4] [supc++]" library names.
|
||||
#
|
||||
# - if your library does not follow the standard library naming scheme,
|
||||
# you need to specify the path to the library and it's name.
|
||||
# (e.g. for mylib.a, specify "mylib.a" or "path/mylib.a")
|
||||
LIBS = be $(STDCPPLIBS)
|
||||
|
||||
# Specify additional paths to directories following the standard libXXX.so
|
||||
# or libXXX.a naming scheme. You can specify full paths or paths relative
|
||||
# to the Makefile. The paths included are not parsed recursively, so
|
||||
# include all of the paths where libraries must be found. Directories where
|
||||
# source files were specified are automatically included.
|
||||
LIBPATHS =
|
||||
|
||||
# Additional paths to look for system headers. These use the form
|
||||
# "#include <header>". Directories that contain the files in SRCS are
|
||||
# NOT auto-included here.
|
||||
SYSTEM_INCLUDE_PATHS =
|
||||
|
||||
# Additional paths paths to look for local headers. These use the form
|
||||
# #include "header". Directories that contain the files in SRCS are
|
||||
# automatically included.
|
||||
LOCAL_INCLUDE_PATHS =
|
||||
|
||||
# Specify the level of optimization that you want. Specify either NONE (O0),
|
||||
# SOME (O1), FULL (O3), or leave blank (for the default optimization level).
|
||||
OPTIMIZE :=
|
||||
|
||||
# Specify the codes for languages you are going to support in this
|
||||
# application. The default "en" one must be provided too. "make catkeys"
|
||||
# will recreate only the "locales/en.catkeys" file. Use it as a template
|
||||
# for creating catkeys for other languages. All localization files must be
|
||||
# placed in the "locales" subdirectory.
|
||||
LOCALES =
|
||||
|
||||
# Specify all the preprocessor symbols to be defined. The symbols will not
|
||||
# have their values set automatically; you must supply the value (if any) to
|
||||
# use. For example, setting DEFINES to "DEBUG=1" will cause the compiler
|
||||
# option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG" would pass
|
||||
# "-DDEBUG" on the compiler's command line.
|
||||
DEFINES =
|
||||
|
||||
# Specify the warning level. Either NONE (suppress all warnings),
|
||||
# ALL (enable all warnings), or leave blank (enable default warnings).
|
||||
WARNINGS =
|
||||
|
||||
# With image symbols, stack crawls in the debugger are meaningful.
|
||||
# If set to "TRUE", symbols will be created.
|
||||
SYMBOLS :=
|
||||
|
||||
# Includes debug information, which allows the binary to be debugged easily.
|
||||
# If set to "TRUE", debug info will be created.
|
||||
DEBUGGER :=
|
||||
|
||||
# Specify any additional compiler flags to be used.
|
||||
COMPILER_FLAGS =
|
||||
|
||||
# Specify any additional linker flags to be used.
|
||||
LINKER_FLAGS =
|
||||
|
||||
# Specify the version of this binary. Example:
|
||||
# -app 3 4 0 d 0 -short 340 -long "340 "`echo -n -e '\302\251'`"1999 GNU GPL"
|
||||
# This may also be specified in a resource.
|
||||
APP_VERSION :=
|
||||
|
||||
# (Only used when "TYPE" is "DRIVER"). Specify the desired driver install
|
||||
# location in the /dev hierarchy. Example:
|
||||
# DRIVER_PATH = video/usb
|
||||
# will instruct the "driverinstall" rule to place a symlink to your driver's
|
||||
# binary in ~/add-ons/kernel/drivers/dev/video/usb, so that your driver will
|
||||
# appear at /dev/video/usb when loaded. The default is "misc".
|
||||
DRIVER_PATH =
|
||||
|
||||
## Include the Makefile-Engine
|
||||
DEVEL_DIRECTORY := \
|
||||
$(shell findpaths -r "makefile_engine" B_FIND_PATH_DEVELOP_DIRECTORY)
|
||||
include $(DEVEL_DIRECTORY)/etc/makefile-engine
|
|
@ -0,0 +1,41 @@
|
|||
#include <iostream>
|
||||
#include <InterfaceDefs.h>
|
||||
#include <Message.h>
|
||||
#include <MimeType.h>
|
||||
|
||||
// add the given attribute to a BMessage for use as attr info
|
||||
// borrowed from mailserver, thanks!
|
||||
static void addAttribute
|
||||
( BMessage& msg, const char* name, const char* publicName, int32 type, int32 width )
|
||||
{
|
||||
msg.AddString( "attr:name", name );
|
||||
msg.AddString( "attr:public_name", publicName );
|
||||
msg.AddInt32( "attr:type", type );
|
||||
msg.AddInt32( "attr:width", width );
|
||||
msg.AddInt32( "attr:alignment", B_ALIGN_LEFT );
|
||||
msg.AddBool( "attr:extra", false );
|
||||
msg.AddBool( "attr:viewable", true );
|
||||
msg.AddBool( "attr:editable", true );
|
||||
}
|
||||
|
||||
// install the x-album filetype for folders containing music
|
||||
int main ( int argc, char** argv )
|
||||
{
|
||||
BMessage info;
|
||||
BMimeType mime( "audio/x-album" );
|
||||
if ( mime.IsInstalled() ) return 2;
|
||||
|
||||
std::cout << "DAD";
|
||||
mime.GetAttrInfo( &info );
|
||||
|
||||
mime.SetShortDescription( "Album" );
|
||||
mime.SetLongDescription( "Generic audio container" );
|
||||
|
||||
addAttribute( info, "Audio:Artist", "", B_STRING_TYPE, 200 );
|
||||
addAttribute( info, "Album:Title", "", B_STRING_TYPE, 200 );
|
||||
addAttribute( info, "Media:Year", "Year", B_INT32_TYPE, 200 );
|
||||
|
||||
mime.SetAttrInfo( &info );
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
#!/bin/sh
|
||||
# --------------------------------------
|
||||
# name: music2attr
|
||||
# main: jadedctrl<@teknik.io>
|
||||
# lisc: MIT
|
||||
# date: 2020-11
|
||||
# --------------------------------------
|
||||
|
||||
# ======================================
|
||||
# FFMPEG PARSING
|
||||
# ======================================
|
||||
# prints metadata output from FFMPEG of the given file
|
||||
function song_metadata {
|
||||
local file="$1"
|
||||
|
||||
ffmpeg -i "$file" 2>&1 \
|
||||
| sed '1,/Metadata/d' \
|
||||
| head -n -1 \
|
||||
| sed 's% : %:%'
|
||||
}
|
||||
|
||||
# get value of song's metadata key, from it's `song_metadata` output
|
||||
function get_value {
|
||||
local trait="$1"
|
||||
|
||||
sed -n "/^ *${trait}.*:/I,\$p" \
|
||||
| sed "s/$trait//i" \
|
||||
| print_until_nonempty
|
||||
}
|
||||
|
||||
# ======================================
|
||||
# ATTRIBUTES
|
||||
# ======================================
|
||||
|
||||
|
||||
# set a song's metadata attribute, if file contains it
|
||||
# pipe in output from `song_metadata`
|
||||
function set_attr {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
local attr="$3"
|
||||
local type="$4"
|
||||
|
||||
local value="$(get_value "$key")"
|
||||
|
||||
if test "$type" = "time"; then set_time_attr "$file" "$attr" "$value"; return; fi
|
||||
if echo "$type"|grep -q "^int";then set_int_attr "$file" "$attr" "$value" "$type";return;fi
|
||||
|
||||
if test -n "$value"; then
|
||||
addattr -t "$type" "$attr" "$value" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
# we have some special sanitization to do for time attributes (helper of 'set_attr')
|
||||
function set_time_attr {
|
||||
local file="$1"; local attr="$2"; local value="$3"
|
||||
|
||||
if test 5 -eq "$(echo "$value" | wc -c)"; then
|
||||
value="${value}-01-01"
|
||||
fi
|
||||
if test -n "$value"; then
|
||||
addattr -t "time" "$attr" "$value" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
# we have some special sanitization to do for ints, too (helper of 'set_attr')
|
||||
function set_int_attr {
|
||||
local file="$1"; local attr="$2"; local value="$3"; local type="$4"
|
||||
|
||||
value="$(echo "$value" | sed 's%[A-z/, -].*%%')"
|
||||
if test -n "$value"; then
|
||||
addattr -t "$type" "$attr" "$value" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
# set a file's entire all song-related attributes
|
||||
function set_song_attrs {
|
||||
local file="$1"
|
||||
meta="$(song_metadata "$file")"
|
||||
|
||||
echo "$meta" | set_title_attr "$file" "Media:title"
|
||||
echo "$meta" | set_year_attr "$file" "Media:Year"
|
||||
echo "$meta" | set_lyrics_attr "$file" "Audio:Lyrics"
|
||||
echo "$meta" | set_artist_attr "$file" "Audio:Artist"
|
||||
echo "$meta" | set_album_attr "$file" "Audio:Album"
|
||||
echo "$meta" | set_track_attr "$file" "Audio:Track"
|
||||
}
|
||||
|
||||
# set all of an album's necessary attributes
|
||||
function set_album_attrs {
|
||||
song="$1"
|
||||
album="$(dirname "$song")"
|
||||
meta="$(song_metadata "$song")"
|
||||
|
||||
addattr -t mime "BEOS:TYPE" "audio/x-album" "$album"
|
||||
echo "$meta" | set_artist_attr "$album" "Album:Artist"
|
||||
echo "$meta" | set_year_attr "$album" "Media:Year"
|
||||
}
|
||||
|
||||
function set_title_attr { set_attr "$1" "TITLE" "$2" "string"; }
|
||||
function set_year_attr { set_attr "$1" "DATE" "$2" "int32"; }
|
||||
function set_lyrics_attr { set_attr "$1" "LYRICS" "$2" "string"; }
|
||||
function set_artist_attr { set_attr "$1" "ARTIST" "$2" "string"; }
|
||||
function set_album_attr { set_attr "$1" "ALBUM" "$2" "string"; }
|
||||
function set_track_attr { set_attr "$1" "TRACK" "$2" "int32"; }
|
||||
|
||||
# ======================================
|
||||
# UTIL
|
||||
# ======================================
|
||||
# selects all fields except the first, until a a line's first field is non-empty
|
||||
# delimiter used is a colon.
|
||||
function print_until_nonempty {
|
||||
awk -F ':' \
|
||||
'{ lines[NR] = $0 }
|
||||
END { i = 1
|
||||
split( lines[i], L )
|
||||
while ( i <= NR && match( L[1], /^( )+$/ ) ) {
|
||||
for ( j = 2; j <= length(L); j = j + 1 ) {
|
||||
if ( j > 2 )
|
||||
printf ":"
|
||||
printf L[j]
|
||||
}
|
||||
printf "\n"
|
||||
i = i + 1
|
||||
split( lines[i], L )
|
||||
}
|
||||
}'
|
||||
}
|
||||
|
||||
# ======================================
|
||||
# INVOCATION
|
||||
# ======================================
|
||||
function help {
|
||||
echo "usage: $(basename $0) [-hi] [-A|a] file"
|
||||
echo
|
||||
echo \
|
||||
"Use a song file's metadata to populate related attributes. The attributes set
|
||||
are 'Media:Title', 'Audio:Artist', 'Audio:Album', 'Audio:Track', and 'Media:year'.
|
||||
|
||||
In addition, the parent directory is assumed to be the 'album' folder, its
|
||||
type is set to 'audio/x-album', and has its attributes populated with relevant
|
||||
metadata. The attributes set to 'album' folders are 'Album:Artist' and
|
||||
'Media:Year', based on the song files' metadata.
|
||||
|
||||
$(basename $0) requires 'ffmpeg' to be installed.
|
||||
|
||||
-a don't edit the parent directory's attributes
|
||||
-A only edit the parent directory's attributes
|
||||
-h prints this message."
|
||||
exit 1
|
||||
}
|
||||
|
||||
ALBUM=1
|
||||
SONG=1
|
||||
|
||||
while getopts ":haAi" arg; do
|
||||
case $arg in
|
||||
a) ALBUM=0;;
|
||||
A) ALBUM=1; SONG=0;;
|
||||
|
||||
h) help;;
|
||||
esac
|
||||
done
|
||||
|
||||
shift $(($OPTIND - 1))
|
||||
|
||||
if test -z "$@"; then help; fi
|
||||
if test ! -e /bin/ffmpeg; then help; fi
|
||||
|
||||
if test "$SONG" -eq 1; then set_song_attrs "$@"; fi
|
||||
if test "$ALBUM" -eq 1; then set_album_attrs "$@"; fi
|
Ŝarĝante…
Reference in New Issue