Cílem skriptu je získat z audio CD digitální záznam všech skladeb, jejich seznam z CDDB, skladby zkomprimovat do formátu OGG Vorbis, ze záznamů CDDB vytvořit ID3 tagy a jména souborů a uklidit dočasné soubory.
#!/bin/bash if [ "$1" ]; then device=$1; else device="cdrom"; fi if [ "$2" ]; then directory=$2; else directory="new_dir"; fi if [ -e $directory ]; then if [ ! -d $directory ]; then echo "$directory již existuje a není to adresář!" exit 1 else echo "Adresář $directory již existuje!" fi else mkdir $directory fi cdda2wav -D /dev/$device -L 0 -J -v titles cdparanoia -d /dev/$device -Q -v cdparanoia -d /dev/$device -B err_track="track00.cdda.wav" [ -e $err_track ] && rm -f $err_track soubor_idx=1 for soubor in *.wav ; do [ $soubor_idx -lt 10 ] && soubor_index=0$soubor_idx [ $soubor_idx -ge 10 ] && soubor_index=$soubor_idx if [ -e "$PWD/audio_$soubor_index.inf" ]; then nazev_song=`grep Tracktitle audio_$soubor_index.inf |sed "s/[^']*'\(.*\)'[^']*/\1/g"` nazev_artist=`grep Performer audio_$soubor_index.inf |sed "s/[^']*'\(.*\)'[^']*/\1/g"` nazev_album=`grep Albumtitle audio_$soubor_index.inf |sed "s/[^']*'\(.*\)'[^']*/\1/g"` novy="$soubor_index-$nazev_song.ogg" novy=`echo $novy |tr '[]&=|/\\:;, ' '{}+-----.._'` novy=`echo $novy |sed -e "s/-_/-/g" -e "s/_-/-/g" -e "s/\._/./g" -e "s/_\././g"` novy=`echo $novy |sed -e "s/[!\"#$%'()*<>?@{}]//g"` echo "Převádí se $soubor_index:$nazev_song,$nazev_album,$nazev_artist" oggenc -q 6 -t "$nazev_song" -a "$nazev_artist" -l "$nazev_album" -N $soubor_index -n "%n %t.ogg" "$soubor" -o "$directory/$novy" else echo "Převádí se $soubor_index" novy=`echo $soubor |sed 's/wav/ogg/'` oggenc -q 6 "$soubor" -o "$directory/$novy" fi soubor_idx=$[$soubor_idx+1] done echo "Přejete si odstranit dočasné soubory inf a wav z aktuálního adresáře?" read -n 1 y echo case $y in [yYaAjJ]) mv *.cddb *.cdindex *.log $directory rm -f *.inf *.wav ;; esac exit 0
Rozbor skriptu
První podmínka if zjišťuje, zda byl zadán první poziční parametr. Pokud ano, naplní jím proměnnou device, pokud ne, uloží do této proměnné výchozí hodnotu cdrom. Podobně druhá podmínka naplňuje proměnnou directory buď hodnotou druhého pozičního parametru nebo defaultním new_dir.
Třetí podmínka zjišťuje, zda položka stejného jména, jako je hodnota proměnné directory, již existuje v aktuálním adresáři. Pokud ano a nejde o adresář, celý skript se ukončí. Pokud adresář již existuje, vypíše se jen upozornění a skript pokračuje dál.
Příkaz cdda2wav stáhne z CDDB názvy skladeb a uloží je do souborů pojmenovaných track<číslo>.inf, které budeme dále využívat pro ID3 tagy a jména souborů ogg. Dále vytvoří soubory audio.cddb a audio.cdindex s popisem celého disku, které si na konci skriptu uschováme.
Příkazy cdparanoia provedou vlastní převod všech audio stop z CD do aktuálního adresáře po skladbách. Vznikne tak tolik vsw souborů, kolik bylo melodií na CD. Někdy však mechanika nesprávně vytvoří ještě prázdný soubor track00.cdda.wav. Toto jméno jsem proto vložil do proměnné err_track.
V syntaxích cdda2wav a cdparanoia využíváme parametr pro označení zařízení, ze kterého se má číst (tj. naše CD-ROM mechanika). Protože z příkazového řádku se očekává pouze např. hdb nebo cdrom2, doplňujeme před hodnotu $device ještě adresář /dev/, takže z toho vzejde např. /dev/hdb nebo /dev/cdrom2.
Na dalším řádku je podmínka ve zjednodušeném zápisu (bez if). Zjišťuje, zda soubor jména odpovídajícího hodnotě proměnné err_track v aktuálním adresáři existuje. Pokud ano (&&), smaže jej. Kdybychom to neudělali, nesouhlasilo by nám číslování skladeb.
Před začátkem procesu konvertování souborů z wav na ogg nastavíme počítadlo skladeb (soubor_idx) na hodnotu 1. A nyní zahájíme konvertovací smyčku příkazem for. Ta bude postupně obměňovat obsah proměnné soubor tak dlouho, až v něm vystřídá všechna jména souborů z aktuálního adresáře, které odpovídají masce *.wav, tj. projde postupně všechny naše nagrabované skladby.
Další dva řádky zavádějí novou proměnnou soubor_index, což bude dvoumístné pořadové číslo skladby na CD. Vycházíme z proměnné soubor_idx (která se na konci každého průchodu cyklem zvyšuje o 1). Pokud je soubor_idx menší než deset, bude soubor_index sestávat z nuly a hodnoty soubor_idx, tj. i čísla pod 10 budou přidáním nuly dvojmístná. Pokud je soubor_idx větší nebo roven 10, převezme se tato hodnota do soubor_index.
Následující podmínka zkoumá, zda máme pro právě zpracovávanou skladbu soubor s popisem stažený z CDDB, tj. zda existuje soubor jména audio_$soubor_index.inf. Máme-li jej, vybere z něj postupně tři hodnoty pro proměnné nazev_song, nazev_artist a nazev_album.
Výběr hodnot provádíme tak, že každé proměnné přiřadíme výsledek práce posloupnosti příkazů grep (vyhledávání řetězce v obsahu souboru) a sed (proudový editor textu). Tato posloupnost je spojena rourou, takže řádek, který grep v zadaném souboru najde, pošle ke zpracování sedu. Ten z něj vybere potřebnou posloupnost znaků (řetězec mezi apostrofy) a ten se pak stane hodnotou příslušné proměnné.
Další čtyři řádky postupně utvářejí jméno budoucího souboru a využívají k tomu proměnnou novy. Nejprve ji naplníme spojením hodnoty soubor_index (číslo skladby), pomlčky, nazev_song (název skladby) a koncovky .ogg.
Lze očekávat, že nazev_song obsahuje mezery, lomítka, dvojtečky, uvozovky a jiné znaky, které bychom ve jménech souborů raději neměli. Proto řetězec uložený v proměnné novy v následujících třech řádcích profiltrujeme.
Použijeme k tomu podobnou metodu jako při vytahování jména skladby, autora a alba z inf souboru. Proměnné novy přiřadíme (vlastně její hodnotu nahradíme) řetězcem, který vypadne z posloupnosti příkazů zadaných ve zpětných apostrofech. Nejprve vypíšeme příkazem echo původní hodnotu proměnné novy a potom ji skrze rouru pošleme na zpracování konkrétnímu filtru.
V prvním případě hraje roli filtru příkaz tr, který nahradí všechny výskyty jednotlivých znaků uvedených v prvních apostrofech jejich ekvivalenty z druhých apostrofů, takže z hranatých závorek udělá složené, z & bude +, rovnítko, svislítko, lomítko, obráceného lomítko (to bylo nutné zadat zdvojeně) a dvojtečka se změní v pomlčku, středník a čárka v tečku a z mezery se stane podtržítko.
Zbývající dva filtry na jméno souboru jsou poháněny programem sed. I sed zde používáme jen k nahrazování. V každém páru uvozovek je příkaz pro jedno nahrazení. Nahrazuje se vždy řetězec mezi prvním a druhým lomítkem řetězcem mezi druhým a třetím lomítkem. Jeden řádek tak změní konstrukce typu _-_ na pomlčku a _._ na tečku. V tom druhém změníme vypsané znaky (!\"#$%'()*<>?@{}) na prázdný řetězec, tedy odstraníme je.
Potom je tam řádek velmi jednoduchý. Pomocí echo nám oznámí, která skladba se bude převádět. Vlastní enkódování zajišťuje příkaz oggenc, který převezme dříve zjištěné informace o názvu skladby, jménu autora a alba do ID3 tagů. Výstup (-o) nasměruje do adresáře stanoveného proměnnou adresar a jméno souboru vezme z námi pracně upravené proměnné novy.
Tím jsme ukončili tu část podmínkové konstrukce if, ve které pro zpracovávaný hudební soubor existoval příslušný soubor inf stažený z CDDB. Za else bude následovat posloupnost příkazů, které se provedou, když tento soubor přítomný není.
Nejprve nám skript oznámí, který soubor bude převádět, a to výpisem jeho pořadového čísla. Potom si připraví proměnnou novy tak, že vezme původní jméno souboru (echo $soubor) a rourou se pošle programu sed, který v něm nahradí koncovku wav za ogg. A nakonec už stačí jen spustit oggenc s parametrem vstupního a výstupního souboru.
Pomocným fi zakončujeme celou část vlastního překódovávání wavu do oggu. Než se ukončením cyklu for-do-done vrhneme na další soubor, zvýšíme ještě hodnotu soubor_idx o jedničku. Využíváme k tomu zápis $[$soubor_idx+1], který podrobněji rozebereme v některém z následujících dílů seriálu.
Až skript projde a překóduje všechny wav soubory v aktuálním adresáři, přistoupí k závěrečně fázi, kde se nás zeptá, zda má odstranit pracovní soubory inf a wav. Potom pomocí read přečte právě jeden znak z klávesnice. Jedno echo pro odřádkování a je tu case, kde budeme vyhodnocovat obsah proměnné y načtené zmíněným read.
Pokud y nabyde jednu z hodnot yYaAjJ, budou soubory inf a wav odstraněny. Soubory *.cddb, *.cdindex a *.log budou přesunuty do cílového adresáře ($directory). A je vymalováno. Ani to nebolelo.