Hlavní navigace

Jak na kompresi mp3 na více jádrech

11. 7. 2008 10:11 (aktualizováno) Petr Krčmář

Přemýšlel jsem nad tím, jak vyřešit vícevláknovou kompresi souborů mp3. Nedávno byla v diskusi debata na toto téma. Bylo to spíš takové hraní, ale pokud vás zajímá jednoduché řešení, nabízím jeho popis.

Když se v diskusích objevilo téma Využití více jader, také jsem přemýšlel, jak elegantně problém vyřešit. Svou ideu jsem v diskusi naznačil. Je jasné, že se nejedná o ideální řešení.

Hodí se ve chvíli, kdy potřebujeme zpracovat hromadu úloh, které nám zaberou přibližně stejnou dobu – tedy ideální například na kompresi mp3. Většina skladeb má totiž podobnou délku a doba jejich zpracování bude velmi podobná.

Před pár dny jsem chtěl zkomprimovat jedno album a tak jsem se rozhodl, že se pustím do psaní skriptu, který mi vše urychlí. Nejde ani tak o ten samotný výkon, ale o to dokázat si, že to jde. Jeden kolega to shrnul slovy: „Aha, takže teď se Ti to album nekomprimuje čtyři minuty, ale dvě a půl“ Je jasné, že výkon počítače není problém. Ale když už tam ta jádra jsou…

Výsledný skript vypadá takto:

#!/bin/bash

ls *.wav|while read "soubor"
do
    echo "Delam mp3 z $soubor"
    nice -19 lame -m j --quiet --vbr-new -b 64 -B 192 "$soubor" "$soubor.mp3" &

    read "soubor"
    if [ -z "$soubor" ]
        then
            wait
            continue
        fi

    echo "Delam mp3 z $soubor"
    nice -19 lame -m j --quiet --vbr-new -b 64 -B 192 "$soubor" "$soubor.mp3" &

    wait
done

Netvrdím, že je to nejlepší řešení. Spíš bych to nazval „proof of concept“ tedy důkaz, že to i takto jde.

Jak to funguje? Nejprve získám z aktuálního adresáře seznam wav souborů, pak na první z nich pustím lame na pozadí. Pak načtu další název a ověřím, jestli jsem něco dostal (pokud by už byl konec seznamu wavů, skript končí). Pokud ano, pak se pustí druhý lame opět na pozadí. Pak přichází klíčový příkaz wait, který čeká, až úlohy na pozadí skončí. Poté, pokud ještě nějaké soubory v seznamu zbývají, se skript opakuje.

Skutečně to funguje, skript po většinu doby vytěžuje obě jádra. Je jasné, že pokud by byla některá skladba podstatně kratší než druhá, došlo by u jednoho jádra k prostoji (čekalo by, až doběhne delší práce), ale na tom mi příliš nesejde.

Jedná se o velmi jednoduché řešení, které prostě funguje. Ve zmiňované diskusi bylo načtrnuto více možností, mě osobně se nejvíce líbil nápad s Make, který je zcela univerzální, netrpí „prostoji“, ale zase na druhou stranu to není o několika řádcích skriptu. Časem ho ale možná taky zkusím realizovat.

Sdílet