Apple’s Safari on iOS is pretty cool. It has pretty good support for HTML5 audio and video. Unfortunately there’s one big quirk that makes it almost impossible to do anything useful with it. Why? They disabled autoplay. According to the docs this is because:
(…) the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it.
In theory, this sounds great. Who doesn’t detest autoplaying advertisements on sites? Unfortunately this ‘feature’ has a few side-effects that cripple the general use of HTML5 audio/video. The autoplay property isn’t the only thing that’s disabled. Playing a HTML5 media element is not possible at all without an user action.
What does this mean in practice? Consider a piece of HTML like this:
<script>
function play() {
var a = new Audio();
a.src = 'http://example.com/audio.mp3';
a.play();
}
</script>
<button onclick="play()">play</button>
This works on iOS because the play() function is initiated from a user action (the click on the button). Now, consider something like this:
<script>
function play() {
var a = new Audio();
a.src = 'http://example.com/audio.mp3';
a.play();
}
setTimeout(play, 3000);
</script>
This doesn’t work on iOS. The play() method is called, but nothing happens because the function is not called from an user action.
Now, you might say, why would you ever want to play a video from a timeout? This example is very simplistic, but consider you’re writing a cross-browser media player that falls back on Flash on Internet Explorer, automatically plays the next track in a playlist, etcetera. You want to write clean code, so everything is modulairized, maybe using a tool like RequireJS and a MVC framework.
This means you’re getting lots of asynchronous callbacks, events, AJAX calls and dozens of functions you’re working with. Your original ‘click’ is lost and your cross-browser player doesn’t work on iOS. Bummer.
Or consider a game with sound effects. Every time you hit an enemy you want to play a sound. I suppose you don’t want to let your user click a button when she wants to hear a sound effect.
Of course, if you just want a simple video player for a blogpost you don’t run into this problem. But for virtually all advanced applications you’re going to run into the autoplay bug sooner or later.
Native iOS apps don’t have this problem, and you can actually disable the autoplay ‘feature’ by putting your web app in a native app (using UIWebView) and disabling the UIWebView.mediaPlaybackRequiresUserAction flag.
On Android this isn’t a problem at all. The code above works fine (tested on 2.3.3).
I think Apple has three possible solutions to ‘fix’ this problem:
Prompt the user to enable autoplay, just like with geolocation
Disable the ‘mediaPlaybackRequiresUserAction’ flag when the device is on WIFI
Op 19 september bezocht ik Kings of Code, de conferentie voor web developers. Het aardige aan Kings of Code is dat het complete spectrum aan web development aan bod komt en dus niet alleen een bepaalde programmeertaal of een bepaald framework. Hieronder een kort overzicht van wat ik op deze dag gezien en gehoord heb.
Understanding, Choosing & Instrumenting NoSQL
Tim Anglade werkt voor Cloudant en is de maker van NoSQL Tapes, een project met interviews en case studies over NoSQL-projecten. Hij gaf een uitgebreid overzicht van verschillende (open source) NoSQL-producten: CouchDB, Couchbase, BigCouch, Cassandra, Riak, MongoDB, Redis, Neo4j; besprak ze aan de hand van de volgende eigenschappen: distribution (Dynamo-style, master-slave, master-master), data/query model en disk structure; en gaf voor elke database een ideaal scenario. Zie de slides voor het overzicht:
Ik vond het opvallend dat hij NoSQL-oplossingen ziet als technologie waar je pas naar zou moeten gaan kijken als relationele databases je in de steek laten en je echt niet meer met een RDBMS toe kan. Onze ervaring met CouchDB is dat een NoSQL-oplossing ook gewoon allerlei wenselijke features kan hebben die je bij relationele databases niet vindt, zoals bijvoorbeeld de REST API van CouchDB. Aan de andere kant was het ook goed om een verhaal te horen dat niet uitsluitend de positieve kanten van NoSQL behandelde.
Declarative Applications
Steven Pemberton (CWI, W3C) is een oude rot op het web. Hij stond aan de wieg van de programmeertaal ABC (een voorloper van Python) en is tegenwoordig o.a. voorzitter van de XHTML2 en XForms Working Groups van W3C.
Na een interessante geschiedenisles over de kosten van computers en programmeurs door de jaren heen trekt Steven de conclusie dat programmeertalen traditioneel ontwikkeld zijn om zo efficiënt mogelijk door computers verwerkt te kunnen worden, omdat computertijd vroeger enorm duur was in vergelijking met het loon van een programmeur. Tegenwoordig is dat precies andersom: goede programmeurs zijn niet goedkoop, maar computers wel. Maar zijn programmeertalen daar op aangepast? Volgens Steven niet, of in ieder geval veel te weinig.
Het gros van het programmeerwerk wordt nog altijd in procedurele programmeertalen gedaan: de programmeur vertelt de computer stap voor stap wat er moet gebeuren. Volgens Steven is dé manier om programmeurs efficiënter te laten werken om ze gebruik te laten maken van declaratieve programmeertalen: specificeer wat je wil dat er gedaan wordt, niet hoe.
In beginsel ben ik het helemaal met Steven eens: het is prachtig als je declaratief kunt specificeren wat er moet gebeuren en de computer laat uitdokteren hoe dat precies moet gebeuren. Helaas illustreert Steven zijn punt met voorbeelden in XForms. De user interfaces van de voorbeelden zijn wat Spartaans (duidelijk een academicus, die Steven) en XML is naar mijn idee ook niet de meest leesbare vorm voor code, dus de wow-factor was wat laag. Daarnaast waren zijn voorbeelden dusdanig compact dat waarschijnlijk niemand in de zaal dacht: “Goh, dat levert een hoop winst op! Ik ga nooit meer iets met JavaScript doen!”
Het concept is prachtig, maar het is nog even wachten op degene die declarative programming naar de massa gaat brengen.
Jeroen van Dijk (CTO Enrise) gaf een mooi overzicht van hoe je ‘application accelerator’ Varnish Cache kunt gebruiken om de performance van je website te verbeteren. Hij liet onder andere zien hoe je performance kan verbeteren door cookies te laten negeren door de cache en hoe de website van AutoTrack.nl gebruik maakt van Edge Side Includes om verschillende onderdelen van de pagina voor verschillende periodes te cachen. Hierbij wordt de pagina dus eigenlijk samengesteld door Varnish (who needs a CMS?) en dat gaat toch wel wat verder dan een simpele reverse proxy (waar je Varnish overigens ook prima voor kan gebruiken).
Stephen Nelson-Smith (Atalanta Systems, Opscode) kwam ons vertellen waarom je je infrastructuur eigenlijk net zoals je software wil behandelen. Is een extra server toevoegen aan je setup een hoop werk? Is het lastig om een testserver te vervangen? Niet als je het installeren en configureren van een server en z’n applicaties automatiseert in code. Die code kun je testen, je kunt er versiebeheer op toepassen en je setup wordt makkelijk ‘repeatable’. Een server toevoegen aan een cluster wordt dan ineens een eitje.
En dat doe je dan uiteraard met Chef als het aan Stephen ligt. Chef voed je met ‘recipes’, wat feitelijk gewoon stukken Ruby-code zijn die gebruik maken van de Chef API. (De Chef Server gebruikt trouwens CouchDB als backend.) De vraag waarom je Chef zou moeten gebruiken in plaats een concurrerend product als Puppet (of CFEngine?) werd helaas ontweken.
Het zou naar mijn idee in beginsel best een goed idee zijn om de setup van een aantal applicaties bij de VPRO in een dergelijk systeem te vangen, maar het nadeel is dat onze infrastructuur niet erg homogeen is. Als al je machines (test, acceptatie en productie) bij Amazon in de cloud staan is dit waarschijnlijk goed werkbaar, maar als je lokale testserver een VMware image is en je acceptatieserver in een omgeving met NFS-shares staat, dan wordt het al snel een stuk lastiger.
Het zou interessant kunnen zijn om hier eens verder over na te denken en het zou misschien zelfs een argument kunnen zijn om een OTAP-straat te homogeniseren: het wiel niet opnieuw hoeven uitvinden voor elke stap in het proces kan een hoop tijd schelen en je documenteert ook indirect je infrastructuur.
Stephen Nelson-Smith gelooft niet in het publiceren van slides:
Web API’s World
Michele Zonca (Mashape) geeft een vliegensvlug overzicht van de staat van web API’s. SOAP was te complex, hoe REST opkwam, dat dat geen standaard maar een stijl is, dat een hoop mensen het verkeerd doen, het gedoe rond verschillende authenticatie-mechanismen en hoe je er geld mee zou kunnen verdienen. Dankzij zijn Italiaanse accent was het even lastig om erbij te blijven, maar het was een lekker compleet overzicht!
Chris Heilmann (Principal Evangelist Mozilla) presenteerde een tsunami aan technieken die HTML5 programmeurs in staat stelt om een lekker gelikte webapplicatie te maken. HTML5 is een misnomer, want de standaard omvat meer dan alleen markup: CSS3 (animatie, calculatie, hardware acceleratie), HTML5 forms (validatie (hoewel je daar voor beveiliging niet op kan vertrouwen, lijkt me, je zal toch server-side moeten valideren om te voorkomen dat iemand met de validatie heeft gerommeld), nieuwe elementen), File API, HTML5 video, Popcorn.js, Canvas, WebGL, local storage, offline mode, History API en SVG met D3.js en Raphaël.
Bert Belder is één van de core developers van Node.js, het event-driven I/O framework voor server-side JavaScript-applicaties op basis van Google’s V8 JavaScript-engine. Na een korte introductie over wat Node precies is begin hij aan een live demo. Hij begon met de mededeling dat live demo’s altijd een slecht idee zijn, omdat er altijd wat mis gaat. Waarom hij alsnog een live demo gaf is dan ook een raadsel, want het ging inderdaad mis. Een erg eenvoudige Node-applicatie startte zonder foutmeldingen, maar werkte niet. En Bert kon ook niet ontdekken wat er mis was. Niet al te beste reclame voor een systeem dat conceptueel wel erg interessant is.
Een tweede demo verliep iets beter en hierbij viel op dat Bert letterlijk JavaScript-code van de client naar de server kon verplaatsen, om deze door de server af te laten handelen. Het begin van de demo was een JavaScript-implementatie van Gorilla die in de browser draaide. Even later had hij een multiplayer-versie met een Node.js backend waar iedereen in de zaal met z’n laptop of telefoon op kon inloggen om ook met bananen te gooien. Node.js is duidelijk nog een jong project, maar heeft zeker potentie, zeker voor mensen die graag één programmeertaal gebruiken voor zowel frontend als backend.
Big Data
De dag werd afgesloten door Werner Vogels (CTO Amazon). Hij gaf geen presentatie, maar werd op het podium geïnterviewd door Robert Gaal, de host van Kings of Code, waarna er ook nog tijd was voor vragen van het publiek. De video van dit gesprek is nog niet beschikbaar, maar toevallig was hij enkele dagen later ook op bezoek bij Fast Moving Targets van o.a. oud-Digibaas Erwin Blom:
Veel websites die we bij VPRO Digitaal maken hebben audio en video als belangrijkste onderdeel. Essentieel voor deze sites is dus dat de media goed te bekijken en te beluisteren valt. We bieden daarom graag onze bezoekers een consistente en prettig bruikbare mediaspeler.
In de praktijk blijkt het echter behoorlijk moeilijk te zijn om één speler aan te bieden. Er is natuurlijk de speler van Uitzending Gemist, maar die is alleen bruikbaar voor media die ook daar te zien is, en dat is lang niet alles wat we aan media hebben. Veel sites hebben een mix van media die wel en niet op Uitzending Gemist staat, dus dan zijn twee spelers al noodzakelijk. Verder past de Uitzending Gemist speler niet altijd in de vormgeving van de sites. Twee spelers betekent twee verschillende vormgevingen, en onduidelijkheid voor de bezoeker. Iets wat we niet willen.
Het afgelopen jaar hebben we daarom gewerkt aan een oplossing die én een consistente vormgeving heeft én alle benodigde formaten kan afspelen. Deze speler, die we de VPROHTML Player hebben genoemd wordt inmiddels gebruikt op onder andere de sites van Tegenlicht, Holland Doc en Geschiedenis24. Het streven is om de speler op alle VPRO-sites te gebruiken, waaronder de vernieuwde website van 3voor12, die later dit jaar online zal gaan.
Wat maakt deze speler anders dan de bestaande spelers? Daarvoor moeten we eerst even terug naar de basis van wat we willen met een speler: het afspelen van video en audio op het web. Er is op dat gebied technisch de laatste tijd veel veranderd: een paar jaar geleden was het alleen mogelijk om met behulp van plugins als Flash en Silverlight video af te spelen. Sinds de introductie van HTML5 kan het ook ‘native’ in de webbrowsers, met de <video> en <audio> tags. Dat is uiteindelijk beter dan plugins, omdat de ondersteuning al in de browser zit ingebakken. Het voorkomt problemen tussen de plugins en de browser (plugins zijn vaak een belangrijke oorzaak van crashes in de browser), en het maakt het makkelijker voor de ontwikkelaar en dus uiteindelijk ook voor de bezoeker.
Helaas is de ondersteuning van HTML5 nog niet op een niveau dat we het cross-browser kunnen gebruiken om media af te spelen. Ook is een groot deel van ons media-archief van de publieke omroep in het Windows Media-formaat, wat alleen af te spelen valt met de Silverlight plugin. Nieuwere video is wel beschikbaar in andere formaten als H264. Op termijn zal dat wel convergeren naar andere formaten, maar we zullen zeker nog een lange tijd meerdere combinaties van formaten, plugins en browsers moeten ondersteunen.
Dat betekent echter niet dat we geen gebruik kunnen maken van delen van HTML5 om wél die consistente speler aan te bieden aan onze bezoekers.
Het principe van onze speler is in feite heel simpel: alle controls van de speler (zoals de play en volumeknoppen) zijn gemaakt in HTML en worden bovenop de eigenlijke speler gelegd. De look and feel kan gewoon worden gestyled met CSS, net zoals de rest van de website.
De control-loze speler (die we het canvas noemen) wordt aangestuurd met Javascript. Dat gebeurt via een generieke interface, die is gebaseerd op de HTML5 specificatie voor het <video> en <audio> element.
Niet alle spelers implementeren de HTML5 <video> en <audio> API spec, maar dat maakt niet uit. Voor die spelers schrijven we een jQuery plugin die commando’s vertaalt naar de HTML5 commando’s. Als een speler bijvoorbeeld de totale tijd van een mediafragment ‘endTime’ noemt (zoals in de Uitzending Gemist-speler) in plaats van ‘duration’ (wat HTML5 gebruikt) dan vertalen we dat. Op die manier hoef je niet voor alle canvassen de controls overnieuw te schrijven. Je laat het aan de onderliggende jQuery plugin over om het te vertalen. De bovenste ‘control’ laag kan daarom helemaal toegesneden zijn op het goed verwerken van de aansturing van de gebruiker.
Op dit moment hebben we twee ‘canvassen’ gemaakt voor onze speler: de Uitzending Gemist-speler en een generieke Silverlight-speler voor alle andere media die niet in Uitzending Gemist zit. Die speler kan bijvoorbeeld ook MP3 of H264 afspelen. In de toekomst hopen we dat uit te breiden met de Flash-variant van de Uitzending Gemist speler, een generieke Flash speler en natuurlijk de HTML5 <video> en <audio> elementen.
Door de recentelijk geïntroduceerde Tegenlicht Money & Speed ‘TouchDoc’ voor de iPad laait de discussie waarom de VPRO apps voor een specifiek platform maakt weer op. Hier een poging onze redenering uiteen te zetten.
Onze voorkeur gaat in eerste instantie altijd altijd uit naar een platform-onafhankelijke oplossing. Hierbij kan gedacht worden aan HTML5, als in het bouwen van mobiele sites of applicaties met HTML, javascript, CSS, Ajax etc, of het aanbieden van content via een API. Om hiervan af te wijken en te kiezen voor een gesloten omgeving als bijvoorbeeld iOS moet er dus een reden zijn.
VPRO Digitaal is er natuurlijk om voor een groot publiek haar applicaties en content aan te bieden, maar ook om op digitaal gebied te te innoveren. Soms gaat dat goed samen, soms minder goed. Het verkennen van nieuwe mogelijkheden, deze snel specifiek toe te passen en het geleerde terug vertalen naar algemeen bruikbare kennis of halffabrikaten is wat VPRO digitaal al ruim 15 jaar met succes doet. De opgedane kennis worden zeker binnen de omroepen, maar ook via dit weblog, presentaties en andere publicaties, ruim gedeeld.
Soms komt innovatie vanuit de techniek, een nieuwe techniek inzetten om verhalen op een nieuwe manier te vertellen, soms wil zijn er ideeën van ‘makers’ waar we techniek bij zoeken, soms een combinatie van beiden. In alle gevallen kan het zijn dat er gekozen wordt voor 1 enkel ‘beperkt’ platform als bijvoorbeeld iOS om het idee uit te voeren als dit niet of niet efficiënt op een platform-onafhankelijke manier kan. Het innoveren op meerdere platforms tegelijk is niet efficiënt omdat je niet ontkomt aan een iteratief proces van verbeteren. Mocht het nodig zijn om een ‘app’ op meerdere platforms aan te bieden vinden we het verstandiger eerst op 1 platform leergeld te betalen en daarna de vertaling te maken naar een volgend platform. Zo wordt momenteel de luisterpaal Android-app vervangen door een nieuwe versie op basis van de voor de iPhone ontwikkelde app.
In de keuze tussen iOS en Android zal dit geen rol spelen, maar er zijn bepaalde features die (nog?) niet te bouwen zijn in HTML5. In het geval van de populaire Luisterpaal hebben we bijvoorbeeld gekozen voor een iOS-app om redenen van beveiliging en het kunnen afspelen en bedienen in de achtergrond. Beide zaken die niet mogelijk zijn via HTML5 en hebben ons in dit geval voor apps doen kiezen.
De keuze tussen iOS en Android (en Blackberry / Windows Phone 7 etc) is eigenlijk een nieuwe. Tot op heden was iOS eigenlijk het enige platform waarvoor het zin had te ontwikkelen. We introduceerden anderhalf jaar geleden de Luisterpaal-app voor een groot aantal platforms (zie http://3voor12.vpro.nl/artikelen/artikel/42634182) en zagen dat het aantal downloads en het gebruik van de iPhone versie vele malen hoger was dat van alle andere platforms. Hierop besloten we, wetende dat het tijdelijk zou zijn, dat we ons op iPhone konden concentreren. Inmiddels is de tijd gekomen dit te herzien en ontwikkelen we ook voor Android en wellicht Blackberry. Uit kostenoverweging is het niet haalbaar alle verschillende platforms te bedienen en zullen we hier keuzes moeten blijven maken.
Een andere factor in de discussie tussen app of HTML5 is de distributie. Distributie via de Apple Appstore werkt gewoon goed. Gebruikers weten de app te vinden en deze wordt automatisch op het homescreen geplaatst, waardoor de kans dat een gebruiker de app ook daadwerkelijk gebruikt groter is. Uiteraard kunnen gebruikers van een HTML applicatie/site bookmarks en zelfs homescreen-buttons maken, maar dit is een extra stap waarvan wij (ook uit eigen ervaring) zien dat die vaak niet gemaakt wordt. Gevolg is dat mensen je sneller vergeten (uit het oog, uit het hart). Dit is zonde van alle middelen die we inzetten de app te maken. Dit argument zou snel aan gewicht kunnen verliezen als HTML-appstores een alternatief gaan bieden en ingeburgerd raken.
Terug naar de aanleiding, we krijgen regelmatig de vraag waarom de Money & Speed iPad app niet op andere platforms beschikbaar is. De reden dat het een app is en geen HTML5 site is dat de datavisualisaties die in de app zitten zo zwaar zijn dat we vermoedden dat dit beperkend zou zijn voor het eindresultaat. Daarnaast was het aanbieden van de documentaire gebundeld met de extra’s als 1 download (app) een wens zodat de documentaire ook offline gekeken kan worden. Overigens is de documentaire zelf via http://tegenlicht.vpro.nl/moneyandspeed voor een veel groter publiek te bekijken.
De keuze voor iOS (iPad in dit geval) is eenvoudig. Op het moment dat de Tegenlicht redactie met het idee kwam en wij er mee aan de slag gingen was de iPad net geïntroduceerd en veroverde de wereld. Andere tablets waren er niet of nauwelijks, ze vormden in elk geval niet een zodanige groep gebruikers dat het grechtvaardigd was daarvoor te ontwikkelen. Op dit moment is dat eigenlijk nog steeds zo, maar dat zal met de komst van het nieuwe Android tablet OS vrijwel zeker veranderen.
Bij de VPRO zijn we aan het experimenteren met RequireJS, een JavaScript module (en bestand) lader gebaseerd op de CommonJSAsynchronous Module Definition API. RequireJS helpt ons onze JavaScripts gestructureerder en herbruikbaarder te ontwikkelen. Versie 0.2 is vandaag gelanceerd, “stronger, faster, and prettier”, aldus ontwikkelaar James Burke. Nog geen 1.0, dus experimenteren blijft het, maar wij zijn er voor aan het warm lopen.
De VPRO host sinds gisteren een mirror van Wikileaks. Zo’n mirror opzetten kan op meerdere manieren. Het is mogelijk om een mirror op te zetten die automatisch wordt bijgewerkt. We hebben ervoor gekozen om dat niet te doen, maar in plaats daarvan een statische kopie te maken.
Er zijn verschillende goede open source pakketten waarmee dat heel simpel te doen is. De meest bekende is wget, hiermee kan je met de ‘-m’ optie een mirror maken. wget staat standaard op de meeste Linux en Mac systemen geinstalleerd. In een terminal tik je simpelweg:
wget -m "http://www.example.com"
In ons geval werkte dat alleen niet. De paden op de site gaan er van uit dat ze op een domein draaien (www.wikileaks.org), en wij draaien onder een subfolder (files.vpro.nl/wikileaks). Er zijn wel opties om dat te corrigeren maar uiteindelijk hebben we gebruik gemaakt van httrack wat nog simpeler werkt.
Httrack is er overigens ook in GUI versies voor mensen die de command line niet beheersen.
De man achter de documentatie van MySQL werkt sinds kort voor CouchOne en er is nu een preview-versie van de documentatie van de CouchDB API online te vinden.
Dit is het CMS wat de VPRO nu voor veel van haar websites gebruikt. Nieuwe mogelijkheden zijn onder andere om revisies van documenten naast elkaar te bekijken.
“Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js (orRuby), but without extending any of the built-in JavaScript objects. It’s the tie to go along with jQuery’s tux.”