Linux-Skript zum Zusammenstellen von Mixed-Musik-CDs

Eine ganze CD zu Hause für das Auto zu kopieren, ist leicht.

Wenn man aber eine CD aus einer zufälligen Auswahl von Songs seiner Festplatte zusammenstellen will, ist man ziemlich aufgeschmissen – Unterstützung seitens Software wie Rythmbox, Brasero o.ä. gibt es dafür leider nicht.

Darum hab ich ein Skript erstellt, welches genau das erledigt, oder besser gesagt, vorbereitet. Es liest alle MP3-Dateien im Verzeichnis „\home\user\Musik“ in eine Tabelle ein und mischt diese kräftig durch. Danach wird ein Verzeichnis („shufflecd.jjjjmmtt-hhmmss“) angelegt, in die so viele Titel kopiert werden, wie auf eine CD passen. Standardmäßig verwende ich 700MB-CDs, der entsprechende Wert kann leicht eingestellt werden.

Dieser Vorgang dauert auf meinem vier Jahre altem Thinkpad weniger als eine Minute.

Ich hatte in meinem Musik-Verzeichnis auch Hörbücher und ähnliches gespeichert. Wer das üblicherweise ebenso hält, sollte die entsprechenden Unterverzeichnisse zumindest bis nach dem Brennen in einen anderen („\home\user\Musi“) verschieben, das ist eine Sache von Sekunden. Auch wenn man z.B. auf den neuen Mix-CDs etwa keine Klassik möchte – einfach schnell verschieben.

Meistens brenne ich gleich drei-vier CD nacheinander – während Brasero die erste CD brennt, laufen schon die nächsten shuffle-Durchgänge.

Leider verweigert WordPress mir das Ablegen des Skripts für den Download („Tut mir leid, aber aus Sicherheitsgründen ist dieser Dateityp nicht erlaubt.“), also müsst Ihr wohl selbst eine leere Datei anlegen.

Edit 19.4.: „shuf“ erledigt das shuffeln automatisch (bei „find“ eingebaut), entsprechend ist der Block „Mischen“ weggefallen.

 

Auf gehts:

#!/bin/bash
#./shufflecd
#

#Erstmal das akutelle Verzeichnis sichern
aktP=${PWD}

#auf Home\User gehen
cd ~

# Kleines Format 650MB-CD
#  682000000
# Standardgröße 700MB-CD
#  735000000 hat noch Luft nach oben, aber 
#  737280000 war in 2 von 8 Fällen zu groß
#  und ergab unvollständig gebrannte CDs
GG=735000000

#Standardzielverzeichnis anlegen
Verz="shufflecd.$(date +%Y%m%d-%H%M%S)"
#echo ${Verz}
mkdir ${Verz}

#Standardquellverzeichnis für die Suche ist ~/Musik
cd ~/Musik

#alle Unterordner-mp3s gemischt (geSHUFfelt) ausgeben
find . -name "*.mp3" | shuf --output=shuffle.txt

#Datei in ein Array ausgeben
IFS=$'\n\t' Songs=( $(cat shuffle.txt) )
IFS=$'\n\t' Zufal=( $(cat shuffle.txt) )
IFS=$'\n\t' Groes=( $(cat shuffle.txt) )
unset IFS

#ganzes Array ausgeben ohne Umbrüche
#echo ${Songs[*]}

#Anzahl Elemente ermitteln
Anzahl=${#Songs[*]}
#echo ${Anzahl}

#Liste ausgeben
#for ((i=0;$i<${Anzahl};i++)); do
#  echo ${Songs[$i]};
#done

#Dateigroessen ermitteln
for ((i=0;$i<${Anzahl};i++)); do
   Dire=($(ls -lg "${Songs[$i]}"))
   #echo ${Dire[3]}
   G=${Dire[3]}
   Groes[$i]=$(((1+G/32768)*32768));
done
#Groessenliste ausgeben
#for ((i=0;$i<${Anzahl};i++)); do
#  echo ${Groes[$i]}; 
#done

i=0
summe=0
#echo ${GG}
until ((${summe}>${GG})); do
   #kopieren
   #echo "${Songs[$i]}"
   #echo "../${Verz}"
   cp "${Songs[$i]}" "../${Verz}"
   #verbrauchten Speicher summieren
   summe=$((summe+${Groes[$i]}))
   #echo "${Groes[$i]}" - "${summe}" - "${Songs[$i]}"
   i=$((i+1));
done

i=$((i-1))
#Letzter Song passt leider nicht  / löschen
rm "../${Verz}/${Songs[$i]##*/}"

#wieder auf's alte Verzeichnis
cd ${aktP}

#endlich

echo Fertig.
00

Veröffentlicht von Dirk Haar

Unternehmensberater, branchenübergreifend in der Großrechnerwelt tätig. Geboren 1964 in Wilhelmshaven, wohnhaft in Wilhelmshaven, verheiratet, eine Tochter. Mehr ist unter https://www.xing.com/profile/Dirk_Haar zu finden.

Beteilige dich an der Unterhaltung

2 Kommentare

  1. Hallo Dirk,

    vielen Dank für das tolle Skript! War genau das, was ich gesucht habe (Stichwort: Auto-CD :-)).
    Habe mir aber die Freiheit genommen, das Skript noch etwas zu ergänzen:
    – Man kann nun, entweder als Parameter oder in einem Dialog, den Namen des Unterzeichnisses angeben, das man als Quellverzeichnis nehmen möchte.
    – Basisverzeichnis ist immer das Verzeichnis, in dem das Skript liegt.
    – Der Name des neuen Zielverzeichnisses setzt sich aus dem Quellverzeichnis plus „shuffle_usw..“ zusammen.
    – Der Dateiname bekommt die laufende Nummer verpasst, aber zuerst wird er noch um führende Zahlen (mit Trennzeichen “ – “ oder „. „) gekürzt.

    Linux ist echt Klasse für solche nützlichen kleinen Programme !

    Viele Grüße
    Ralph

    Und hier nun mein Skript:
    #!/bin/bash
    #./shufflecd
    #

    # aktuelles Verzeichnis des Skripts ermitteln und CD dorthin
    SKRIPT=`realpath -s „$0″`
    PROGDIR=`dirname „$SKRIPT“`
    cd „$PROGDIR“

    # Kleines Format 650MB-CD
    # 682000000
    # Standardgröße 700MB-CD
    # 735000000 hat noch Luft nach oben, aber
    # 737280000 war in 2 von 8 Fällen zu groß
    # und ergab unvollständig gebrannte CDs
    GG=735000000

    if [ „$1“ == „“ ]; then
    ERGEBNIS=$(/usr/bin/yad –title=“CD-Shuffle“ –width=500 –mouse –dialog-sep –separator=“^“ –form \
    –field=“Name Quellverzeichnis:“ )
    UVERZ=$(echo $ERGEBNIS | cut -d’^‘ -f1 )
    else
    UVERZ=$1
    fi

    if [ „$UVERZ“ == „“ ]; then
    exit
    fi

    cd „$PROGDIR/$UVERZ“ 2>/dev/null

    if [ $? -ne 0 ]; then
    echo „Verzeichnis \“$PROGDIR/$UVERZ\“ nicht gefunden !“
    exit
    fi

    ZIELVERZ=“${UVERZ}_shuffle.$(date +%Y%m%d-%H%M%S)“

    # Zielverzeichnis anlegen
    mkdir „$PROGDIR/$ZIELVERZ“

    #alle Unterordner-mp3s gemischt (geSHUFfelt) ausgeben
    find . -name „*.mp3“ | shuf –output=shuffle.txt

    #Datei in ein Array ausgeben
    IFS=$’\n\t‘ Songs=( $(cat shuffle.txt) )
    IFS=$’\n\t‘ Zufal=( $(cat shuffle.txt) )
    IFS=$’\n\t‘ Groes=( $(cat shuffle.txt) )

    # das „./“ vor den Dateinamen löschen
    sed -i „s/\.\///g“ shuffle.txt
    # führende Ziffern löschen
    sed -i „s/[0-9][0-9]* – //g“ shuffle.txt
    sed -i „s/[0-9][0-9]*\. //g“ shuffle.txt

    IFS=$’\n\t‘ SongsNeu=( $(cat shuffle.txt) )
    unset IFS

    #ganzes Array ausgeben ohne Umbrüche
    #echo ${Songs[*]}

    #Anzahl Elemente ermitteln
    Anzahl=${#Songs[*]}
    #echo ${Anzahl}

    #Liste ausgeben
    #for ((i=0;$i<${Anzahl};i++)); do
    # echo ${Songs[$i]};
    #done

    #Dateigroessen ermitteln
    for ((i=0;$i<${Anzahl};i++)); do
    Dire=($(ls -lg "${Songs[$i]}"))
    #echo ${Dire[3]}
    G=${Dire[3]}
    Groes[$i]=$(((1+G/32768)*32768));
    done
    #Groessenliste ausgeben
    #for ((i=0;$i${GG})) || (($i>=${Anzahl})); do
    #kopieren
    #echo „$i – ${Anzahl}“ – „${Songs[$i]}“
    #echo „../${ZIELVERZ}“

    ZAHL=$((i+1))
    ZAHL=$(printf „%0*d“ 3 $ZAHL)
    NEUERTITEL=“$ZAHL – ${SongsNeu[$i]}“
    cp „${Songs[$i]}“ „../$ZIELVERZ/$NEUERTITEL“

    #verbrauchten Speicher summieren
    summe=$((summe+${Groes[$i]}))

    # echo „${Groes[$i]}“ – „${summe}“ – „$NEUERTITEL“
    i=$((i+1));
    done

    if (($i>${Anzahl})); then
    i=$((i-1))
    #Letzter Song passt leider nicht / löschen
    echo „Löschen: ../$ZIELVERZ/$NEUERTITEL“
    rm „../$ZIELVERZ/$NEUERTITEL“
    fi
    echo Fertig.

  2. Hallo Dirk,

    mir ist eben hoch die Idee gekommen, dass es doch praktisch wäre, wenn immer CD-Mischungen von allen verfügbaren Songs generiert werden würden. Daher habe ich am Schluss noch eine weiter Schleife drangehängt, so dass solange neue Mixverzeichnisse erstellt werden, bis alle Songs aufgeteilt wurden.

    Nochmals viele Grüße und Danke für die tolle Vorarbeit !

    Ralph

    #!/bin/bash
    #./shufflecd

    # aktuelles Verzeichnis des Skripts ermitteln und CD dorthin
    SKRIPT=`realpath -s „$0″`
    PROGDIR=`dirname „$SKRIPT“`
    cd „$PROGDIR“

    # Kleines Format 650MB-CD
    # 682000000
    # Standardgröße 700MB-CD
    # 735000000 hat noch Luft nach oben, aber
    # 737280000 war in 2 von 8 Fällen zu groß
    # und ergab unvollständig gebrannte CDs
    GG=735000000

    if [ „$1“ == „“ ]; then
    ERGEBNIS=$(/usr/bin/yad –title=“CD-Shuffle“ –width=500 –mouse –dialog-sep –separator=“^“ –form \
    –field=“Name Quellverzeichnis:“ )
    UVERZ=$(echo $ERGEBNIS | cut -d’^‘ -f1 )
    else
    UVERZ=$1
    fi

    if [ „$UVERZ“ == „“ ]; then
    exit
    fi

    cd „$PROGDIR/$UVERZ“ 2>/dev/null

    if [ $? -ne 0 ]; then
    echo „Verzeichnis \“$PROGDIR/$UVERZ\“ nicht gefunden !“
    exit
    fi

    #alle Unterordner-mp3s gemischt (geSHUFfelt) ausgeben
    find . -name „*.mp3“ | shuf –output=shuffle.txt

    #Datei in ein Array ausgeben
    IFS=$’\n\t‘ Songs=( $(cat shuffle.txt) )
    IFS=$’\n\t‘ Zufal=( $(cat shuffle.txt) )
    IFS=$’\n\t‘ Groes=( $(cat shuffle.txt) )

    # das „./“ vor den Dateinamen löschen
    sed -i „s/\.\///g“ shuffle.txt
    # führende Ziffern löschen
    sed -i „s/[0-9][0-9]* – //g“ shuffle.txt
    sed -i „s/[0-9][0-9]*\. //g“ shuffle.txt

    IFS=$’\n\t‘ SongsNeu=( $(cat shuffle.txt) )
    unset IFS

    #ganzes Array ausgeben ohne Umbrüche
    #echo ${Songs[*]}

    #Anzahl Elemente ermitteln
    Anzahl=${#Songs[*]}
    echo „Anzahl Titel: ${Anzahl}“

    #Liste ausgeben
    #for ((i=0;$i<${Anzahl};i++)); do
    # echo ${Songs[$i]};
    #done

    #Dateigroessen ermitteln
    for ((i=0;$i<${Anzahl};i++)); do
    Dire=($(ls -lg "${Songs[$i]}"))
    #echo ${Dire[3]}
    G=${Dire[3]}
    Groes[$i]=$(((1+G/32768)*32768));
    done
    #Groessenliste ausgeben
    #for ((i=0;$i=${Anzahl})); do
    VERZNR=$((VERZNR+1));
    ZIELVERZ=“$ZIELVERZBASIS-$VERZNR“

    # Zielverzeichnis anlegen
    mkdir „$PROGDIR/$ZIELVERZ“

    summe=0
    #echo ${GG}
    until ((${summe}>${GG})) || (($i>=${Anzahl})); do
    #kopieren
    echo „$i – ${Anzahl}“ – „${Songs[$i]}“
    #echo „../${ZIELVERZ}“

    ZAHL=$((i+1))
    ZAHL=$(printf „%0*d“ 3 $ZAHL)
    NEUERTITEL=“$ZAHL – ${SongsNeu[$i]}“
    # echo „$NEUERTITEL“
    cp „${Songs[$i]}“ „../$ZIELVERZ/$NEUERTITEL“

    #verbrauchten Speicher summieren
    summe=$((summe+${Groes[$i]}))

    # echo „${Groes[$i]}“ – „${summe}“ – „$NEUERTITEL“
    i=$((i+1));
    done

    if ((${summe}>${GG})); then
    i=$((i-1))
    #Letzter Song passt leider nicht / löschen
    echo „Löschen: ../$ZIELVERZ/$NEUERTITEL“
    rm „../$ZIELVERZ/$NEUERTITEL“
    fi
    done

    rm shuffle.txt

    echo „Anzahl gemischter CDs: $VERZNR“
    echo Fertig.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.