Přejít k navigační liště

Zdroják » Webdesign » Duch Indiana Jonese: synchronizace videa s mapou

Duch Indiana Jonese: synchronizace videa s mapou

Články Webdesign

Velmi oblíbený efekt je zobrazování pozice na mapě spolu s videem – např. při jízdě nějakou trasou, kdy vidíme video zabírané z vozu a zároveň sledujeme pozici na mapě. V HTML5 můžeme použít tagu Video a synchronizovat zobrazování trasy na mapách s přehráváním pomocí zabudovaných API funkcí.

Článek je volným překladem textu Spirit of Indiana (Jones) – syncing HTML5 Video with Maps, jehož autorem je Chris Heilmann. Text vyšel na webu Mozilla Developer Center pod licencí CC-BY-SA. Tento text je k dispozici pod stejnou licencí, můžete jej tedy šířit a upravovat, pokud zachováte informace o autorovi a pokud své dílo zveřejníte pod podobnou licencí. 

Vždy se mi velmi líbily cestovatelské a letecké sekvence ve filmech o Indiana Jonesovi, a soudě dle velkého množství napodobenin na YouTube, nejsem sám. Nemám žádný software pro editování videa, tak jsem přemýšlel, zda by bylo možné dosáhnout téhož efektu za pomoci webových technologií a Google Maps, a výsledkem je toto:

Online demo zde

Můžete si stáhnout zdrojové kódy a vyzkoušet vše lokálně – budete potřebovat pouze prohlížeč, který zvládá HTML5 Video. Já vím – hudba není stejná jako ve filmech, ale ta, kterou jsem použil, aspoň není zatížena copyrightem a jde nám přímo od srdce (vznikla během pěti minut v zasedačce v kancelářích Mozilly).

Jak to celé funguje a jaké problémy bylo potřeba řešit? Čtěte dál.

Krok 1: najděte video a získejte ho ve správném formátu

To byla ta snazší část. Mnoho public domain videí lze nalézt na Archive.org, a navíc jsou už ve formátech, vhodných pro HTML5 video. V tomto případě jsem použil krátké video s Charlesem Lindberghem, pořízené při jeho rekordním letu z New Yorku do Paříže v roce 1927.

Krok 2: zobrazení videa

Použití videa je velmi jednoduché:

<div id="stage">
  <video>
    <source src="http://www.archive.org/download/
CharlesLindbergTakesOff/CharlesLindbergTakesOff_512kb.mp4"
type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
    <source src="http://www.archive.org/download/
CharlesLindbergTakesOff/CharlesLindbergTakesOff.ogv"
 type='video/ogg; codecs="theora, vorbis"'>
  </video>
</div>

Formát MP4 využijí prohlížeče založené na Webkitu, Ogg použije Firefox a další. Vynecháme atribut controls u elementu video, protože si budeme video spouštět ve vlastní režii. Takže si vytvoříme tlačítko, které spustí přehrávání JavaScriptem:

window.addEventListener('load',
  function() {
    var stage = document.getElementById('stage');
    var v = document.getElementsByTagName('video')[0];
    but = document.createElement('button');
    but.innerHTML = 'Click to see Lindbergh's flight';
    stage.appendChild(but);
    but.addEventListener('click',function(e) {
      v.play();
      e.preventDefault();
    },false);
  },
false);

Protože je video součástí značkovacího jazyka, nikoli přehrávané přes plugin, můžeme s ním dělat co chceme – výhoda otevřených technologií. Například můžeme, jako v tomto případě, nastavit průhlednost pomocí CSS a umístit jej přes mapu.

Krok 3: animace cesty na mapě

Pojďme se teď zaměřit na animaci trasy. Google Earth má na to API, ale potřebuje speciální plugin. Naštěstí Google Maps umožňují kreslit do mapy (pomocí SVG, což je další otevřený formát). Zabalíme toto malování do funkce, a získáme požadovaný efekt:

V podstatě jsem pouze vzal výchozí a koncový bod a spočítal jsem tolik mezihodnot, kolik jich je potřeba pro celou animaci. Uložil jsem si souřadnice do pole pos; následně zobrazuji cestu od začátku na současnou pozici a centruji mapu na aktuální bod při každé iteraci.

spirit.draw = function(){
  var path = new google.maps.Polyline({
        path: [startpos,pos[now]],
        strokeColor: "#c00",
        strokeOpacity: .7,
        strokeWeight: 10
  });
  path.setMap(map);
  map.panTo(pos[now])
  now = now + 1;
  if(now < animationend-1){
    setTimeout(spirit.draw,200);
  }
}

Detaily naleznete v komentovaném výpisu kódu. Teď můžeme použít tuto animaci a pustit video přes ni. Problém je, že animace a video mohou ztratit synchronizaci. Když se video zasekne (jak se často stává např. na hotelových WiFi), tak by bylo dobré animaci pozastavit.

Krok 4: synchronizace videa a pohybu mapy

Mít dva zdroje časového signálu není dobré, je na místě se rozhodnout, kterému dáme přednost. V našem případě to bude přehrávané video.

Mimochodem – možná jste si všimli, že jsem kód mapy zabalil do obsluhy události tilesloaded. To je další opatření pro udržení synchronizace. Zjistil jsem totiž, že na pomalejším připojení může nahrávání mapových podkladů brzdit celé rozhraní, proto je celé rozhraní závislé na načtení mapy a je spuštěné až ve chvíli, kdy jsou podklady načtené.Protože je obsluha tilesloaded vyvolávána i při pohybu mapy, potřebujeme příznak, kterým zabráníme opakování efektu:

google.maps.event.addListener(map,'tilesloaded',function(){
  if(played === false){
    // [...other code...]
    played = true;
  }
});

Aktuální časovou značku přehrávaného videa zjistíme z video.currentTime. Dokud se video přehrává, volá neustále obsluhu události timeupdate. Protože je takových událostí vyvoláno opravdu mnoho, musíme obsluhu trochu urychlit. Trik je v tom, že počítáme po sekundách a zvyšujeme počítadlo vždy, když je dosaženo nové sekundy. Můžete se podívat na ukázku timestamp a sekundového intervalu v demonstraci synchronizace:

var now = 0;
v.addEventListener('timeupdate',function(o){
  log.innerHTML = v.currentTime; /* logging the real timestamp */
  var full = parseInt(v.currentTime);
  if(full >= now) {
    seqlog.innerHTML = now;  /* logging the seconds firing */
    now = now + 1;
  }
},false);

V tomto případě se může přehrávání videa přerušit kvůli přerušení datového toku, a sekvence stále zůstane synchronizovaná. Viz zdrojový kód na Githubu.

Dáme to vše dohromady

Není třeba už mnoho práce – jediné, co jsem musel udělat, bylo nastavit průhlednost videa v určitou chvíli, v jinou spustit zvuk a v dalších bodech ukázat a zase schovat copyright. Protože používáme obsluhu události společně s ostatními efekty, potřebujeme opět příznaky, které zajistí, že se činnost nevyvolá vícekrát:

v.addEventListener('timeupdate',function(o){
  full = parseInt(v.currentTime);
  if(full === now-1){
    mapelm.style.opacity = .8;
    v.style.opacity = .4;
  }
  if(full === animationstart+1 && audioplay === false){
    a.play();
    audioplay = true;
  }
  if(full === animationstart+2 && hidden === true){
    drmbedamned.style.display = 'block';
    hidden = false;
  }
  if(full === animationstart+3 && hidden === false){
    drmbedamned.style.display = 'none';
    hidden = true;
  }
  if(full >= now) {
    path = new google.maps.Polyline({
        path: [startpos,pos[full]],
        strokeColor: "#c00",
        strokeOpacity: .7,
        strokeWeight: 10
    });
    path.setMap(map);
    map.panTo(pos[full])
    now = now + 1;
  }
},false);

Další událostí, kterou si obsloužíme, je konec přehrávaného videa. V tu chvíli zastavíme zvuk a pustíme rolující titulky:

v.addEventListener('ended',function(o){
  a.pause();
  spirit.credslist.parentNode.style.display = 'block';
  spirit.creds();
},false)

Protože je audio příliš krátké na to, aby vystačilo po celou dobu animace, potřebujeme jej „zacyklit“. To uděláme testem na událost  ended a „převinutím“ času zpět na 0:

a.addEventListener('ended', function(o) {
  a.currentTime = 0;
},false);

Souhrn

A máme hotovo – mapa ve stylu Indiana Jonese pomocí otevřených technologií. Včetně náhradního řešení pro audio (bylo nahráno, stříháno a konvertováno ve volném editoru Audacity) a s využitím Google’s Web Fonts pro grafiku.

Můžete toto demo dál upravovat, třeba:

  • Nahradit Google Maps pomocí Openstreetmap, kvůli omezením GMaps
  • Udělat cestu z NYC do Paříže jako lehký oblouk, aby byla věrnější (ale opět – časování není stoprocentní, protože Lindberghovi to trvalo přece jen o něco delší dobu)
  • Použít místo mapy obyčejný obrázek a malovat do něj v Canvasu, čímž zrychlíte a zjemníte animaci.

Proč to nezkusit? Je to volně k použití, a je to zábava!

Komentáře

Odebírat
Upozornit na
guest
3 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře
Tomáš

Viděl jsem moc pěknou věc: na stránce se promítá reálné video z jedoucího auta a vedle se ukazuje trasa v mapě (v čase videa, rychlost není konstantní). Dá se i taková věc udělat?

Něco víc k tomu videu: jmenuje se „C’était un rendez-vous“, info na wikipedii http://en.wikipedia.org/wiki/C%27%C3%A9tait_un_rendez-vous, k vidění například tady: http://www.milkandcookies.com/link/36571/detail/ a mapa se promítá tady: http://bhendrix.com/wall/Gmaps_GVideo_Mashup_Rendezvous.html, ale video už k tomu nefunguje. Pro člověka neznalého Paříže to je jistě zajímavé. Řidič tam jel rozhodně rychle, ale projel to bez nehody.

Martin Malý

jasne, da… resil jsem neco podobneho, kde zdrojem souradnic na trase byly data z GPS – neni to nijak tezke, jednodussi to je v tom, ze data z GPS maji v sobe casove udaje, tak se synchronizuje snaz.

Simca

Pro opravdovou aplikaci, ktera pouziva API google kombinaci s videem se podivejte na http://www.videopasport.cz/

Hermes místo OpenClaw?

AI
Komentáře: 2
Většina AI agentů v roce 2026 vám nabízí pohodlí výměnou za kontrolu — běží na cizí infrastruktuře, ukládají vaše data neznámo kam a fungují jen tak, jak je jejich tvůrci navrhli. Hermes od Nous Research jde opačným směrem: je open-source, nainstalujete si ho na vlastní server za pár dolarů měsíčně, připojíte k libovolnému LLM a necháte ho, aby si sám psal vlastní schopnosti podle toho, co od něj potřebujete. Výsledek? Agent, který skutečně patří vám a po pár týdnech používání rozumí vašemu setupu lépe než kterýkoli komerční asistent. Podívejme se, co Hermes umí, jak ho rozjet a pro koho dává smysl.

Robots.txt nestačí. AI crawleři mění, jak weby chrání obsah

Robots.txt zůstává základní signál pro slušné crawlery, ale už neumí popsat hlavní problém: stejný veřejný obsah může sloužit klasickému vyhledávání, AI odpovědím, tréninku modelů i načtení na pokyn uživatele. Provozovatel webu proto musí oddělit účel přístupu, ověřovat identitu botů, měřit dopad na infrastrukturu a u hodnotného obsahu řešit i vynucení pravidel mimo samotný robots.txt.

Jak funguje WordPress Cron a proč občas selhává

„Cron mi nějak neběhá." Klasická věta, která ve WordPress světě může znamenat cokoli od špatně nastavené WP_SITEURL, přes loopback zablokovaný Cloudflarem, až po fatal error v callbacku, který nechal viset transient doing_cron. WP-Cron totiž není skutečný scheduler — je to pseudo-cron závislý na návštěvnosti webu a HTTP loopbacku, se všemi pastmi, které si dokážete představit. Tenhle článek je hloubkový průchod jeho vnitřnostmi: co se reálně děje při spawn_cron(), kde vznikají race conditions, proč selhává a čím ho v produkci nahradit.