Migration to Linux: Music

From Wurst-Wasser.net
Jump to navigation Jump to search

You are here: /Migrating from macOS to Linux/Migration to Linux: Music


🚧 This article might contain false clues - read carefully. And yes, I could have edited my failures out, but I believe it's also nice to know what doesn't work. :-)

Player

iTunes was great, Music suckt. I was looking for a most iTunes-like App.

Lollypop

Nice clean interface, even has EQ. No Album list as of now. That's stupid.

Strawberry

Look is a bit oldschool, works as expected.

Audacious

Strange interface, looks like WinAmp or SoundApp in the 90s.

Clementine

Nice, but missing a column view and easier Playlist/Smart playlist handling.

Rhythmbox

I ended up using this. Interface is iTunes like, does simple and smart playlists. No stupid Icons or unnessary eye-candy.

Equalizer

Rhythmbox box's equalizer plugin won't work, the project seems abandoned. I ended up using EasyEffects which does the job nicely and is available in the OpenSUSE repo. Also it does work globally, so your presets will work with any player. \o/

DJing

💡 If re-indexing your Library takes hours...remove all non-music files from the library!

I grew quite fond if djay on iOS
since syncing music with iOS is no longer (easily) possible, I found Mixxx, which is available via Flatpak.

Importing CDs

🚧 Not sure, whats working best!
  • Sound Juicer is easy to use and works fine (sometimes needs to mount CDs in Dolphin first, don't understand why)
  • SoundConverter needs Sound Juicer to import CDs

  • EasyTAG is great for tagging already ripped CDs


Music export and import

Just copy the "iTunes Music" folder from your Mac to Linux. If necessary, add the folder in the new player's settings. If you have maaaaany music files: Wait really patiently. Your music will show up! Progress bar is usually at the bottom of the window.

Playlist export and import

🚧 Important: Mind the umlauts and other special characters in filenames! And if your target filesystem is case-sensitive...

Try #1: Export as m3u

https://www.wikihow.com/Export-an-iTunes-Playlist

Nice idea, but Achtern DĂŒnen und Diek.m3u contains this::

#EXTM3U
#EXTINF:149,Fröhjahr op den Diek - Knut Kiesewetter
/Volumes/Daten HD (Portable Samsung 2TB)/Users/heiko/Music/iTunes/iTunes Music/Knut Kiesewetter/Wo bĂŒst du ween/08 Fröhjahr op den Diek.m4a
#EXTINF:148,Giff uns noch een ut de Buddel - Butendieks
/Volumes/Daten HD (Portable Samsung 2TB)/Users/heiko/Music/iTunes/iTunes Music/Butendieks/Giff uns noch een ut de Buddel/01 Giff uns noch een ut de Buddel.m4a

Absolute paths! \o/ Awesome!

M3U8, TXT and XML also have absolute paths. XML adds more metdata. Saving location (on same disk, same folder) doesn't make a difference, paths are always absolute.

Idea #1: Rewrite paths?

If I export all this playlists with absolute paths, why can't I use a shell script to change the prefix of the path?

Test with Audacious and Lollypop: Audacious exports M3U8 with relative paths, Lollypop reads it and works! Therefore: Writing a script to remove path prefix will work!

Idea #2: Create symlink to actual location?

Why not? You can still work on the playlists later, and this keeps you compatible with your former player/system.

Solution #1: Rewriting paths with Kate

Actually, that didn't work out. :-( It seems that this only works in the primary Music-folder. Might be wrong.

Solution #1, again: Retry rewriting by script(s)

It seems that all music files are just references by Lollypop. Playlist files, however, seem to get copied to Lollypop database (~/.local/share/lollypop/playlists.db) and are ignored afterwards. Since Lollypop lacks a feature for deleting all playlists at once, just delete the db-file. :) On next launch Lollypop will re-import all playlist files found in the configured music-folders.

Main Script

ConvertITunesPlaylistsForLollypop.sh
#!/bin/bash
#set -x
#
# Script: ConvertITunesPlaylistsForLollypop.sh
# Purpose: Open the iTunes/Music exported .m3u8s and change the path of the music files. 
# Author: Heiko # More: https://www.wurst-wasser.net/nextcloud/index.php/apps/collectives/Knowledge-Base/Linux/Linux%20Client%20(migrating%20from%20macOS)/Migration%20Plan/Music?fileId=135030

# Functions
FURLENCODESTRING()
{    
    echo -n "${1}" | urlencode.php | sed s/%2F/\\//\g
}

FESCAPESTRING()
{        
    # Prefix / with \ and " " with \, too
    echo "${1}" | sed s/\\//\\\\\\//\g | sed s/\\\ /\\\\\ /\g
}

FPROCESSPLAYLIST()
{
    LFILENAMEPLAYLIST="`basename \"${1}\"`"
    test -f "${GFOLDERPLAYLISTS}/${LFILENAMEPLAYLIST}" && rm "${GFOLDERPLAYLISTS}/${LFILENAMEPLAYLIST}"
    cat "${1}" | sed s/\\r/\\n/\g | grep -v ^# | while read LLINE; do
         LLINE2="`echo \"${LLINE}\" | str_replace.php \"${GFOLDERMUSICOLD}\" \"${GFOLDERMUSICNEW}\"`"          LLINENEW="${GFOLDERMUSICNEWPREFIX}`FURLENCODESTRING \"${LLINE2}\"`"
         echo "${LLINENEW}" >> "${GFOLDERPLAYLISTS}/${LFILENAMEPLAYLIST}"
done
}

# Globals
GFOLDERDRIVEROOT="/run/media/heiko/f595f49a-f483-4e65-9559-aef130f2a1a6" #TODO: Refactor this mess! GFOLDERITUNESPLAYLISTS="${GFOLDERDRIVEROOT}/Playlist_Export" GFOLDERDOCUMENTROOT="${GFOLDERDRIVEROOT}/Music" GFOLDERPLAYLISTS="${GFOLDERDOCUMENTROOT}/Playlists" GFOLDERMUSICNEW="${GFOLDERDOCUMENTROOT}/Music" GFOLDERMUSICOLD="/Volumes/Daten HD (Portable Samsung 2TB)/Users/heiko/Music/iTunes/iTunes Music" GFILEPLAYLISTSUFFIX="\.m3u8" GFOLDERMUSICNEWPREFIX="file://"

# Get the (relative) paths of playlists, f.e. "./Easy Listening.m3u8" find "${GFOLDERITUNESPLAYLISTS}" -type f -name \*${GFILEPLAYLISTSUFFIX} | while read LPLAYLIST; do
        echo "Processing \"${LPLAYLIST}\"..."
        FPROCESSPLAYLIST "${LPLAYLIST}"
#    exit 1 # deb
done 

# EOF

Helper scripts

Yes, you can do this with bash, sed, awk or whatever. But this seems much easier (at least for me).

str_replace.php
#!/usr/bin/php
<?php
if (count($argv)<3)
{        
    echo "Usage:\n";
    echo "echo \"foo bar\" | ./str_replace.php \" \" \"_\"\n";
    exit(1);
}

while($lLine = fgets(STDIN))
{
    echo(str_replace($argv[1], $argv[2], $lLine));
}

# EOF
?>
urlencode.php
#!/usr/bin/php
<?php
while($lLine = fgets(STDIN))
{
#       echo(urlencode($lLine));
        echo(rawurlencode($lLine));
}

# EOF
?>

Known issues

Umlaute und special characters are real PITA. If the playlist file doesn't work (if paths are not okay, Lollypop will ignore it completely), consider trying this:

testPlaylistsPaths.sh
#!/bin/bash
#set -x

find "/run/media/heiko/f595f49a-f483-4e65-9559-aef130f2a1a6/_NARF" -type f | while read LFILE; do
     testPlaylistPaths.sh "${LFILE}"
done
testPlaylistsPaths.sh
#!/bin/bash
#set -x

LFILE="${1}"

        echo "Processing basename \"${LFILE}\"..."
        cat "${LFILE}" | while read LPATH; do
                curl --silent "${LPATH}" > /dev/null
                if [ "${?}" -ne 0 ]; then
                        echo "Inaccessible: \"${LPATH}\""
                fi
        done
        echo ""

Try #2: Screw playlists and use tags

Find a Tag that's not in use, or just use the lyrics-field (like adding at the end a extra line with #PLAYLISTNAME#). Tag all files in playlist before importing in your new player. Then create smart playlist there searching for that tag.

🚧 This I still have to try this