Difference between revisions of "How to use Vifm as your music player"
Viminator25 (talk | contribs) (Add Playlist Editor Script) |
m (<source> -> <syntaxhighlight>) |
||
(6 intermediate revisions by one other user not shown) | |||
Line 8: | Line 8: | ||
You '''can''' use older versions of mpc and still get 99% of the functionality, but certain mappings will have to be adjusted for displaying the current status. | You '''can''' use older versions of mpc and still get 99% of the functionality, but certain mappings will have to be adjusted for displaying the current status. | ||
− | The python dependency is only for if you want to sort or edit your playlist with a terminal-based text editor ''on-the-fly'' | + | The python dependency is only for if you want to sort or edit your playlist with a terminal-based text editor ''on-the-fly''. |
− | |||
== Vifm mappings and Commands == | == Vifm mappings and Commands == | ||
Line 15: | Line 14: | ||
Simply copy and paste this into your vifmrc: | Simply copy and paste this into your vifmrc: | ||
− | < | + | {{NOTE|text=Make sure that you set the shell variables to their appropriate locations on the harddrive.}} |
+ | |||
+ | <syntaxhighlight lang="vim"> | ||
" {{{1 MUSIC PLAYER | " {{{1 MUSIC PLAYER | ||
let $SONG_FORMAT="[[%artist% - ]%title%]|[%file%]" | let $SONG_FORMAT="[[%artist% - ]%title%]|[%file%]" | ||
Line 29: | Line 30: | ||
nnoremap rmg :GotoSong<cr> | nnoremap rmg :GotoSong<cr> | ||
nnoremap rmt :mpcStat 2<cr> | nnoremap rmt :mpcStat 2<cr> | ||
− | |||
nnoremap rm0 :let $IGNORE = system('mpd_restart')<cr>:echo 'Music player daemon has been restarted'<cr> | nnoremap rm0 :let $IGNORE = system('mpd_restart')<cr>:echo 'Music player daemon has been restarted'<cr> | ||
nnoremap rmi :mpcinsert<cr>:!echo Song %f:t inserted. %S<cr> | nnoremap rmi :mpcinsert<cr>:!echo Song %f:t inserted. %S<cr> | ||
nnoremap rma :mpcadd<cr>:!echo Song %f:t added. %S<cr> | nnoremap rma :mpcadd<cr>:!echo Song %f:t added. %S<cr> | ||
− | nnoremap rmm :!echo "%f" | sed -e 's/\([^\]\) /\1\n/g' -e 's/\\//g' | xargs -d '\n' -L 1 realpath --relative-to=$MUSIC_DIR %M | sort -nr | xargs -d '\n' -L 1 mpc insert<cr>:mpcplay<cr>:ShowSong<cr> | + | nnoremap rmA :mpcadd<cr>:!mpc play $(mpc playlist | wc -l) %i<cr> |
+ | nnoremap rmm :!echo "%f" | sed -e 's/\([^\]\) /\1\n/g' -e 's/\\//g' | xargs -d '\n' -L 1 realpath -s --relative-to=$MUSIC_DIR %M | sort -nr | xargs -d '\n' -L 1 mpc insert<cr>:mpcplay<cr>:ShowSong<cr> | ||
nnoremap rmd :Delfind<cr> | nnoremap rmd :Delfind<cr> | ||
+ | nnoremap rmD :Delcurrent<cr>:ShowSong<cr> | ||
nnoremap rmf :goto $MUSIC_DIR<cr>i:FZFfind<cr> | nnoremap rmf :goto $MUSIC_DIR<cr>i:FZFfind<cr> | ||
nnoremap rms :Playfind<cr> | nnoremap rms :Playfind<cr> | ||
Line 43: | Line 45: | ||
nnoremap rmv :let $IGNORE = system('mpc prev')<cr>:ShowSong<cr> | nnoremap rmv :let $IGNORE = system('mpc prev')<cr>:ShowSong<cr> | ||
nnoremap rmr :let $IGNORE = system('mpc seek 0%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 1<cr> | nnoremap rmr :let $IGNORE = system('mpc seek 0%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 1<cr> | ||
+ | nnoremap rm0 :let $IGNORE = system('mpc seek 0%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm1 :let $IGNORE = system('mpc seek 10%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm2 :let $IGNORE = system('mpc seek 20%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm3 :let $IGNORE = system('mpc seek 30%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm4 :let $IGNORE = system('mpc seek 40%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm5 :let $IGNORE = system('mpc seek 50%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm6 :let $IGNORE = system('mpc seek 60%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm7 :let $IGNORE = system('mpc seek 70%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm8 :let $IGNORE = system('mpc seek 80%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
+ | nnoremap rm9 :let $IGNORE = system('mpc seek 90%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr> | ||
nnoremap rmR :let $IGNORE = system('mpc stop')<cr>:!mpc play 1 %i<cr> | nnoremap rmR :let $IGNORE = system('mpc stop')<cr>:!mpc play 1 %i<cr> | ||
nnoremap rmx :let $IGNORE = system('mpc random')<cr>:echo system('mpc status "Random is %random%"')<cr> | nnoremap rmx :let $IGNORE = system('mpc random')<cr>:echo system('mpc status "Random is %random%"')<cr> | ||
Line 56: | Line 68: | ||
command! PlayListfind :exe '!mpc load "'.system('mpc lsplaylist | fzf --height 40 2>/dev/tty').'"' | redraw | command! PlayListfind :exe '!mpc load "'.system('mpc lsplaylist | fzf --height 40 2>/dev/tty').'"' | redraw | ||
command Delfind :exe '!mpc del "'.system('mpc playlist | nl | fzf --height 40 --with-nth 2.. 2>/dev/tty | cut -f 1 | tr -d " "').'" &' | redraw | command Delfind :exe '!mpc del "'.system('mpc playlist | nl | fzf --height 40 --with-nth 2.. 2>/dev/tty | cut -f 1 | tr -d " "').'" &' | redraw | ||
+ | command Delcurrent mpc del $(mpc status %%songpos%%) %i | ||
command ShowSong mpc -f "$SONG_FORMAT" current %S | command ShowSong mpc -f "$SONG_FORMAT" current %S | ||
command GotoSong :exe 'goto "$MUSIC_DIR/'.system('mpc -f "%%file%%" | sed -ne "1p" --').'"' | command GotoSong :exe 'goto "$MUSIC_DIR/'.system('mpc -f "%%file%%" | sed -ne "1p" --').'"' | ||
− | command mpcadd :let $IGNORE = system(expand('mpc search filename "$(realpath --relative-to=$MUSIC_DIR %%f)" | mpc add')) | + | command mpcinsert :let $IGNORE = system(expand('realpath -s --relative-to=$MUSIC_DIR %%f | mpc insert')) |
+ | command mpcadd :let $IGNORE = system(expand('mpc search filename "$(realpath -s --relative-to=$MUSIC_DIR %%f)" | mpc add')) | ||
command pls mpc save %a | echo "Playlist saved." %i | command pls mpc save %a | echo "Playlist saved." %i | ||
command pll mpc load %a %i | command pll mpc load %a %i | ||
command mpcStat :echo system('mpc | sed -ne '.%a.'p --') | command mpcStat :echo system('mpc | sed -ne '.%a.'p --') | ||
command mpcls mpc playlist | sed -e "s%%$(mpc | sed -ne '1p')%%& *%%" -- %M | command mpcls mpc playlist | sed -e "s%%$(mpc | sed -ne '1p')%%& *%%" -- %M | ||
+ | command mpcStatus mpc status "vol:%%volume%% rep %%repeat%% rand %%random%% single %%single%%" %S | ||
command mpcEdit mpc_edit.py %s | command mpcEdit mpc_edit.py %s | ||
command mpcplay :if system('mpc | sed -ne 2p -- | cut -d " " -f 1') == '' | execute '!mpc toggle &' | else | execute '!mpc next &' | endif | command mpcplay :if system('mpc | sed -ne 2p -- | cut -d " " -f 1') == '' | execute '!mpc toggle &' | else | execute '!mpc next &' | endif | ||
" }}}2 | " }}}2 | ||
" }}}1 | " }}}1 | ||
− | </ | + | </syntaxhighlight> |
== Playlist Editor Script == | == Playlist Editor Script == | ||
Line 73: | Line 88: | ||
Copy and paste the following into your <code>$VIFM/scripts</code> folder or somewhere in your <code>$PATH</code> as <code>mpc_edit.py</code>: | Copy and paste the following into your <code>$VIFM/scripts</code> folder or somewhere in your <code>$PATH</code> as <code>mpc_edit.py</code>: | ||
− | < | + | <syntaxhighlight lang="python"> |
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||
Line 116: | Line 131: | ||
else: | else: | ||
client.seek(new_pos, elapsed-setback if elapsed>setback else 0) | client.seek(new_pos, elapsed-setback if elapsed>setback else 0) | ||
− | </ | + | </syntaxhighlight> |
This allows you to edit the current playlist by tying <code>rmE</code> if you have the optional dependencies installed. | This allows you to edit the current playlist by tying <code>rmE</code> if you have the optional dependencies installed. | ||
+ | |||
+ | What's nice about it is that if the new, edited playlist contains the same song you were just listening to, then it will immediately jump to were you left off and continue playing. | ||
A video showcasing most of the features is [https://youtu.be/6JNZKT7VgIg here]. | A video showcasing most of the features is [https://youtu.be/6JNZKT7VgIg here]. |
Revision as of 11:59, 31 August 2021
If you have mpc then with some scripting you can use Vifm as your music player!
Requirements and Reccomendations
- The most recent version of mpc, preferably compiled from github.
- fzf: Fuzzy search finder that makes life easier.
- Python 3 with the python-mpd2 package installed. (OPTIONAL)
You can use older versions of mpc and still get 99% of the functionality, but certain mappings will have to be adjusted for displaying the current status. The python dependency is only for if you want to sort or edit your playlist with a terminal-based text editor on-the-fly.
Vifm mappings and Commands
Simply copy and paste this into your vifmrc:
NOTE Make sure that you set the shell variables to their appropriate locations on the harddrive. |
" {{{1 MUSIC PLAYER
let $SONG_FORMAT="[[%artist% - ]%title%]|[%file%]"
let $MUSIC_DIR=expand("$HOME/music")
let $PLAY_LIST=expand("$HOME/music/play_list")
" {{{2 MAPPINGS
nnoremap L :!mpc seek +5%% %i<cr>:mpcStat 2<cr>
nnoremap B :!mpc seek -5%% %i<cr>:mpcStat 2<cr>
nnoremap l :!mpc seek +5 %i<cr>:mpcStat 2<cr>
nnoremap b :!mpc seek -5 %i<cr>:mpcStat 2<cr>
nnoremap rmp :!mpc toggle %i<cr>:mpcStat 2<cr>
nnoremap rmw :ShowSong<cr>
nnoremap rmg :GotoSong<cr>
nnoremap rmt :mpcStat 2<cr>
nnoremap rm0 :let $IGNORE = system('mpd_restart')<cr>:echo 'Music player daemon has been restarted'<cr>
nnoremap rmi :mpcinsert<cr>:!echo Song %f:t inserted. %S<cr>
nnoremap rma :mpcadd<cr>:!echo Song %f:t added. %S<cr>
nnoremap rmA :mpcadd<cr>:!mpc play $(mpc playlist | wc -l) %i<cr>
nnoremap rmm :!echo "%f" | sed -e 's/\([^\]\) /\1\n/g' -e 's/\\//g' | xargs -d '\n' -L 1 realpath -s --relative-to=$MUSIC_DIR %M | sort -nr | xargs -d '\n' -L 1 mpc insert<cr>:mpcplay<cr>:ShowSong<cr>
nnoremap rmd :Delfind<cr>
nnoremap rmD :Delcurrent<cr>:ShowSong<cr>
nnoremap rmf :goto $MUSIC_DIR<cr>i:FZFfind<cr>
nnoremap rms :Playfind<cr>
nnoremap rmc :!mpc crop %i<cr>:echo 'Playlist cropped'<cr>
nnoremap rme :!mpc clear %i<cr>:echo 'Playlist cleared'<cr>
nnoremap rmE :mpcEdit<cr>
nnoremap rmn :let $IGNORE = system('mpc next')<cr>:ShowSong<cr>
nnoremap rmv :let $IGNORE = system('mpc prev')<cr>:ShowSong<cr>
nnoremap rmr :let $IGNORE = system('mpc seek 0%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 1<cr>
nnoremap rm0 :let $IGNORE = system('mpc seek 0%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm1 :let $IGNORE = system('mpc seek 10%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm2 :let $IGNORE = system('mpc seek 20%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm3 :let $IGNORE = system('mpc seek 30%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm4 :let $IGNORE = system('mpc seek 40%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm5 :let $IGNORE = system('mpc seek 50%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm6 :let $IGNORE = system('mpc seek 60%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm7 :let $IGNORE = system('mpc seek 70%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm8 :let $IGNORE = system('mpc seek 80%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rm9 :let $IGNORE = system('mpc seek 90%')<cr>:let $IGNORE = system('mpc play')<cr>:mpcStat 2<cr>
nnoremap rmR :let $IGNORE = system('mpc stop')<cr>:!mpc play 1 %i<cr>
nnoremap rmx :let $IGNORE = system('mpc random')<cr>:echo system('mpc status "Random is %random%"')<cr>
nnoremap rml :let $IGNORE = system('mpc repeat')<cr>:echo system('mpc status "Repeat is %repeat%"')<cr>
nnoremap rmS :let $IGNORE = system('mpc single')<cr>:echo system('mpc status "Single is %single%"')<cr>
nnoremap rmh :!mpc shuffle %i<cr>:echo 'Playlist shuffled'<cr>
nnoremap rmL :PlayListfind<cr>:!sleep 0.2 %i<cr>:Playfind<cr>
nnoremap + :!mpc volume +5 %i<cr>:echo system('mpc status "Volume is:%volume%"')<cr>
nnoremap - :!mpc volume -5 %i<cr>:echo system('mpc status "Volume is:%volume%"')<cr>
" }}}2
" {{{2 COMMANDS
command! Playfind :exe '!mpc play "'.system('mpc playlist | nl | grep -Fv "$(mpc | sed -ne "1p" --)" | fzf --height 40 --with-nth 2.. 2>/dev/tty | cut -f 1 | tr -d " "').'" &>/dev/null %IU' | redraw
command! PlayListfind :exe '!mpc load "'.system('mpc lsplaylist | fzf --height 40 2>/dev/tty').'"' | redraw
command Delfind :exe '!mpc del "'.system('mpc playlist | nl | fzf --height 40 --with-nth 2.. 2>/dev/tty | cut -f 1 | tr -d " "').'" &' | redraw
command Delcurrent mpc del $(mpc status %%songpos%%) %i
command ShowSong mpc -f "$SONG_FORMAT" current %S
command GotoSong :exe 'goto "$MUSIC_DIR/'.system('mpc -f "%%file%%" | sed -ne "1p" --').'"'
command mpcinsert :let $IGNORE = system(expand('realpath -s --relative-to=$MUSIC_DIR %%f | mpc insert'))
command mpcadd :let $IGNORE = system(expand('mpc search filename "$(realpath -s --relative-to=$MUSIC_DIR %%f)" | mpc add'))
command pls mpc save %a | echo "Playlist saved." %i
command pll mpc load %a %i
command mpcStat :echo system('mpc | sed -ne '.%a.'p --')
command mpcls mpc playlist | sed -e "s%%$(mpc | sed -ne '1p')%%& *%%" -- %M
command mpcStatus mpc status "vol:%%volume%% rep %%repeat%% rand %%random%% single %%single%%" %S
command mpcEdit mpc_edit.py %s
command mpcplay :if system('mpc | sed -ne 2p -- | cut -d " " -f 1') == '' | execute '!mpc toggle &' | else | execute '!mpc next &' | endif
" }}}2
" }}}1
Playlist Editor Script
Copy and paste the following into your $VIFM/scripts
folder or somewhere in your $PATH
as mpc_edit.py
:
#!/usr/bin/env python3
import os
import tempfile
from mpd import MPDClient
# Options
editor = os.environ['EDITOR']
# Amount (in seconds) to rewind when reloading the playlist
setback = 4
# Startup
client = MPDClient()
client.connect("localhost", 6600)
with tempfile.NamedTemporaryFile('w+') as tmpf:
tmpf.writelines((song['file']+'\n' for song in client.playlistid()))
tmpf.seek(0)
old_playlist = [song.strip() for song in tmpf.readlines()]
# Ensure that the file has been written to disk
tmpf.flush()
os.system("{} {}".format(editor, tmpf.name))
tmpf.seek(0)
new_playlist = [song.strip() for song in tmpf.readlines()]
if new_playlist != old_playlist:
# Save the status right before we change things:
current_song = client.currentsong()['file']
elapsed = float(client.status()['elapsed'])
client.clear()
for song in new_playlist:
client.add(song)
# Check if the song we were listing to is in the new playlist
try:
new_pos = [song['file'] for song in
client.playlistid()].index(current_song)
except ValueError:
pass
else:
client.seek(new_pos, elapsed-setback if elapsed>setback else 0)
This allows you to edit the current playlist by tying rmE
if you have the optional dependencies installed.
What's nice about it is that if the new, edited playlist contains the same song you were just listening to, then it will immediately jump to were you left off and continue playing.
A video showcasing most of the features is here.