hellmi666
Anmeldungsdatum: 30. August 2007
Beiträge: 238
Wohnort: Zwickau
|
Hallo Leute, ich habe einen Ordner zum Bearbeiten von meinen Musikdateien angelegt. Dort sind die Dateien wie folgt gespeichert: /Interpret/Jahr - Album/Interpret - Nummer Titel.mp3 Beispiel:
/Deep Purple/1970 - Deep Purple In Rock/Deep Purple - 01 Speed King.mp3 Nun habe ich ein Skript geschrieben, welches die in diesem Ordner liegenden Dateien neue Tags schreibt und auch durch mp3gain normalisiert.
So weit, so gut. Leider arbeitet das Skript sehr langsam. Kann mir der Eine oder die Andere ein paar Tipps geben, damit es schneller arbeitet?
Danke im Voraus. Hier das Skript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | #! /bin/bash
find ~/Multimedia/Musik/Arbeitsordner -type f -name '*.mp3' | sort -u | while read song
do
interpret=$(echo $song | cut -d'/' -f7)
album=$(echo $song | cut -d'/' -f8 | sed -e 's/[0-9][0-9][0-9][0-9][ ][-][ ]//g')
titel=$(echo $song | cut -d'/' -f9 | cut -d'-' -f2- | cut -d' ' -f3- | sed -e 's/.mp3//g')
nummer=$(echo $song | cut -d'/' -f9 | cut -d'-' -f2- | cut -d' ' -f2)
jahr=$(echo $song | cut -d'/' -f8 | cut -d' ' -f1)
eyeD3 --remove-all "$song"
id3v2 -y "$jahr" "$song"
eyeD3 -a "$interpret" "$song"
eyeD3 -A "$album" "$song"
eyeD3 -t "$titel" "$song"
eyeD3 -n "$nummer" "$song"
mp3gain -r -c "$song"
done
|
|
xuniL123
Anmeldungsdatum: 5. August 2012
Beiträge: 293
|
Du rufst im Script eyeD3 ziemlich oft auf. Kannst du die ganzen Parameter nicht auf einmal übergeben? Am längsten dürfte aber das Normalisieren dauern (mp3gain -r -c "$song" ?). Das lässt sich wohl kaum beschleunigen.
|
hellmi666
(Themenstarter)
Anmeldungsdatum: 30. August 2007
Beiträge: 238
Wohnort: Zwickau
|
xuniL123 schrieb: Du rufst im Script eyeD3 ziemlich oft auf. Kannst du die ganzen Parameter nicht auf einmal übergeben?
Weiß nicht, kann man das?
So, wie in dieser Art?
| eyeD3 -a "$interpret" "$song" -A "$album" "$song" -t "$titel" "$song" -n "$nummer" "$song"
|
Oder So?
| eyeD3 -a "$interpret" -A "$album" -t "$titel" -n "$nummer" "$song"
|
Werde beide Varianten mal probieren.
|
hellmi666
(Themenstarter)
Anmeldungsdatum: 30. August 2007
Beiträge: 238
Wohnort: Zwickau
|
Ok. Die zweite Variante funktioniert. So sieht es nun aus:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | #! /bin/bash
find ~/Multimedia/Musik/Arbeitsordner -type f -name '*.mp3' | sort -u | while read song
do
interpret=$(echo $song | cut -d'/' -f7)
album=$(echo $song | cut -d'/' -f8 | sed -e 's/[0-9][0-9][0-9][0-9][ ][-][ ]//g')
titel=$(echo $song | cut -d'/' -f9 | cut -d'-' -f2- | cut -d' ' -f3- | sed -e 's/.mp3//g')
nummer=$(echo $song | cut -d'/' -f9 | cut -d'-' -f2- | cut -d' ' -f2)
jahr=$(echo $song | cut -d'/' -f8 | cut -d' ' -f1)
eyeD3 --remove-all "$song"
id3v2 -y "$jahr" "$song"
eyeD3 -a "$interpret" -A "$album" -t "$titel" -n "$nummer" "$song"
mp3gain -r -c "$song"
done
|
Bei einer Anzahl von 11 Alben zum Testen verringerte sich die Zeit, ohne mp3gain, von 2:19 min auf 1:35 min.
Ich habe aber vor, das bei rund 2000 Alben zu tun. Nun Habe ich festgestellt, dass zum generieren des Jahres, anders als beim Erstellen des Skriptes, auch eyeD3 funktioniert. Damit sieht es nun so aus:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | #! /bin/bash
find ~/Multimedia/Musik/Arbeitsordner -type f -name '*.mp3' | sort -u | while read song
do
interpret=$(echo $song | cut -d'/' -f7)
album=$(echo $song | cut -d'/' -f8 | sed -e 's/[0-9][0-9][0-9][0-9][ ][-][ ]//g')
titel=$(echo $song | cut -d'/' -f9 | cut -d'-' -f2- | cut -d' ' -f3- | sed -e 's/.mp3//g')
nummer=$(echo $song | cut -d'/' -f9 | cut -d'-' -f2- | cut -d' ' -f2)
jahr=$(echo $song | cut -d'/' -f8 | cut -d' ' -f1)
eyeD3 --remove-all -a "$interpret" -Y "$jahr" -A "$album" -t "$titel" -n "$nummer" "$song"
mp3gain -r -c "$song"
done
|
Damit liegt die Zeit bei 1:22 min. Das ist zwar schon fast eine Minute schneller, als das Original, aber ich hätte nichts gegen eine weitere Beschleunigung.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Man könnte sicherlich den 1. Teil der Schleife noch schöner machen (z.B. mit Parameter Expansion statt der blöden Process Expansions), aber für die Rechenzeit bringt das nicht wirklich was. Wie xunil123 schon sagte: den Löwenanteil wird mp3gain brauchen. Vielleicht kann man da noch an einem Schräubchen drehen ? Ich frage mich allerdings sowieso, warum Du Deine gesamte Musiksammlung umcodierst, denn dabei verlierst Du zwangsläufig ein ganzes Stück Qualität. Da hat man bei MP3 ja eigentlich auch nicht so viel zu verschenken ... track
|
hellmi666
(Themenstarter)
Anmeldungsdatum: 30. August 2007
Beiträge: 238
Wohnort: Zwickau
|
track schrieb: Ich frage mich allerdings sowieso, warum Du Deine gesamte Musiksammlung umcodierst,...
Damit auf einem Mp3-Player alle Titel gleich laut sind. track schrieb: Parameter Expansion statt der blöden Process Expansions
Kannst du mir das einmal erklären? Bin jetzt nicht so der Skript-Guru.
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
hellmi666 schrieb: track schrieb: Parameter Expansion statt der blöden Process Expansions
Kannst du mir das einmal erklären? Bin jetzt nicht so der Skript-Guru.
Du müsstest Dir das mal selber angucken: in Greg's Wiki, und ansonsten hier im Forum mit dem Suchwort "Parameter Expansion" - da gibt es reichlich Beispiele und Erklärungen. (ich bin nämlich jetzt bis heute Abend spät unterwegs !) LG, track
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13213
|
track schrieb: hellmi666 schrieb: track schrieb: Parameter Expansion statt der blöden Process Expansions
Kannst du mir das einmal erklären? Bin jetzt nicht so der Skript-Guru.
Du müsstest Dir das mal selber angucken: in Greg's Wiki, und ansonsten hier im Forum mit dem Suchwort "Parameter Expansion" - da gibt es reichlich Beispiele und Erklärungen.
Das könnte ungefähr so gehen: | IFS='/' songdata=($song)
interpret=${songdata[6]}
album=${songdata[7]/[0-9][0-9][0-9][0-9] - /}
...
|
Ciao robert
|
froggydancer
Anmeldungsdatum: 6. Januar 2010
Beiträge: 156
|
track schrieb: hellmi666 schrieb: track schrieb: Parameter Expansion statt der blöden Process Expansions
Kannst du mir das einmal erklären? Bin jetzt nicht so der Skript-Guru.
Du müsstest Dir das mal selber angucken: in Greg's Wiki, und ansonsten hier im Forum mit dem Suchwort "Parameter Expansion" - da gibt es reichlich Beispiele und Erklärungen.
Mein Vorschlag dafür wäre:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | #! /bin/bash
find ~/Multimedia/Musik/Arbeitsordner -type f -name '*.mp3' | sort -u | while read song
do
echo "$song" | sed 's%\([^/]*/\)\?\([^/]\+\)/\([0-9]\{4\}\) - \([^/]\+\)/\([^/]\+\) - \([0-9]\{2\}\) \([^/]\+\)\.mp3%\2\t\3\t\4\t\5\t\6\t\7%' | (
IFS=" "
read interpret jahr album trackinterpret nummer titel
echo eyeD3 --remove-all -a "$interpret" -Y "$jahr" -A "$album" -t "$titel" -n "$nummer" "$song"
echo mp3gain -r -c "$song"
)
done
|
Kurz erklärt, was darin passiert: sed in Zeile 5 zerlegt den Dateinamen/Pfad per Regex in die einzelnen Bestandteile und fügt dazwischen jeweils einen Tab (\t ) als Trennzeichen ein. In Zeile 6 wird über die Umgebungsvariable IFS Tab als Feldtrenner definiert, sodass das read in Zeile 7 die einzelnen Teile erkennen und in verschiedene Variablen laden kann. lg Froggy
|
hellmi666
(Themenstarter)
Anmeldungsdatum: 30. August 2007
Beiträge: 238
Wohnort: Zwickau
|
Vielen Dank für eure Antworten. Aber irgendwie ist mir das mit den Regexen zu hoch. Und wenn schon zu hoch, warum dann nicht richtig. Gibt es vielleicht andere Sprachen, wo die Rechenzeit beschleunigt wird? Ich glaube, dass ich irgendwo mal gelesen habe, dass C oder C++ schnell sein soll. Ist dem so?
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2133
Wohnort: Gelsenkirchen
|
Es wird ziemlich egal sein, ob du den Ablauf jetzt auch noch in C oder gar Assembler realisierst. Fakt ist, dass der Löwenanteil sehr wahrscheinlich für Festplattenzugriffe draufgehen wird. Die Songs wollen halt auch geladen und dann in der veränderten Version wieder geschrieben werden. Das wird bei solchen Aufgaben einfach zum Flaschenhals. Wenn du wirklich einen spürbaren Performanceschub sehen willst, dann müsstest du dir quasi eine schnellere Festplatte zulegen... 😉
|
sven-s
Anmeldungsdatum: 5. August 2010
Beiträge: 700
|
Es koennte vielleicht noch etwas bringen, wenn man das ganze parallelisiert, um so die CPU so stark wie moeglich auzulasten. So muesste die CPU nicht immer warten, bis alles von der Festplatte geladen ist, sondern sie koennte gleich durchweg arbeiten. Frag mich aber bitte nicht, wie es zu realisieren waere.
|
stfischr
Anmeldungsdatum: 1. März 2007
Beiträge: 19197
|
Peace. Parallel ist auch meine Idee, man muss halt find mit exec benutzen.
|
sven-s
Anmeldungsdatum: 5. August 2010
Beiträge: 700
|
Ich habe da schon mal vor einer Weile was gelesen, vielleicht koennte GNU prallel hier Anwendnung finden.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13213
|
sven-s schrieb: Ich habe da schon mal vor einer Weile was gelesen, vielleicht koennte GNU prallel hier Anwendnung finden.
Das braucht man gar nicht. Da wir hier bereits find benutzen kann man das auch so machen: | find ~/Multimedia/Musik/Arbeitsordner -type f -name '*.mp3' | sort -u | while read song
do
...
done
|
übersetzt man dann nach | find ~/Multimedia/Musik/Arbeitsordner -type f -name '*.mp3' -print0 \
| xargs -r0 --max-args=100 --max-procs=20 bash -c 'for song; do ... done' --
|
Hatte eigentlich mal jemand darauf hingewiesen, dass der "sort -u" total überflüssig ist? Die Dateinamen werden sowieso nur ein mal ausgegeben. Im Gegenteil, der sort hat hier auch noch den negativen Effekt, dass find erst komplett fertig sein muss, bevor irgendein Dateiname vom sort in die Pipe ausgegeben wird. Vermutlich reicht es schon, den sort wegzulassen, damit die ganze Sache deutlich schneller wird. Ciao robert
|