Playlist MTP Sync

18.07.2016 12:39 | keine Kommentare

Eigentlich benutze ich mobil immer Spotify. In der letzten Zeit fällt mir aber auf, dass ich es eben kaum noch nutze bzw. die Käufe von bandcamp nicht bei Spotify verfügbar sind. Aus diesem Grund brauchte ich ein kleines Script, dass Musikdateien mit meinem Smartphone synchronisiert und das möglichst unkompliziert.

Auf mobilen Geräten gibt es aber meist ein Problem: Speicherplatz. Außerdem möchte ich eine möglichst große Vielfalt an Musik mit diesem Platzproblem. Die einfachste Lösung ist also die Synchronisierung von Playlists und nicht von ganzen Alben/Ordnern. Playlists können bequem am PC erstellt werden und das Script fragt nach einer Auswahl der zu synchronisierenden Playlists. Pfade müssen ggf. angepasst werden. Benötigt wird außerdem fzf, gvfs-mtp und natürlich rsync. Hier das Script:

#!/usr/bin/env bash

DEVICE_MUSIC_ROOT="Interner Speicher/Music" # Where the music will live on your phone, without slash

MUSIC_ROOT="${HOME}/Musik"          # music lib
MUSIC_PLAYLIST_ROOT="${HOME}/Musik/Playlists"   # playlist folder
SYNC_MUSIC_ROOT="${HOME}/Downloads/mpd_sync"    # Staging folder (receives all files prior to sync)
SYNC_PLAYLIST_ROOT="${SYNC_MUSIC_ROOT}/playlists"   # Where to place playlist files (m3u) for sync
SYNC_DELETE_AFTER=true

# Output stuff to stdout if $DEBUG evaluates to anything
# $ DEBUG=1 ./script.sh
function debug()
{
    [[ ! -z "$DEBUG" ]] && echo $*
}

# check dependencies
function checkDependencies()
{
    type rsync >/dev/null 2>&1 || { echo >&2 "Require rsync but it's not installed.  Aborting."; exit 1; }
    type fzf >/dev/null 2>&1 || { echo >&2 "Require fzf but it's not installed.  Aborting."; exit 1; }
    type gvfs-mount >/dev/null 2>&1 || { echo >&2 "Require gvfs-mount (for MTP) but it's not installed.  Aborting."; exit 1; }
}

# Sync stuff with phone over rsync
function sync() 
{
    list_usb="$(lsusb | fzf --reverse)"

    read -r -a info <<< "$list_usb"

    if [ -z "$list_usb" ]; then
        echo "No device selected. Aborting.";
        exit 1;
    fi

    bus="${info[1]}"
    device="${info[3]::-1}"

    DEVICE_MOUNT="/run/user/${UID}/gvfs/mtp:host=%5Busb%3A${bus}%2C${device}%5D/${DEVICE_MUSIC_ROOT}"

    confirm "Syncing to ${DEVICE_MOUNT}" && doSync
}

function doSync()
{
    echo "Syncing now ...";

    if [ "$SYNC_DELETE_AFTER" == true ]; then
        echo "Old files will be deleted on device.";
        rsync -vzrL --delete-after --no-perms --no-t "${SYNC_MUSIC_ROOT}"/ "${DEVICE_MOUNT}"/       
    else
        rsync -vzrL --no-perms --no-t "${SYNC_MUSIC_ROOT}"/ "${DEVICE_MOUNT}"/
    fi

    echo "Finished syncing!";
}

# Ask for confirmation on something
function confirm()
{
    echo -n "$@ [y/N] "
    read answer
    for response in y Y yes YES Yes Sure sure SURE OK ok Ok kk; do
    [[ "_$answer" == "_$response" ]] && return 0
    done

    return 1
}

# MAIN
echo "Syncing only works with MTP.";
checkDependencies

echo "";

echo "Music root: " ${MUSIC_ROOT};
echo "Playlists root: " ${MUSIC_PLAYLIST_ROOT};
echo "Temporary staging root: " ${SYNC_MUSIC_ROOT};

[[ ! -d "$SYNC_PLAYLIST_ROOT" ]] && mkdir -p "$SYNC_PLAYLIST_ROOT"

PLAYLISTS=$(ls --color=never ${MUSIC_PLAYLIST_ROOT}/*.m3u | fzf -m --reverse)
read -r -a info <<< "$PLAYLISTS"

if [ -z "$PLAYLISTS" ]; then
    echo "No playlist selected. Aborting.";
    exit 1;
fi

echo "${PLAYLISTS}" | while read pl; do 
##for pl in ${MUSIC_PLAYLIST_ROOT}/*.m3u; do
    plname="$(basename "${pl}")"
    plname="${plname%%.*}"
    echo "Linking playlist: " ${plname}
    plfolder="${SYNC_MUSIC_ROOT}/${plname}"
    plfile="${SYNC_PLAYLIST_ROOT}/${plname}.m3u"

    [[ -f "$plfile" ]] && rm -f "$plfile"
    [[ -d "$plfolder" ]] && rm -rf "$plfolder"
    [[ ! -d  "$plfolder" ]] && mkdir -p "$plfolder" && touch "$plfile"

    while read line; do
    f="${MUSIC_ROOT}/${line}"
    bn=$(basename "$f")

    if [[ -f "$f" && ! -f "${plfolder}/${bn}" ]]; then
        ln -s "$f" "$plfolder"
        echo "${DEVICE_MUSIC_ROOT}/${plname}/${bn}" >> "$plfile"
    fi

    done < "$pl"
done

echo "";
confirm "Would you like to sync with your MTP device?" && sync

Kommentare

Keine Daten vorhanden.

Mit dem Absenden des Formulars akzeptiere ich die Datenschutzbestimmungen dieses Dienstes.