You are not logged in.
So the issue was not MPD, i hadn't noticed my script was creating a bad symlink when i passed it a relative path. new problem, the simplest way to accept any relative path as argument and return an absolute path for use throughout the script. i'm off to google...
my current version of the solution as a bashrc function:
rel2abs() {
local file="$(basename "$1")"
local dir="$(dirname "$1")"
pushd "${dir:-./}" &>/dev/null && local dir="$PWD"
echo "$dir/$file"
popd &>/dev/null
}
:: OP ::
so i have this little script that is supposed to allow me to one-time-play an audio file sitting outside my mpd directory by creating a symlink to the file, updating the db, then playing the symlink. everything's great accept mpd won't follow the symlink when creating/updating the db.
i've restarted mpd and re-create[d]-db both as myself (mpd runs as me) and as root many, many times. it never changes. the symlink file is never added to my database... is the manpage lying? do i file a bug? can anyone else reproduce?
i don't think it's a perm issue, mpd runs as me and the symlink's target and destination are both under ~/
┌─[ 13:30 ][ blue:~ ]
└─> pacman -Q mpd
mpd 0.15.1-1
follow_outside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing outside the music dir. You must
recreate the database after changing this option. The default is "yes".follow_inside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing inside the music dir, potentially
adding duplicates to the database. You must recreate the database after changing this
option. The default is "yes".
######################### OTHER OPTIONS ########################
gapless_mp3_playback "yes"
#save_absolute_paths_in_playlists "no"
#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
follow_outside_symlinks "yes"
follow_inside_symlinks "yes"
┌─[ 13:33 ][ blue:~ ]
└─> ll Music/temp/
total 0
lrwxrwxrwx 1 patrick patrick 36 2009-08-13 13:30 apocalyptica_beyond_time.mp3 -> Dropbox/apocalyptica_beyond_time.mp3
┌─[ 13:37 ][ blue:~ ]
└─> mpc ls temp
┌─[ 13:37 ][ blue:~ ]
└─>
i guess i can resort to simply copying the file into the temp directory rather than symlinking... but you archers know how it is, it just bothers you when something should work and it doesn't...
comments and pointers always appreciated.
Last edited by brisbin33 (2009-08-17 20:35:21)
//github/
Offline
It's a dead symlink: take a look at the part after -> again while inside Music/Temp
Offline
It's a dead symlink: take a look at the part after -> again while inside Music/Temp
┌─[ 14:26 ][ blue:~ ]
└─> file Music/temp/apocalyptica_beyond_time.mp3
Music/temp/apocalyptica_beyond_time.mp3: broken symbolic link to `Dropbox/apocalyptica_beyond_time.mp3'
well, i'll be... so the issue is...
if i pass $1 to my script as directory/file.mp3 (which is fine relative to ~/, where i am in the filesystem), then ln doesn't know the difference so it symlinks to directory/file.mp3 which is ofcourse a stupid thing to do inside ~/Music/temp/.
let me think about a way to 'cleanse' $1 before symlinking...
i'll test and report back what i come up with (and also mark [SOLVED]). thanks for the fresh set of eyes Procyon
EDIT: this is proving more difficult than i thought, anyone know the KISSest way to take a relative path and return an absolute path inside a bash script?
i can take care of ./* ~/* /* with a small case statement, but if possible, i'd like to account for all possibilities.
Last edited by brisbin33 (2009-08-13 18:55:02)
//github/
Offline
Mind posting your script? I've been using the following perl script to play a file outside of the music directory using mpd (found through the mpd wiki, I think). I'm up for a simpler solution if you found one!
#!/usr/bin/perl
# mpc-play
# version 0.2
# by Ilya "Voyager" Schurov (http://comm.noo.ru/iv-en/)
$MUSIC_PREFIX="/home/[username]/music";
$TEMP_DIR="tmp";
$SCRIPT_NAME="mpc-play";
# warning! all symlinks in $MUSIC_PREFIX/$TEMP_DIR will be lost on start!
$DEBUG=0;
$PWD=`pwd`;
chomp $PWD;
if(!@ARGV)
{
print "Usage:\n$SCRIPT_NAME <files-to-play>\n";
}
say_and_do("mpc --no-status stop",$DEBUG);
say_and_do("mpc --no-status clear",$DEBUG);
# removing symlinks from $TEMP_DIR
while(<$MUSIC_PREFIX/$TEMP_DIR/*>)
{
unlink if(-l);
}
foreach $file (@ARGV)
{
$link=$file;
# stripping slashes from arguments
$link=~s/\//_/g;
if($file!~/^\//)
{
$file="$PWD/$file";
}
symlink("$file","$MUSIC_PREFIX/$TEMP_DIR/$link")
|| die("Can't create symlink from $file to $MUSIC_PREFIX/$TEMP_DIR/$link: $!");
push @links, $link;
}
say_and_do("mpc update $TEMP_DIR",$DEBUG);
# now we need to wait while mpd updating DB
do
{
$stat=`mpc`;
sleep(0.1);
}while($stat=~/^Updating DB/m);
# generating playlist
foreach $link(@links)
{
$link=~s/\`/\\\`/g;
say_and_do("mpc --no-status add \"$TEMP_DIR/$link\"",$DEBUG);
}
#let's the music begins! :)
say_and_do("mpc play",$DEBUG);
sub say_and_do
{
my $str=shift;
my $debug=shift;
print "$str\n" if($debug);
system($str);
}
Thanks!
Scott
Offline
yeah, mines a bit shorter; and it's working really well so far:
#!/bin/bash
#
# creates a temp symlink to a file outside mpd DB
# adds it to the playlist and plays it
#
###
# usage: playnow [file]
[ $# -ne 1 ] && exit 1
# find our music directory
mdir="$(awk -F '"' '/^music_directory/ {print $2}' /etc/mpd.conf)"
# no matter what we pass, or where we are, we get
# an absolute path to the file we want. nifty.
file="$(basename $1)"
dir="$(dirname $1)"
cd ${dir:-./} && dir="$PWD" || exit 1
# clean the temp dir and make the new symlink
rm -rf "$mdir/temp"; mkdir "$mdir/temp"
ln -s "$dir/$file" "$mdir/temp/$file"
# update the db, add the new file, and play it
mpc --no-status update "temp/$file"
mpc --no-status add "temp/$file" &>/dev/null || exit 1
mpc play $(mpc playlist | wc -l)
exit $?
usage is simply `playnow some_file.mp3`. i keep my system completely clean of spaces in filenames so if you have those you'll want to tweak some parts...
/edit: a slight simplification.
Last edited by brisbin33 (2009-08-13 20:36:59)
//github/
Offline
I have spaces -- lots of spaces -- so I had to change \
file="$(basename $1)"
dir="$(dirname $1)"
to
file="$(basename "$1")"
dir="$(dirname "$1")"
and the ~/music wasn't being evaluated as an actual path (error: 'cannot create ~/music/temp'), so I came up with
mdir="$(awk -F '"' '/^music_directory/ {print $2}' /etc/mpd.conf)"
mdir=`eval echo "$mdir"`
To get mdir as an actual path. I'm sure there's a MUCH better way to do that, but I just keep trying things until they work
Works great now with spaces and ~ ! Think I'll switch You should get that added to the list of MPD hacks on their wiki.
Thanks!
Scott
Offline
thanks firecat, i've adopted your "$1" changes just because it makes the script more portable.
i'd also recommend this for the ~ issue: (i keep absolute paths in /etc/mpd.conf so i never got bit by that)
# find our music directory
mdir="$(awk -F '"' '/^music_directory/ {print $2}' /etc/mpd.conf)"
mdir="${mdir/\~/$HOME}"
odd, neither sed nor tr wanted to switch out ~ for $HOME easily, but the bashism works quite nicely. One could probably put the switch right in the awk statement, but that's beyond me.
//github/
Offline
I'm a little tired so maybe I didn't understand the question, but to get a full un-qualified path you could use:
realpath -s /dir
realpath /dir
The former will follow a link to it's source.
Edit: bah, just re-read, I probably need to get some sleep.
Last edited by Gen2ly (2009-08-17 21:36:20)
Setting Up a Scripting Environment | Proud donor to wikipedia - link
Offline
"${mdir/\~/$HOME}" simply means "evaluate $mdir but switch any occurance of ~ with $HOME" so:
if $mdir="~/Music", then ${mdir/\~/$HOME/}="$HOME/Music"="/home/user/Music" which i believe solves our issue with mkdir.
//github/
Offline
Ah, neat -- sort of like a shorthand sed search and replace I guess. Works great!
Thanks, Scott
P.S. thanks also for your dmenu cache script and light/dark grey colorscheme. I stole both of those for my dwm configs
Offline