HTML5 Audio: rádio ve vašich stránkách

V dalším pokračování seriálu o HTML5 se podíváme na jednu z novinek prakticky – vyzkoušíme si, jak lze pomocí HTML5 a elementu Audio vytvořit webový rozhlasový přijímač, který přehrává streamované vysílání rozhlasových stanic, a navíc si ukážeme, jak z takového přehrávače vytvořit samostatnou aplikaci.

Seriál: Webdesignérův průvodce po HTML5 (21 dílů)

  1. Webdesignérův průvodce po HTML5 – díl nultý 25.5.2010
  2. Webdesignérův průvodce po HTML5 – nová sémantika 1.6.2010
  3. Webdesignérův průvodce po HTML5 – nová sémantika II 8.6.2010
  4. Webdesignérův průvodce po HTML5 – pohyblivé obrázky 15.6.2010
  5. Webdesignérův průvodce po HTML5 – používáme pohyblivé obrázky 22.6.2010
  6. Webdesignérův průvodce po HTML5 – taháme data od návštěvníka 29.6.2010
  7. HTML5 Audio: rádio ve vašich stránkách 13.7.2010
  8. Webdesignérův průvodce po HTML5: Microdata 20.7.2010
  9. AppCache: webové aplikace i bez připojení 27.7.2010
  10. Webdesignérův průvodce po HTML5: WebStorage 3.8.2010
  11. Webdesignérův průvodce po HTML5: Multithreading s WebWorkers 10.8.2010
  12. Webdesignérův průvodce po HTML5: Databáze v prohlížečích 17.8.2010
  13. Webdesignérův průvodce po HTML5: Shrnutí a rozhrnutí 24.8.2010
  14. HTML5: ukládáme si data k elementům 6.12.2010
  15. Webdesignérův průvodce po HTML5: Táhni a srůstej 5.1.2011
  16. HTML5: První krůčky s FileSystem API 15.2.2011
  17. Mobilizujeme web v HTML5 4.4.2011
  18. Single Page Apps a řešení problémů s historií 1.6.2011
  19. Page Visibility API: Kouká na mě vůbec někdo? 10.8.2011
  20. Práce se soubory v prohlížeči, díl 1 15.8.2011
  21. Práce se soubory v prohlížeči, díl 2 5.9.2011

Tento článek je překladem anglického originálu vydaného na serveru Dev.Opera.

Úvod

Před příchodem HTML5 bylo přidání audia na stránky poněkud neohrabané. Po mnoho let byl Flash jedinou možností, jak interaktivně nabídnout nějaký audio obsah, ale s příchodem elementu<audio> v HTML5 se při přehrávání zvuku obejdeme bez pluginů. Navíc jej lze velmi dobře kombinovat s dalšími technologiemi – můžete vytvořit a nastylovat tlačítka pomocí HTML a CSS a můžete je obsluhovat pomocí HTML5 audio API. Nemusíte tak kvůli každé změně chování měnit Flashový přehrávač.

V tomto článku se podíváme na element <audio>. Probereme si základy, podíváme se detailně na podporu v prohlížečích a nakonec si postavíme přehrávač rádia, které bude používat živé streamované vysílání. (Doplníme si tak informace o elementu <audio> , které jsme v našem seriálu už přinesli – pozn.překl.)

Základní syntaxe

Použití elementu <audio> je velmi snadné. Chcete-li přehrát nějaký .ogg soubor, napište

<audio src="http://yourserver/rockandroll.ogg" controls preload> </audio>

Prohlížeč pak nabídne na stránce jednoduchý přehrávač:

Obrázek 1: základní element <audio> v prohlížeči Opera.

Element <audio> má pět atributů:

  • src obsahuje cestu k audio souboru, který chcete přehrát. Atribut src může být též nahrazen jedním nebo více vnořenými elementy <source>:

    <audio controls preload>
        <source src="http://yourserver/rockandroll.ogg" />
    </audio>

    To je velmi užitečná vlastnost, protože umožňuje použít několik elementů <source> a odkázat je na různé audioformáty. Jak uvidíme později, není podpora audioformátů v prohlížečích jednotná, takže nejlepší je nabídnout něco, co může přehrát většina prohlížečů. Například:

    <audio controls preload>
        <source src="http://yourserver/rockandroll.ogg" />
        <source src="http://yourserver/rockandroll.mp3" />
    </audio>
  • autoplay je příznak, který specifikuje, jestli má začít přehrávání automaticky po nahrání stránky.

    Poznámka: Mějte na paměti, že automatické spuštění přehrávání je mnohými uživateli vnímáno negativně. Autoplay začne přehrávat zvuk bez zásahu uživatele a může tak rušit jiné zvukové zdroje, které uživatel chce poslouchat. Pokud už musíte autoplay použít, ujistěte se, že uživatel má možnost přehrávání vypnout.

  • preload napovídá prohlížeči, jak se zachovat k datům. Mobilní prohlížeč se např. může rozhodnout, že nebude žádná data stahovat dopředu, aby ušetřil přenosové pásmo, zatímco desktopový prohlížeč na rychlé lince může začít s nahráváním ihned. Povolené hodnoty jsou preload="none", preload="metadata" a preload="all". Další informace o atributu preload naleznete ve specifikaci.

  • loop říká, zda má přehrávač poté, co přehraje celý soubor, začít přehrávat znovu od začátku v nekonečné smyčce.

  • controls je příznak, který určuje, jestli prohlížeč zobrazí svou vlastní sadu ovládacích prvků. Pokud tento příznak neuvedete, neukážou se žádné ovládací prvky a budete si muset vytvořit vlastní pomocí JS API, HTML, CSS a dalších možných technik.

JavaScript API

Element <audio> nabízí poměrně mocné JavaScriptové API. V tomto článku popíšeme pouze nezbytné minimum, protože k vytvoření přehrávače použijeme hotovou knihovnu, ale přesto je dobré alespoň základní představu o jeho možnostech mít.

V JavaScriptu můžeme zavolat objekt Audio, který vrátí element <audio> element. Tento element není součástí DOM stromu, dokud jej tam pomocí dalších operací nepřidáme. Element <audio> může být řízen pomocí svých metod a vlastností bez ohledu na to, jestli je nebo není v DOM. Můžeme mu např. předat URL souboru, který má být přehrán:

var audio = new Audio("http://yourserver/rockandroll.ogg");

Můžeme změnit soubor i tak, že přiřadíme novou hodnotu atributu src:

audio.setAttribute("src", "http://yourserver/morerock.ogg");

Přehrávání můžeme spustit a zastavit metodami audio.play() a audio.pause(). audio.volume nabízí přístup k hlasitosti a event listener timeupdate zavolá událost pokaždé, když se změní čas. Tyto jednoduché metody nám postačí k vytvoření jednoduchého přehrávače se stejnými funkcemi, jaké má ten, který je zabudovaný v prohlížeči.

Pojďme se podívat na tyto funkce v akci. Následující skript vytvoří element <audio> a přiřadí ovladače událostí jednoduchým tlačítkům v HTML, pomocí nichž budeme moci ovládat přehrávání audia:

// Vytvoříme nový objekt Audio
var audio = new Audio('test.ogg');
// Vezmeme tlačítko Play a na onclick připojíme audio play
var play = document.getElementById('play');
play.addEventListener('click', function(){
    audio.play();
}, false);
// Vezmeme tlačítko Pause a na onclick připojíme audio pause
var pause = document.getElementById('pause');
pause.addEventListener('click', function(){
    audio.pause();
}, false);
// Vezmeme HTML5 range input element a událost change obsloužíme změnou hlasitosti přehrávače
var volume = document.getElementById('volume');
volume.addEventListener('change', function(){
    audio.volume = parseFloat(this.value / 10);
}, false);
// Zjistíme odehraný čas a zobrazíme jej v patřičném elementu
audio.addEventListener("timeupdate", function() {
    var duration = document.getElementById('duration');
    var s = parseInt(audio.currentTime % 60);
    var m = parseInt((audio.currentTime / 60) % 60);
    duration.innerHTML = m + '.' + s + 'sec';
}, false);

Tento skript bude pracovat s následujícím HTML kódem:

<div>
    <input id="play" type="button" value="Play" />
    <input id="pause" type="button" value="Pause" />
    <span id="duration"> </span>
</div>
<div>
    Volume:
    <input id="volume" type="range" min="0" max="10" value="5" />
</div>

Podívejte se na výsledek.

Pokud se chcete s možnostmi Audio API seznámit blíž, doporučuji prostudovat článek Simona Pieterse „Vše co potřebujete vědět o HTML5 videu a audiu“.

Podpora kodeků v prohlížečích

Element <audio> jde v HTML5 ruku v ruce s elementem <video>. Proběhla řada debat a sporů o tom, jaký videoformát by měl být používán (viz Introduction to HTML5 video nebo náš článek o audiu a videu v HTML5), a stejná diskuse probíhala i o zvuku. Současný stav podpory audiokodeků v hlavních prohlížečích je následující:

Prohlížeč Ogg Mp3 Wave
Opera 10.50 x x
Firefox 3.5 x x
Safari 4 x x
Chrome 3 x x
IE 8

Pokud chceme, aby obsah mohly přehrát různé prohlížeče, je nezbytné jej poskytnout ve více formátech. Jak jsme si řekli výše, lze použít více elementů <source> v jednom prvku  <audio>:

<audio controls preload>
    <source src="http://yourserver/rockandroll.ogg" />
    <source src="http://yourserver/rockandroll.mp3" />
    <!-- nouzové řešení - Flash apod. -->
</audio>

V audio elementu mezi otvíracím a zavíracím tagem může být (a mělo by být) nějaké nouzové řešení pro případ, že prohlížeč element <audio> nepodporuje, nebo nenašel vhodný formát. Může to být kupříkladu Flashový přehrávač s odkazem na stejný MP3 soubor, jako je v druhém  <source>.

Neznámé území — přehrávání streamovaného audia pomocí  <audio>

Máme přehrávač pro jeden audiosoubor, vytvořený s pomocí <audio> a funkční ve většině prohlížečů. Pojďme se posunout dál, na trošku míň probádané území: přehrávání živého audio streamu elementem <audio>. Naším cílem v tomto článku bude vytvořit radiopřehrávač, založený právě na elementu  <audio>.

Jednoduchý test ukázal, že prohlížeče se v podpoře audiostreamů velmi liší. Jsme ale stále ve velmi rané fázi vývoje HTML5, takže lze doufat, že se v blízké budoucnosti podpora streamovaného zvuku zlepší. Na druhou stranu test ukázal, že streamovat audio pomocí elementu <audio> lze, a s využitím vícenásobných zdrojů a „nouzového řešení“ to bude fungovat ve všech moderních prohlížečích.

Tento článek se nezabývá problematikou nastavení streamovacího serveru. Existují ale dobré tutoriály jak nastavit Icecast pro streamování živého proudu zvuku jako OGG i MP3.

Vytváříme přehrávač

Náš přehrávač postavíme na živém vysílání Českého rozhlasu. (Poznámka překladatele: Na rozdíl od originálního článku nebudeme ke streamování používat vysílání norského rozhlasu, ale použijeme internetový stream, který poskytuje Český rozhlas.) Český rozhlas nabízí live audio stream jak v MP3, tak v OGG, a my tedy budeme moci využít obojí.

Abychom se vyhnuli problémům s různými prohlížeči, použijeme plugin jPlayer pro jQuery. jPlayer poskytuje jednotné rozhraní: v moderních prohlížečích použije <audio> a ve starších náhradní řešení s Flashem. Společné rozhraní jak pro zabudovaný prvek <audio>, tak pro Flashovou náhradu, nám umožní vytvořit jednotný design a ovládání v JavaScriptu, CSS a HTML, aniž bychom se museli zabývat tím, jestli prohlížeč použil nativní řešení nebo Flash.

Oddělení dat od přehrávače

Nejprve si připravíme malý soubor ve formátu JSON s informacemi o streamech. Do něho si zapíšeme některé základní informace o rádiu a kanálech – URL streamů, jména kanálů a odkaz na logo stanice:

{
    "station" : {
        "name" : "CRo",
        "fullname" : "Český rozhlas",
        "website" : "http://www.rozhlas.cz/",
        "newsfeed" : "http://www.rozhlas.cz/export/portal",
        "qualitys" : [
            {
                "type" : "middle",
                "name" : "Middels"
            }
        ],
        "message" : "A message to the listener",
        "defaultChannel" : "Radiožurnál",
        "channels" : [
            {
                "name" : "Radiožurnál",
                "channel" : "CRo",
                "website" : "http://www.rozhlas.cz/radiozurnal",
                "schedule" : "",
                "logo" : "http://www.rozhlas.cz/img/t/zive_logo_cro1.jpg",
                "middle" : {
                        "type" : "middle",
                        "ogg" : "http://amp1.cesnet.cz:8000/cro1.ogg",
                        "mp3" : "http://amp.cesnet.cz:8000/cro1_high.mp3"
                }
            }
        ]
    }
}

Přesunutím informací o stanicích a streamech do tohoto JSON souboru je oddělíme od samotného přehrávače. V budoucnu se nám to bude hodit, pokud budeme chtít přidat další stanice či opravit některá data (např. při změně URL streamů). V takovém případě pouze editujeme JSON a nemusíme nijak zasahovat do přehrávače samotného.

Přidáváme strukturu a design

Nyní vybudujeme základní HTML kostru pro náš prohlížeč:

<div id="radio-player" class="radio-default">
    <!-- Audio placeholder used by jPlayer -->
    <div id="player"> </div>
    <!-- Container for channel picker -->
    <div id="channelPicker">
        <a tabindex="8" accesskey="l" id="paginationLeft" class="inactive"><span>Left</span></a>
        <div id="channels"> </div>
        <a tabindex="9" accesskey="r" id="paginationRight" class="active"><span>Right</span></a>
    </div>
    <!-- Container for display -->
    <div id="display">
        <a id="currentChannel"><img src="gfx/default/default-station.png" /></a>
        <span id="duration"> </span>
        <span id="quality"> </span>
    </div>
    <!-- Containers for admin functions -->
    <a tabindex="7" accesskey="c" id="displayChannelPicker" title="Channels"><span>Channels</span></a>
    <a id="config">Config</a>
    <!-- Containers for jPlayer actions -->
    <a tabindex="3" accesskey="d" id="volumeMin" title="Mute"><span>Mute Volume</span></a>
    <a id="volume"><span>Adjust Volume</span></a>
    <a tabindex="4" accesskey="u" id="volumeMax" title="Max"><span>Max Volume</span></a>
    <a tabindex="1" accesskey="p" id="play" title="Play"><span>Play</span></a>
    <a id="pause" title="Pause"><span>Pause</span></a>
    <a tabindex="2" accesskey="s" id="stop" title="Stop"><span>Stop</span></a>
    <!-- Container for error messages -->
    <div id="error">
        <h2>Error</h2>
        <p> </p>
    </div>
</div>

Každý <a> a <div> má nastavený id, aby byl snadno stylovatelný a dostupný z JavaScriptu kvůli přiřazování odpovídajících událostí a propojení s audio API. Některé z těchto elementů využije knihovna jPlayer, například ty s ID play a pause. Později si ukážeme jak.

Každé tlačítko je nastylováno pomocí obrázku na pozadí a umístěno na požadované místo pomocí absolutního pozicování. Kupříkladu CSS pro tlačítko „play“ vypadá takto:

/**
  * Play button
  */
.radio-default #play{
    position: absolute;
    top: 75px;
    left: 255px;
    width: 40px;
    height: 40px;
    background-image: url(../gfx/default/button-play.png);
    background-position: top left;
    background-repeat: no-repeat;
    cursor: pointer;
}

Další ovládací prvky, vybírání kanálu, displej s časem apod. jsou vytvořeny stejným způsobem.

Pozornost zasluhuje atribut class u elementu <div>, který obaluje celý přehrávač. Můžeme tuto třídu použít jako prefix ve stylopisu:

.radio-default #play{
    /* some style */
}

Tímto způsobem jsme u našeho přehrávače zjednodušili změnu vzhledu (skinování). Pokud vytvoříme vlastní vzhled s novým prefixem, můžeme si pomocí jednoduchého JavaScriptového kódu snadno přepínat vzhledy pouhou změnou hodnoty atributu class u zapouzdřujícího elementu <div>:

.radio-different #play{
    /* some different style */
}

Zapojujeme jPlayer

Posledním krokem k vytvoření plně funkčního přehrávače je zabudování knihovny jPlayer. Nejprve přidáme jQuery a jPlayer do dokumentu spolu s naším vlastním JS souborem, do něhož dáme svůj kód:

<script src="script/jquery-1.4/jquery.min.js"> </script>
<script src="script/jplayer-1.1.7/jquery.jplayer.js"> </script>
<script src="script/player.js"> </script>

jPlayer potřebuje knihovnu jQuery ke své práci, ale využijeme ji i my k obsluze dalších věcí v přehrávači.

Nejprve potřebujeme knihovně sdělit, který element bude obsahovat <audio>, co si vytvoří jPlayer:

// Player element - Holds the jPlayer
var playerElement = jQuery("#player");

Teď využijeme AJAXové funkce z jQuery a načteme náš JSON s informacemi o stanicích:

jQuery.ajax({
    url: "http://yourserver/channels.json",
    dataType: 'json',
    ifModified: true,
    success: function(data, status){
        for (var i = 0, len = data.station.channels.length; i < len; i++) {
            // Put each channel into a channel picker
        }
    }
});

Data získaná pomocí AJAXového požadavku projdeme kanál po kanálu a jednotlivé kanály přidáme do výběru stanic. Výběr stanic je obyčejný seznam obrázků, obsahující loga stanic a obsluhu události onclick, která změní přehrávaný kanál v případě, že uživatel na obrázek klikne.

Obrázek 2: Výběr rozhlasových stanic (originál)

Výběr rozhlasových stanic (česká verze)

Zjednodušeně lze činnost přepínače stanic popsat tak, že funkce, která je napojená na událost onclick u každého obrázku, volá metodu pro vyčištění informací o předchozím streamu a pro přidání vybraného streamu k <audio>  elementu:

changeChannel:function(){
    // Remove old stream
    playerElement.jPlayer("clearFile");
    // Set new stream
    playerElement.jPlayer("setFile", "urlToNewMP3Stream", "urlToNewOGGStream");
}

jPlayer se postará o smazání původních informací a nastavení nových. jPlayer ví, jaký typ streamu je v prohlížeči podporován, a jestli by měl být místo elementu <audio> použit náhradní Flashový přehrávač. Když máme načtená kanálová data a připravený výběr stanic, musíme nastavit jPlayer tak, aby pracoval s naší HTML kostrou.

playerElement.jPlayer({
    ready: function(){
        this.element.jPlayer("setFile", urlToDefaultMp3Stream, urlToDefaultOggStream);
    },
    swfPath: "script/jplayer-1.1.1/",
    nativeSupport: true,
    volume: 60,
    oggSupport: true,
    customCssIds: true
})
.jPlayer("cssId", "play", "play")
.jPlayer("cssId", "pause", "pause")
.jPlayer("cssId", "stop", "stop")
.jPlayer("cssId", "volumeMin", "volumeMin")
.jPlayer("cssId", "volumeMax", "volumeMax")
.jPlayer("cssId", "volumeBar", "volume")
.jPlayer("onProgressChange", function updateDuration(lp,ppr,ppa,pt,tt) {
     jQuery("#duration").text(jQuery.jPlayer.convertTime(pt));
});

Tento kód svazuje jPlayer s elementem #player, který jsme si připravili výše. Sdělíme jPlayeru, aby použil nativní <audio> v prohlížečích, které jej podporují – pomocí nativeSupport: true; také nastavíme výchozí hlasitost ( volume: 60), umístění nouzového Flashového přehrávače ( swfPath: "script/jplayer-1.1.1/"), jestli má být použit Ogg, pokud je podporován prohlížečem ( oggSupport:
true
) a co se má stát, když je přehrávač připravený ( ready:
function( ... );
).

Ve funkci ready nastavíme předvybranou stanici, kterou chceme spustit. Pokud uživatel vybere v selektoru jinou stanici, přepíšou nové hodnoty tohoto výběru původní nastavené.

Nakonec propojíme jPlayer s ID našich ovládacích prvků a nastavíme obsluhu událostí, což nám umožní měnit displej s časem.

A tak máme funkční přehrávač radiostanic, který pracuje v různých prohlížečích (originál).

Obrázek 3: Hotový prohlížeč běžící v prohlížeči Opera.

Ve výsledném kódu jsou další funkce, které jsme zde neprobírali, a které se starají o navigaci v selektoru stanic a upravují některé prvky podle chování uživatele. Kód pro přehrávač je dostupný na GitHubu, můžete si jej dle libosti přepracovat a hrát si s ním.

Pozn. překl.: Upravená verze, použitá v ukázce, je rovněž k dispozici – Přehrávač rádia.

Vytváříme z přehrávače widget

Je fajn přidat radiopřehrávač, jako je tento, na stránky, ale má to své nevýhody. Přehrávání se přeruší, pokud uživatel ze stránky odejde, pokud stránku znovu načte, nebo pokud z nějakého důvodu spadne prohlížeč. Takové události jsou pro posluchače nepříjemné, a v zájmu poskytovatele audio obsahu je, aby posluchač poslouchal stále.

Pokud přehrávač zabalíme jako widget pro Operu, budou si jej moci uživatelé Opery 10.5× nainstalovat jako samostatnou aplikaci. Přehrávač pak poběží ve vlastním okně, nezávisle na prohlížeči, a přehrávání audiostreamu bude pokračovat, i když uživatel prohlížeč zavře.

Vytvoření widgetu je snadné. Do kořenového adresáře přidáme jednoduchý soubor config.xml. V tomto konfiguračním souboru nastavíme jméno widgetu, rozměr okna aplikace a ikona, která bude pro přehrávač použita na ploše nebo v hlavním menu.

Widgety dokáží obsloužit AJAXové požadavky na jakýkoli server na internetu, a protože jsme veškeré informace o kanálech a streamech umístili do jednoho JSON souboru na server, jsme tak schopni udržovat aktuální informace o stanicích, aniž by bylo potřeba aktualizovat samotný přehrávač. Což je výhoda v situacích, kdy potřebujeme změnit nějaké informace – změny se projeví rychleji než kdyby si museli uživatelé aktualizovat své přehrávače sami. Abychom povolili widgetu přistupovat na náš server, musíme přidat network="public" do elementu <widget>. Hotový konfigurační soubor pro náš server může vypadat např. takto:

<widget defaultmode="application" network="public private">
    <widgetname>Radio Player</widgetname>
    <description>Radio Player</description>
    <width>300</width>
    <height>120</height>
    <icon>gfx/icon/icon_128.png</icon>
    <icon>gfx/icon/icon_64.png</icon>
    <icon>gfx/icon/icon_32.png</icon>
    <icon>gfx/icon/icon_16.png</icon>
    <author>
        <name>John Doe</name>
        <email>john.doe@yoursite.com</email>
        <link>http://yoursite/</link>
    </author>
    <id>
        <host>radio.yoursite.com</host>
        <name>radio-player</name>
        <revised>2010-05</revised>
    </id>
</widget>

Aplikaci vytvoříme prostým zaZIPováním potřebných HTML, CSS a JavaScript kódů spolu s ostatním příslušenstvím a se souborem config.xml. Změníme příponu souboru na .wgt a dostaneme widget, připravený k instalaci.

Obrázek 4: Radiopřijímač fungující jako Opera Widget.

Tento přehrávač můžete nalézt v repozitoři Opera Widgets.

Shrnutí

V článku jsme se podívali podrobněji na HTML5 <audio> element, pomocí jQuery a jPlayer jsme si usnadnili práci s přenositelností mezi prohlížeči a vytvořili jsme užitečný přehrávač živého internetového vysílání, který funguje ve stránce i jako samostatný widget.

Tento článek je překladem a adaptací textu An HTML5 <audio> radio player, jehož autorem je Trygwe Lie, a je zde zveřejněn s laskavým svolením Opera Software.

Začal programovat v roce 1984 s programovatelnou kalkulačkou. Pokračoval k BASICu, assembleru Z80, Forthu, Pascalu, Céčku, dalším assemblerům, před časem v PHP a teď by rád neprogramoval a radši se věnoval starým počítačům.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 5

Přehled komentářů

Norwi Audio
Pan Y Ukázka v Opeře
Pan Y Re: Ukázka v Opeře
Emanuel Bacigala z Popradu Zdá sa mi
Velda MP3/Wave?
Zdroj: https://www.zdrojak.cz/?p=3277