CouchDB Media API POMS voorziet in een REST API voor het opvragen van media metadata. Deze API wordt gefaciliteerd door Apache CouchDB. Deze metadata is gegroepeerd in zogenaamde documenten per programma, segment en groep. Deze documenten zijn in JSON geformatteerd. Er zijn API-calls voor het opvragen van metadata op basis van het ID van een entiteit en daarnaast zijn er API-calls voor het opvragen van zogenaamde views op deze metadata, waarbij de metadata op andere criteria dan ID beschikbaar wordt gesteld. De API-calls zijn read-only voor afnemers, dus alleen HTTP HEAD en GET requests zijn mogelijk. Er zijn 2 couchdb-databases beschikbaar. De eerste ('poms') is gebaseerd op het 'URN' van de objecten en de tweede ('media') op het 'MID'. We houden in deze documentatie de tweede aan, aangezien het de bedoeling is dat het 'MID' de leidende identifier wordt voor de objecten in poms. Hostname hackathon-api.omroep.nl Metadata Document API Elk metadata-document is uniek geïdentificeerd door een zogenaamde Uniform Resource Name (URN). Met behulp van de Metadata Document API is het mogelijk om een metadata-document op te vragen op basis van een URN. Dit gaat in het algemeen door een HTTP GET request te doen naar /media/mid. Voorbeelden Het opvragen van het metadata-document voor de MID VPRO_1234 gaat als volgt: GET /media/vpro_1234 Via curl is dat dus: curl http://hackathon-api.omroep.nl/media/vpro_1234 Het opvragen van het metadata-document uit de poms-database gaat dus via de URN. Voor de URN urn:vpro:media:program:3043569 gaat het als volgt: GET /poms/urn:vpro:media:program:3043569 Via curl is dat dus: curl http://hackathon-api.omroep.nl/poms/urn:vpro:media:program:3043569 In beide gevallen zal het antwoord zal er ongeveer als volgt uitzien (vooral het veld _id is anders): "_id": "VPRO_1234",
"_rev": "2-675bf173c434939e28fe696db3186437", "segments": [ "lastmodified": 1304955943340, "embeddable": true, "credits": [ "scheduleevents": [ "start": 1258152900000, "urnref": "urn:vpro:media:program:3043569", "channel": "NED3" "start": 1258537200000, "repeat": "isrerun": true, "value": "" "urnref": "urn:vpro:media:program:3043569", "channel": "NED2" "duration": 1500000, "start": 1262783400000, "repeat": "isrerun": true, "value": "" "urnref": "urn:vpro:media:program:3043569", "channel": "BVNT" "duration": 1500000, "start": 1262826600000, "repeat": "isrerun": true, "value": "" "urnref": "urn:vpro:media:program:3043569", "channel": "BVNT" "type": "BROADCAST", "memberof": [ "index": 14, "added": 1279803937261, "urnref": "urn:vpro:media:group:3153453" "added": 1286527773255, "urnref": "urn:vpro:media:group:5235041" "workflow": "PUBLISHED", "crids": [ "crid://tmp.program.omroep.nl/10304477" "descriptions": [ "id": 3213760, "owner": "BROADCASTER", "value": "De correspondenten gaan op zoek naar nationalisten. Want hoewel de wereld steeds kleiner lijkt te worden, betekent dat niet automatisch dat iedereen zich wereldburger voelt. In de Verenigde Staten stuitte correspondent Kel op een afscheidingsbeweging, die de staat Vermont wil loskoppelen van de rest van het land.",
"type": "MAIN" "id": 3043570, "value": "waarin we naar de wereld kijken door de ogen van lokale filmmakers. Hun verhalen spelen zich vaak buiten de focus van de nieuwsmedia af, maar laten evengoed zien hoe de wereld er anno 2009 voorstaat. Hiermee is Metropolis een crossmediaal podium waarop een eigen, oorspronkelijke vorm van buitenlandberichtgeving gestalte krijgt.", "type": "MAIN" "id": 3213761, "owner": "BROADCASTER", "value": "De correspondenten gaan op zoek naar nationalisten. Want hoewel de wereld steeds kleiner lijkt te worden, betekent dat niet automatisch dat iedereen zich wereldburger voelt. In de Verenigde Staten stuitte correspondent Kel op een afscheidingsbeweging, die de staat Vermont wil loskoppelen van de rest van het land.", "type": "SHORT" "id": 3043571, "value": "Op zoek naar nationalisten. Want hoewel de wereld steeds kleiner lijkt te worden, betekent dat niet automatisch dat iedereen zich wereldburger voelt. Vaderlandsliefde, vlagvertoon en volksvermaak.", "type": "SHORT" "urn": "urn:vpro:media:program:3043569", "creationdate": 1279312893636, "poprogid": "VPRO_1135480", "duration": 1500000, "broadcasters": [ "VPRO" "locations": [ "urn": "urn:vpro:media:location:3043574", "creationdate": 1279312893653, "lastmodified": 1279312893653, "publishstart": 1258155362000, "avattributes": "videoattributes": "height": 180, "width": 180, "aspectratio": "16:9" "avfileformat": "MP4", "bitrate": 200000 "programurl": "http://cgi.omroep.nl/legacy/nebo?/ceres/1/vpro/rest/2009/vpro_1135480/sb.20091113. m4v", "type": "INTERNAL", "workflow": "PUBLISHED" "urn": "urn:vpro:media:location:3043577", "creationdate": 1279312893663, "lastmodified": 1279312893663, "publishstart": 1258155362000,
"avattributes": "videoattributes": "height": 180, "width": 180, "aspectratio": "16:9" "avfileformat": "MP4", "bitrate": 500000 "programurl": "http://cgi.omroep.nl/legacy/nebo?/ceres/1/vpro/rest/2009/vpro_1135480/bb.20091113. m4v", "type": "INTERNAL", "workflow": "PUBLISHED" "urn": "urn:vpro:media:location:3043580", "creationdate": 1279312893675, "lastmodified": 1279312893675, "publishstart": 1258155362000, "avattributes": "videoattributes": "height": 180, "width": 180, "aspectratio": "16:9" "avfileformat": "WM", "bitrate": 200000 "programurl": "http://cgi.omroep.nl/legacy/nebo?/ceres/1/vpro/rest/2009/vpro_1135480/sb.20091113. asf", "type": "INTERNAL", "workflow": "PUBLISHED" "urn": "urn:vpro:media:location:3043583", "creationdate": 1279312893685, "lastmodified": 1279312893685, "publishstart": 1258155362000, "avattributes": "videoattributes": "height": 180, "width": 180, "aspectratio": "16:9" "avfileformat": "WM", "bitrate": 500000 "programurl": "http://cgi.omroep.nl/legacy/nebo?/ceres/1/vpro/rest/2009/vpro_1135480/bb.20091113. asf", "type": "INTERNAL", "workflow": "PUBLISHED" "urn": "urn:vpro:media:location:3043586", "creationdate": 1279312893695, "lastmodified": 1279312893695, "publishstart": 1258155362000, "avattributes": "videoattributes":
"aspectratio": "16:9" "avfileformat": "HTML" "programurl": "http://player.omroep.nl/?aflid=10304477", "type": "EXTERNAL", "workflow": "PUBLISHED" "descendantof": [ "urnref": "urn:vpro:media:group:192119" "urnref": "urn:vpro:media:group:3153453" "urnref": "urn:vpro:media:group:5235041" "images": [ "imageuri": "urn:vpro.image:6363", "urn": "urn:vpro:media:image:3213764", "creationdate": 1279803954876, "height": 113, "lastmodified": 1304955943340, "width": 200, "owner": "BROADCASTER", "type": "PICTURE", "workflow": "PUBLISHED" "episodeof": [ "index": 41, "added": 1279312893943, "urnref": "urn:vpro:media:group:192119" "titles": [ "id": 3213762, "owner": "BROADCASTER", "value": "Eigen volk eerst (Metropolis TV)", "type": "MAIN" "id": 3043587, "value": "Metropolis", "type": "MAIN" "id": 3043588, "value": "Eigen volk eerst", "type": "EPISODE" "avtype": "VIDEO", "avattributes": "videoattributes": "aspectratio": "4:3"
Het metadata-document voor de groep met URN urn:vpro:media:group:1038096 vraag je als volgt op: GET /poms/urn:vpro:media:group:1038096 Het antwoord: "_id": "urn:vpro:media:group:1038096", "_rev": "2-2676ef22b76f36f118303585ea1a2a10", "isordered": false, "lastmodified": 1304878969888, "embeddable": true, "credits": [ "scheduleevents": [ "type": "SERIES", "workflow": "PUBLISHED", "crids": [ "crid://tmp.serie.omroep.nl/1263" "descriptions": [ "id": 1038097, "value": "Entermatie voor heel de natie. Rechtstreeks vanuit GrandCafé Beeks. Techniek: Ted van Lieshout. Presentatie: Toon Spoorenberg en Peer van Eersel.", "type": "MAIN" "urn": "urn:vpro:media:group:1038096", "creationdate": 1271701212561, "broadcasters": [ "VPRO" "locations": [ "descendantof": [ "titles": [ "id": 1038098, "value": "Radio Bergeijk", "type": "MAIN" "avtype": "VIDEO", "images": [] Meer informatie Meer mogelijkheden van de CouchDB Document API vind je op de CouchDB wiki. Houd er rekening mee dat de POMS API's read-only zijn en dus alleen HTTP GET en HEAD requests ondersteund worden. Metadata View API Er zijn enkele zogenaamde views beschikbaar om metadata op andere manieren dan via document-id (MID of URN) op te vragen. Views worden in Apache CouchDB geïmplementeerd met behulp van Map/Reduce: een map-functie en een optionele reduce-functie. Een view is een index die snel te bevragen is. De keys van een view
index zijn JSON-waardes en kunnen naast getallen of strings dus ook JSON arrays zijn (zogenaamde complex keys). Als reduce-functie is voor alle metadata views de sommatie-functie gebruikt, zodat het makkelijk is om op te vragen hoeveel metadatadocumenten er in het resultaat van een view query zitten zonder de metadata zelf op te hoeven vragen. Query parameters Als je geïnteresseerd bent in de metadata-documenten zelf in plaats van het aantal, gebruik dan de query parameters reduce=false en include_docs=true. De query parameter reduce=false zorgt ervoor dat alleen het resultaat van de map-functie geretourneerd wordt en de query parameter include_docs=true zorgt ervoor dat dat de metadata-documenten in het resultaat opgenomen worden. De volledige metadata-documenten zijn namelijk niet in de view index opgenomen om dataduplicatie te voorkomen en schijfruimte te besparen. Zonder de query parameter include_docs=true worden er alleen referenties naar metadatadocumenten geretourneerd. Als dat genoeg is, is het aan te raden om include_docs=true niet te gebruiken. Zie de sectie querying options op de CouchDB wiki voor meer informatie over de beschikbare query-mogelijkheden. Beschikbare views De opbouw van view query URL's is als volgt: /media/_design/media/_view/viewnaam-en-query-parameters Voor de poms-database is het /poms/_design/media/_view/viewnaam-en- QUERY-PARAMETERS In beide database zitten, tenzij anders vermeld, dezelfde views. In veel gevallen zit er ook precies hetzelfde. Tenzij er in de key of value verwezen wordt naar documentids. Dan is het in de 'poms'-database de URN, en in de 'media'-database het MID. Uitzendingen op zender/net en starttijd De naam van deze view is broadcasts-by-channel-and-start en deze index heeft een complexe key met twee elementen. Het eerste element van de complex key is de zender-code, het tweede element de starttijd van een uitzending. Voorbeeld Alle uitzendingen op Nederland 1 die op 14 juni 2011 beginnen: GET /media/_design/media/_view/broadcasts-by-channel-andstart?startkey=["ned1",1308002400000]&endkey=["ned1",1308088800000]&reduce=false&in clude_docs=true Een vergelijkbare view broadcasts-by-net-and-start is er voor 'net' ipv channel. Alles op ZAPP: GET /media/_design/media/_view/broadcasts-by-net-andstart?startkey=["zapp",null]&endkey=["zapp",]&reduce=false
Uitzendingen op omroep en starttijd Er zijn drie views om programma's op omroep en starttijd op te vragen: 1. broadcasts-by-broadcaster-and-start (audio én video) 2. audio-broadcasts-by-broadcaster-and-start (alleen audio) 3. video-broadcasts-by-broadcaster-and-start (alleen video) Het eerste element van de complex key is de omroep, het tweede element de starttijd van een uitzending. Voorbeeld Alle uitzendingen van de VPRO die op 14 juni 2011 beginnen: GET /media/_design/media/_view/broadcasts-by-broadcaster-andstart?startkey=["vpro",1308002400000]&endkey=["vpro",1308088800000]&reduce=false&in clude_docs=true Voorbeeld Alle audio-uitzendingen van de EO die op 14 juni 2011 beginnen: GET /media/_design/media/_view/audio-broadcasts-by-broadcaster-andstart?startkey=["eo",1308002400000]&endkey=["eo",1308088800000]&reduce=false&includ e_docs=true Voorbeeld Alle video-uitzendingen van de NTR die op 14 juni 2011 beginnen: GET /media/_design/media/_view/video-broadcasts-by-broadcaster-andstart?startkey=["ntr",1308002400000]&endkey=["ntr",1308088800000]&reduce=false&incl ude_docs=true Uitzendingen op genre en starttijd Er zijn drie views om programma's op genre en starttijd op te vragen: 1. broadcasts-by-genre-and-start (audio én video) 2. audio-broadcasts-by-genre-and-start (alleen audio) 3. video-broadcasts-by-genre-and-start (alleen video) Het eerste element van de complex key is het genre, het tweede element de starttijd van een uitzending. Voorbeeld Alle uitzendingen in het genre 'Documentaire' die op 14 juni 2011 beginnen: GET /media/_design/media/_view/broadcasts-by-genre-andstart?startkey=["documentaire",1308002400000]&endkey=["documentaire",1308088800000] &reduce=false&include_docs=true Voorbeeld Alle audio-uitzendingen in het genre 'Drama' die op 14 juni 2011 beginnen: GET /media/_design/media/_view/audio-broadcasts-by-genre-andstart?startkey=["drama",1308002400000]&endkey=["drama",1308088800000]&reduce=false& include_docs=true
Voorbeeld Alle video-uitzendingen in het genre 'Drama' die op 14 juni 2011 beginnen: GET /media/_design/media/_view/video-broadcasts-by-genre-andstart?startkey=["drama",1308002400000]&endkey=["drama",1308088800000]&reduce=false& include_docs=true Onderdelen van groepen Er zijn verschillende views beschikbaar voor het opvragen van onderdelen van groepen: 1. by-group (alle onderdelen van een groep) 2. episodes-by-group (In 1.8 vervangen door episodes-by-parent-and-index) 3. episodes-by-parent-and-index (alle episodes met hun aflevering nummer). Sinds poms 1.8 4. by-ancestor-and-type (alle onderdelen van een groep of ander mediaobject, ook recursief, met daarbij ook het type van het onderdeel). Sinds poms 1.7 5. by-ancestor-and-first-broadcast-time (alle onderdelen van een groep of ander mediaobject, ook recursief geordend op eerste uitzendtijdstip). 6. by-ancestor-and-sortdate (alle onderdelen van een groep of ander mediaobject, ook recursief geordend op uitzend- of aanmaakdatum bij niet uitzendingen). Sinds poms 1.8 7. by-parent-and-type (alle onderdelen van een groep of ander mediaobject, niet recursief, met daarbij ook het type van het onderdeel). Sinds poms 1.7 De view key is de URN of de MID van de groep. Voorbeeld Alle onderdelen van de groep POMS_VPRO_1234: GET /media/_design/media/_view/bygroup?key="poms_vpro_1234"&reduce=false&include_docs=true Voorbeeld De episodes van het seizoen S_VPRO_1234 kun je als volgt opvragen: GET /media/_design/media/_view/episodes-bygroup?key="s_vpro_1234"&reduce=false&include_docs=true Voorbeeld Alle tracks van de groep POMS_S_VPRO_152958: GET media/_design/media/_view/by-ancestor-andtype?reduce=false&key=["poms_s_vpro_152958","track"] Alle media, onafhankelijk van het type zou zo gaan: GET media/_design/media/_view/by-ancestor-andtype?reduce=false&startkey=["poms_s_vpro_152958"]&endkey=["poms_s_vpro_152958",]& inclusive_end=true Laatste uitzending van een Serie binnen bepaald tijd venster: GET /media/_design/media/_view/by-ancestor-and-first-broadcasttime?startkey=["poms_s_kro_099623",1244733000000]&endkey=["poms_s_kro_099622,121198 6800000]&reduce=false&limit=1&descending=true
Media op tag De naam van deze view is by-tag en deze index heeft als key simpelweg een string: de tag. Voorbeeld Alle media met de tag aap: GET /media/_design/media/_view/by-tag?key="aap"&reduce=false&include_docs=true Media op type en titel (beschikbaar sinds POMS 1.7) De naam van deze view is media-by-type-and-title. De key is het type gevolgd door de lexicografische titel. De lexicografische titel is de main title, tenzij er expliciet een lexicografische titel is ingevuld. De titel is ook helemaal in kapitalen. Voorbeeld Alle albums waarvan de titel met een D begint: GET /media/_design/media/_view/media-by-type-andtitle?startkey=["album","d"]&endkey=["album","e"]&reduce=false Media op UID De naam van deze view is by-uid en deze index heeft als key een string: het Unique ID (UID). Voorbeeld Het mediaobject met het UID TROS_1059372: GET /poms/_design/media/_view/byuid?key="tros_1059372"&reduce=false&include_docs=true Deze view is niet beschikbaar in de 'media' database. Daarin is deze view dus overbodig, omdat wat we hier de UID noemen gewoon de MID is. Voorspellingen (beschikbaar sinds POMS 1.6) Er is een view die alle objecten teruggeeft die 'voorspeld' zijn. Dat wil zeggen dat ze nog niet afspeelbaar zijn, maar dat naar verwachting wel worden. Zodra ze echt afspeelbaar zijn geworden, verdwijnen ze weer uit deze view GET /media/_design/media/_view/predictions-by-channel-and-start?reduce=false Media op type, sortdate en kanaal Geeft alle obecten terug op 'type', sortdate (wat voor uitzendingen de eerste uitzenddatum is), en 'kanaal' (null als er geen uitzendingen waren). De uitzendingen tussen 1 april en 1 juni 2013:
GET media/_design/media/_view/by-type-and-sortdate-andchannel?reduce=false&startkey=["broadcast",1364792400000,null]&endkey=["broadcast", 1370062800000, Afspeelbare objecten (beschikbaar sinds POMS 1.5) De volgende views maken het vinden van 'afspeelbare' media eenvoudiger: 1. media-with-locations-by-broadcaster-and-first-broadcast-time (alle media met locaties gesorteerd op omroep en uitzendtijd) 2. media-with-locations-by-broadcaster-avtype-location (alle media met locaties gesorteerd op omroep en type) Meer informatie Meer informatie over de CouchDB View API is te vinden op de CouchDB wiki. Houd er rekening mee dat de POMS API's read-only zijn en het dus niet mogelijk is om als afnemer zelf views toe te voegen of te bewerken. De sectie over querying options zal waarschijnlijk het interessantst zijn. Meer informatie over hoe keys sorteren in een view index (view collation) vind je op de CouchDB wiki. Beschrijving van het metadata-model Voor tijdstippen wordt gebruik gemaakt van timestamps die het aantal milliseconden sinds 1 januari 1970 00:00:00 GMT representeren. De meeste programmeertalen bieden kant-en-klare methoden om een tijdstip te converteren naar een dergelijke timestamp. In zowel Java als JavaScript kan dit bijvoorbeeld als volgt: Date.parse("14 Jun 2011 00:00:00 GMT+0200") ===> 1308002400000 Voor de lengte van mediafragmenten (duration) worden aantallen milliseconden gebruikt. In het algemeen zijn de documenten in couchdb JSON representaties van onze objecten. Er is daarvan een XSD beschikbaar. Hierin kun je in principe precies zien wat er allemaal kan voorkomen. Daarbij moet worden opgemerkt dat in couchdb slechts program's, group's en segment's zitten. Changes-feed Als je op de hoogte gesteld wil worden van alle gepubliceerde wijzingen kun je daarvoor de couchdb changes feed gebruiken. Dat kan op verschillende manieren
gebruikt worden (zie de couchdb-documentatie), maar de meest recht-toe-recht-aanmethode is alle wijzingen opvragen sinds een zeker versie-nummer (dat je dan zelf kunt onthouden om te weten tot hoever je bij bent) GET media/_changes?since=3426000&limit=10&include_docs=true dit ondersteunt dus ook parameters als 'include_docs', 'limit' en 'descending' net als gewone views. In het resultaat vind je ook deletes, er zit dan een 'deleted: true' jsonattribuut op de geretourneerde objecten.