You are not logged in.

#1 2011-04-01 22:58:17

Markus00000
Member
Registered: 2011-03-27
Posts: 318

[SOLVED] ncmpcpp: rate songs?

Is there a straightforward way to rate songs in ncmpcpp? It wouldn't matter if the ratings were stored in a custom tag or database.

The only (not so straightforward) way that came to my mind was to edit the comment tag which I think ncmpcpp could search afterwards. Though doing this manually would be pretty straightbackward...

Last edited by Markus00000 (2011-04-02 06:07:49)

Offline

#2 2011-04-02 01:04:09

Wintervenom
Member
Registered: 2008-08-20
Posts: 1,011

Re: [SOLVED] ncmpcpp: rate songs?

#!/bin/bash
### MPD Ratings ################
# Version 0.1 by Scott Garrett #
# Wintervenom [(at)] gmail.com #
################################
# Dependencies:
# - mpc
#

# Be sure to change these to reflect your setup.
library="$HOME/Music/Library"
playlists="$HOME/Music/Playlists"

song=$(mpc current -f '%file%')
pl_prefix='rated-'
pl_suffix='.m3u'

if [[ -z "$song" ]]; then
    echo 'No song is playing.'
    exit 1
elif [[ "$1" -lt 1 || "$1" -gt 5 ]]; then
    echo 'Rating must be between 1 and 5.'
    exit 1
fi

# Remove the song from other rating playlists if found.
for n in {1..5}; do
    f="$playlists/${pl_prefix}$n${pl_suffix}"
    if [[ -f "$f" ]]; then
        grep -vF "/$song" "$f" > "/tmp/new.m3u"
        sort -u "/tmp/new.m3u" -o "$f"
        # Remove rating playlist if empty.
        # It takes more than three bytes to store a path.
        [[ $(wc -c < "$f") -lt 4 ]] &&
            rm "$f"
    fi
done

# Append the song to the new rating playlist.
f="$playlists/${pl_prefix}$1${pl_suffix}"
mkdir -p "$playlists"
echo "$library/$song" >> "$f"
sort -u "$f" -o "$f"

[[ -f "/tmp/new.m3u" ]] && rm "/tmp/new.m3u"

Last edited by Wintervenom (2011-04-02 01:14:07)

Offline

#3 2011-04-02 06:07:10

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

Thanks so much. This seems to be an excellent solution!

Offline

#4 2011-04-08 14:30:17

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

I changed your script slightly to work with ncmpcpp. I also added the possibility to remove a song from all rating lists. Here it goes:

#!/bin/bash
#
# Modified version for ncmpcpp. Based on:
#
### MPD Ratings ################
# Version 0.1 by Scott Garrett #
# Wintervenom [(at)] gmail.com #
################################
# Dependencies:
# - ncmpcpp
#
# Usage: Save the script to a file, e.g. "ratesong", make it executable.
# Invoke the script with "ratesong [rating]", where rating is a number between 0 and 5.
# 0 will remove the current song from any rating playlist.
# 1-5 will add the current song to the appropriate rating playlist and remove it from all others.

## Be sure to change these to reflect your setup.
library="" # with trailing slash; leave empty for using paths relative to your mpd library
playlists="$HOME/.mpd/playlists"

song=`ncmpcpp --now-playing '%D/%f'`
song="$library$song"

## Prefix and suffix strings for the playlist file name.
pl_prefix=''
pl_suffix='.m3u'

## Error cases.
if [[ -z "$song" || "$song" == 'Cannot connect to mpd: Connection refused' ]]; then
    echo 'No song is playing.'
    exit 1
elif [[ "$1" -lt 0 || "$1" -gt 5 ]]; then
    echo "Rating must be between 1 and 5. Or zero to delete the current song's rating."
    exit 1
fi

## Allow only one instance by creating a lock file.
if [[ -f "$playlists/lock" ]]; then
    zenity --info --text="Rating failed!\n\nAnother instance is running." &
    exit 1
fi
touch "$playlists/lock"

## Remove the song from other rating playlists if found.
for n in {1..5}; do
    f="$playlists/${pl_prefix}$n${pl_suffix}"
    tmp="$playlists/tmp.m3u"
    if [[ -f "$f" ]]; then
        cp "$f" "$tmp"
        grep -vF "$song" "$tmp" > "$f"
        rm "$tmp"
        ## Don't do this, it seems to empty rating playlists occasionally:
        #grep -vF "$song" "$f" > "$tmp"
        #mv "$tmp" "$f"
    fi
done

## Append the song to the new rating playlist.
if [[ $1 -ne 0 ]]; then
    f="$playlists/${pl_prefix}$1${pl_suffix}"
    mkdir -p "$playlists"
    echo "$song" >> "$f"
    sort -u "$f" -o "$f"
fi

rm "$playlists/lock"

Thanks again!

Edit: Added possibility for relative paths in playlists. Also there is no entry added to a playlist if mpd is not running.

Last edited by Markus00000 (2011-06-12 17:34:20)

Offline

#5 2011-04-21 21:00:04

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

I updated the script again. I was invoking it via keyboard shortcuts and noticed that playlists could be deleted or mixed up with duplicates when two instances ran at the same time. The script now uses a lock file to allow only one instance.

I also removed "sort" after deleting the rated song from each playlist. Deleting a song seemed not to mess up the sorted playlist. Should be fine as playlists are still sorted after adding a new song.

Last edited by Markus00000 (2011-04-21 21:02:43)

Offline

#6 2011-04-22 08:33:04

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

Still my playlists ended up being empty sometimes and I think I know why:

grep -vF "$song" "$f" > "$f"

Reading and writing from/into the same file seemed to be the cause. When I use a temporary file, my playlists won't be emptied:

grep -vF "$song" "$f" > "$tmp"
mv "$tmp" "$f"

I updated the script (again). smile

Offline

#7 2011-05-12 23:18:20

FurryDonkey
Member
Registered: 2011-05-05
Posts: 6

Re: [SOLVED] ncmpcpp: rate songs?

Markus00000

A couple of months ago I was trying to do what your first post mentioned in ncmpcpp but had some problems.  I added a number into the comment song tag which seemed to work, but for some reason ncmpcpp would not search by criteria in the comments field.  Anyway after a while I gave up.

Can you post the latest script?  I am not to familiar with bash scripts so I have a few questions which hopefully do not seem silly.

1.  Does the script actually write the value of 0, 1, 2, 3, 4, or 5 to the comments tag on the song?
2.  I am using flac music files; would the script have a problem with this?

Anyway, I don't want to ask to much since I should play around with the script to get a better idea of what is happening.  A very brief (just a couple points or sentences) summary on how the script works and what it does would be helpful if you don't mind.

Thanx

Offline

#8 2011-05-13 00:05:40

Wintervenom
Member
Registered: 2008-08-20
Posts: 1,011

Re: [SOLVED] ncmpcpp: rate songs?

It toggles the currently-playing song from numbered rating playlists.

Offline

#9 2011-05-13 09:26:36

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

FurryDonkey wrote:

1.  Does the script actually write the value of 0, 1, 2, 3, 4, or 5 to the comments tag on the song?

No, it does not. It manages five .m3u playlists in the specified playlists folder. These are simple text files listing the paths to all files in the playlist. The playlists will show up in ncmpcpp so there is no need to search for certain comment tags. (Comment tags are not altered by the script.)

FurryDonkey wrote:

2.  I am using flac music files; would the script have a problem with this?

I have no flac files but as the playlists simply list paths to files, their file extensions should not matter at all.

I added some more comments to the script (see above). Hopefully this makes it easier to understand for you.

If you have further questions, feel free to ask.

Last edited by Markus00000 (2011-05-13 22:09:15)

Offline

#10 2011-05-13 16:48:15

FurryDonkey
Member
Registered: 2011-05-05
Posts: 6

Re: [SOLVED] ncmpcpp: rate songs?

Markus00000:
The details you posted and comments added into the script are just what I needed to get started.  I will try this out.  I think it solves a problem with mpd/mpd clients that I have in that I could not rate songs since I have quite a large library.  I am using a small computer (alix) embedded with voyage linux running mpd to supply my DAC and pulling song off my server running Arch so I don't want to use Amarok or anything.  I like mpd better anyway.  I will play with this for a while and let you know if I get stuck on something.

Thanks again.

Offline

#11 2011-05-13 21:08:39

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

*deleted*

Last edited by Markus00000 (2011-05-13 22:20:15)

Offline

#12 2011-05-13 22:19:52

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

Sorry for my editing mess. I noticed two problems and therefore updated my original script incorporating all changes and comments. To avoid confusion, I removed the second version of the script.

The relevant problem was that sometimes a rating playlist was overwritten with an empty file (backup!). I don't understand why, but after switching to a seemingly equivalent implementation it seems to work. The problematic code is:

## Don't do the following, it seems to empty rating playlists occasionally.
## Anyone knows why?
    #grep -vF "$song" "$f" > "$tmp"
    #mv "$tmp" "$f"

Last edited by Markus00000 (2011-11-10 18:44:34)

Offline

#13 2011-11-10 19:12:54

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

Ending up with empty files was caused by a race condition. It can happen when locking with "touch" as I did. More than one instance can bypass the check whether the lock file exists. Then both touch it and run simultaneously. I am not exactly sure how I got into a race condition with such a short script. Maybe accidentally hitting two rating shortcuts at once. Maybe the execution was slow sometimes while disk I/O was high. Either way playlists could end up emptied.

Here are some correct examples about how to lock files without race conditions.

And for the record, the current, race-free version of the script follows. Note that this version is for cmus. Exchanging a line or two from the ncmpcpp version should be easy:

#!/bin/bash
## Usage: rate-music [0-5]

## Path to playlists
playlists="$HOME/music"

## Prefix and suffix strings for the playlist file name
pl_prefix=''
pl_suffix='.m3u'

## Get current song from cmus
song=`cmus-remote -Q | grep file`

## Error cases
if [[ -z "$song" ]]; then
	echo 'No song is playing.'
	exit 1
elif [[ "$1" -lt 0 || "$1" -gt 5 ]]; then
	echo "Rating must be between 1 and 5. Or zero to delete the current song's rating."
	exit 1
fi

## Path to lock file
lock="/tmp/rate-music.lock"

## Lock the file
exec 9>"$lock"
if ! flock -n 9; then
	notify-send "Rating failed: Another instance is running."
	exit 1
fi

## Strip "file " from the output
song=${song/file \///}

## Temporary file for grepping and sorting
tmp="$playlists/tmp.m3u"

## Remove the song from all rating playlists
for n in {1..5}; do
	f="$playlists/${pl_prefix}$n${pl_suffix}"
	if [[ -f "$f" ]]; then
		grep -vF "$song" "$f" > "$tmp"
		mv -f $tmp $f
	fi
done

## Append the song to the new rating playlist
if [[ $1 -ne 0 ]]; then
	f="$playlists/${pl_prefix}$1${pl_suffix}"
	mkdir -p "$playlists"
	echo "$song" >> "$f"
	sort -u "$f" -o "$tmp"
	mv -f $tmp $f
fi

## The lock file will be unlocked when the script ends

Any feedback and suggestions welcome!

Last edited by Markus00000 (2011-11-10 19:16:25)

Offline

#14 2011-12-08 09:15:02

sica07
Member
Registered: 2008-06-06
Posts: 29

Re: [SOLVED] ncmpcpp: rate songs?

Thank yoiu for your script, Markus.
I'm using your last script (the one for cmus) with ncmcpp. I'm fetching the song with the:

 song=`ncmpcpp --now--playing '%D/%f'` 

The problem is that I get the error:

 song_list_format: invalid character at position 18: '}' 

I made some searching but I can't find where or why is this character inserted. Could you help me?
Thanks!

Offline

#15 2011-12-08 14:31:56

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

I am not sure. Where in the script does the error occur? Maybe some variable must be put in quotes.

You might have better chances by starting a new thread.

Offline

#16 2012-01-18 15:58:44

tUrGon-Noldor
Member
Registered: 2012-01-18
Posts: 1

Re: [SOLVED] ncmpcpp: rate songs?

Can't we actually add the rating into a the song's metadata?

Offline

#17 2012-01-18 21:33:54

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

Most certainly. There are many programs to modify music metadata. Though I don't like the rating in there.

Offline

#18 2012-10-21 22:53:28

styxsailor
Member
Registered: 2012-10-21
Posts: 2

Re: [SOLVED] ncmpcpp: rate songs?

Nice thread, I directly copied your script and amended it to work with ncmpcpp and cmus (N.B I didn't try the latter as I don't use it, but it should be straightforward) and added a couple of descriptive lines. I actually was looking to rate playlists, mostly because I use these for radiostations which are of varying quality, but haven't gotten around to consider it further. 

Did I say thanks?

#!/bin/bash
## Usage: rate-music [0-5]
# 
# Adds current playing song to the mpd playlist corresponding to the
# rating assigned. Any previous rating is removed. If 0 is given, the
# songs rating will be removed.
# 
# From: https://bbs.archlinux.org/viewtopic.php?id=116113

## USER CONFIGURATION-----------------------------------------------------

## Path to playlists
playlists="$HOME/.mpd/playlists"

## END USER CONFIGURATION--------------------------------------------------

## Prefix and suffix strings for the playlist file name
pl_prefix=''
pl_suffix='.m3u'

## Get current song from ncmpcpp or cmus or throw an error
song=`ncmpcpp --now-playing '%D/%f' 2>/dev/null` || \
    song=`cmus-remote -Q 2>/dev/null | grep file` || \
    { echo "Error: you need either ncmpcpp or cmus installed to run this script. Aborting." >&2; exit 1; }

## Error cases
if [[ -z "$song" ]]; then
	echo 'No song is playing.'
	exit 1
elif [[ "$1" -lt 0 || "$1" -gt 5 ]]; then
	echo "Rating must be between 1 and 5. Or zero to delete the current song's rating."
	exit 1
fi

## Path to lock file
lock="/tmp/rate-music.lock"

## Lock the file
exec 9>"$lock"
if ! flock -n 9; then
	notify-send "Rating failed: Another instance is running."
	exit 1
fi

## Strip "file " from the output
song=${song/file \///}

## Temporary file for grepping and sorting
tmp="$playlists/tmp.m3u"

## Remove the song from all rating playlists
for n in {1..5}; do
	f="$playlists/${pl_prefix}$n${pl_suffix}"
	if [[ -f "$f" ]]; then
		grep -vF "$song" "$f" > "$tmp"
		mv -f $tmp $f
	fi
done

## Append the song to the new rating playlist
if [[ $1 -ne 0 ]]; then
	f="$playlists/${pl_prefix}$1${pl_suffix}"
	mkdir -p "$playlists"
	echo "$song" >> "$f"
	sort -u "$f" -o "$tmp"
	mv -f $tmp $f
fi

## The lock file will be unlocked when the script ends

Offline

#19 2012-12-19 16:51:32

iOfWhy
Member
Registered: 2012-05-16
Posts: 26

Re: [SOLVED] ncmpcpp: rate songs?

Markus00000 wrote:

Most certainly. There are many programs to modify music metadata. Though I don't like the rating in there.

How come? There is a tag, POPM (popularimeter) in the id3v2 specification: http://id3.org/id3v2.3.0. Why not use that? If you only want 5 levels i assume you would just use 0 = 0, 1 = 51, 2 = 102, 3 = 153, 4 = 204, 5 = 255... Would really like to see full implementation of ratings in MPD. It's the only thing i still miss from classic media players...

Last edited by iOfWhy (2012-12-19 16:53:58)

Offline

#20 2012-12-20 14:18:13

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

Changing the metadata changes the file, therefore rsync would back it up again.

Syncing often works with playlists. Not sure how often it works based on metadata. I can also use rsync to sync all songs of a certain rating by feeding the playlist straight into it.

Well, these are my reasons and they might be wrong and/or outdated. :-)

Offline

#21 2012-12-21 19:05:57

iOfWhy
Member
Registered: 2012-05-16
Posts: 26

Re: [SOLVED] ncmpcpp: rate songs?

Rsync is so freaking fast thats not a problem for me i guess... eitherway i want updated files to be resynced. But hey different tasks call for different conventions. To quote stanford algorithm expert Donald Knuth, "Who are you and what are you doing in my house?" http://xkcd.com/163/ smile

Great script by the way... easy to add a line so it updates the metadata as well. Thanks a bunch!

Offline

#22 2012-12-31 20:58:36

ravisghosh
Member
From: Intergalactic Spaces
Registered: 2006-10-12
Posts: 516
Website

Re: [SOLVED] ncmpcpp: rate songs?

Is there a keyboard shortcut assigned to the ratings which you press when on an instance of ncmpcpp and the selected file gets rated? Or is that you have to fire up a terminal and issue the command "ratesong 1/2/3/4/5"?

Sorry for the noobish question.

Offline

#23 2013-01-01 10:50:03

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

ravisghosh wrote:

Is there a keyboard shortcut assigned to the ratings which you press when on an instance of ncmpcpp and the selected file gets rated? Or is that you have to fire up a terminal and issue the command "ratesong 1/2/3/4/5"?

I have keyboard shortcuts defined in my window manager (xmonad, mod4 + F1-F6, where F6 removes the rating). The shortcuts were the reason why I had to take care of parallel execution: Accidentally pressing something like mod4+F1+F2 would sometimes empty a playlist.

Offline

#24 2013-01-02 21:01:48

ravisghosh
Member
From: Intergalactic Spaces
Registered: 2006-10-12
Posts: 516
Website

Re: [SOLVED] ncmpcpp: rate songs?

Markus, it would be great if you could put the instructions for noobs, like where do you put the script file and what command to assign for the keyboard shortcuts.

Sorry, if it sounds like asking too much smile


Also, would like to bring your attention towards this thread about starting mpd and ncmpcpp together - https://bbs.archlinux.org/viewtopic.php?id=155471

Last edited by ravisghosh (2013-01-02 21:05:21)

Offline

#25 2013-01-03 15:01:33

Markus00000
Member
Registered: 2011-03-27
Posts: 318

Re: [SOLVED] ncmpcpp: rate songs?

It depends on your window manager or desktop environment how defining keyboard shortcuts works. There could be a GUI for this or just a configuration text file. What WM/DE are you using?

If you find where to define shortcuts, it should be possible to assign a command. The commands would then be "music-rate 1", "music-rate 2" etc. If that doesn't work, it's likely that the music-rate script is not in your path. If so, read this: https://wiki.archlinux.org/index.php/En … es_Locally

I'm currently using the script with cmus to which I switched from mpd.

Offline

Board footer

Powered by FluxBB