Gebruik van het streams script

Dit document beschrijft het gebruik van het zgn. “streams script” aka http://cgi.omroep.nl/cgi-bin/streams

Het streams script is de redirector voor de on-demand streaming omgeving. Indien er op websites of in players links naar streaming media content nodig zijn, dan dienen deze niet direct naar de mediaservers te wijzen, maar inplaats daarvan naar een redirector, zijnde het streams script. Die redirector bepaalt bij elk inkomend request wat de meest geschikte server is om het mediabestand uit te serveren (bv meest populaire content door de snelste servers laten uitserveren) en genereert vervolgens een redirect naar die betreffende server.

In dit document wordt uitgelegd hoe het streams script gebruikt kan worden om redirects naar mediabestanden te genereren en hoe extra functionaliteit zoals GeoIP en hotlink bescherming gebruikt kan worden.

NPO ICT biedt twee omgevingen om on-demand mediacontent uit te spelen:

  • streaming
  • contentplatform

Het content platform is http, progressive-download. De streaming omgeving is via streaming protocollen (mms en rtsp) uitserveren van windowsmedia, quicktime en realmedia content.

Beide omgevingen werken via een redirector, waarbij de client aan de redirector vraag wat de uiteindelijke url naar de media content is. In het contentplatform zit een interne redirector (dwz je roept content.omroep.nl aan alsof het een gewone webserver is en krijgt dan “toevallig” een http redirect naar de uiteindelijke url terug) De streaming omgeving heeft een externe redirector, nl het streams script. Dit document beschrijft wat het streams script precies is en hoe het aangesproken kan worden om de gewenste redirects naar de mediacontent te genereren.

De streaming omgeving beslaat 4 platformen:

  • windowsmedia (via mms/rtsp uitserveren van wmv bestanden)
  • quicktime (via rtsp uitserveren van mp4 bestanden)
  • realmedia (via rtps uitserveren van rm bestanden)
  • flash (via rtmp uitserveren van flv bestanden)

Het streams script is de centrale ingang voor het windowsmedia, quicktime en realmedia platform. Vooralsnog loopt flash niet via een redirector.

Basis functionaliteiten van het streams script zijn:

  • genereren van redirects naar de meest geschikte uitspeelservers
  • verzorgen van load balancing over de uitspeelservers
  • verzorgen van GeoIP afscherming
  • verzorgen van hotlink protectie

Merk op dat allerlei concepten van het streams script 1-op-1 terugkomen in de download omgeving, waar ook sprake is van scheiding tussen een redirector een een aantal uitspeelservers. Kijk dus vooral met een scheef oog ook naar de Download documentatie

Normaliter is de aanroep van het streams script diep verborgen in de ingewanden van hogere lagen. Neem bijvoorbeeld player.omroep.nl Deze kan media content afspelen door te refereren aan een afleverings id (player.omroep.nl?aflID=XXXXXX)

Wat er gebeurt is dat de player werkt op basis van een database die afleverings ID's kan vertalen naar paden op de streaming omgeving (clips) Vervolgens genereert de player een link naar het streams script met als parameter de gevonden clip.

Op hoger niveau (Nebo, UG, players) heb je normaliter dus nooit iets met het streams script te maken; dat zit verstopt in de Nebo / player code.

Echter, als je nou een ontwikkelaar van Nebo bent of als je nu zelf buiten de centrale players om links naar de streaming omgeving wilt genereren dan moet je direct met het streams script praten en is deze documentatie van belang.

Onderstaand voorbeeld demonstreert wat er precies gebeurt indien er via het streams script aan een stukje media content gelinkt wordt. Als voorbeeld nemen we het bestandje genaamd “/test/wilhelmus.mp3”

Eenmalig moet het bestand ge-upload worden naar de streaming omgeving

  • om het bestand te uploaden wordt er geconnect (b.v. via ftp) met upload.omroep.nl
  • en wordt de root van de on-demand streaming omgeving gekozen.
  • deze is altijd te vinden onder het pad /e/ap/media
  • maar vaak is er in de ftp inlog directory ook een link naartoe welke rmfiles of wmfiles heet.
  • eenmaal in de root wordt het bestand geplaatst onder /test/wilhelmus.mp3

Eenmalig moet in een website of in een player een link naar dit bestand opgenomen worden. Dit loopt via het streams script en in z'n simpelste vorm ziet dat er zo uit:

Vervolgens komen er bezoekers op de website. Wat gebeurt er nu?

  • een bezoeker klikt op bovenstaande link
  • dat genereert een hit op het streams script
  • het streams script zoekt uit welke media server dit bestand het beste uit kan serveren
  • en genereert een redirect (bijvoorbeeld in de vorm van een on the fly gegenereerd ASX bestandje) naar de desbetreffende uitspeelserver

Zo'n ASX bestandje zou er ongeveer zo uit kunnen zien:

<ASX version = "3.0">
<ENTRY>
<Ref href =
"mms://media.omroep.nl/public/ug-od/bobo03/1/media/test/wilhelmus.mp3?wmt=4ad5e411&wmhash=d52a1c2"/>
</ENTRY>
</ASX>

Hierna volgen nog de volgende acties:

  • de browser ziet dat er een ASX bestand terugkomt en start indien nodig een mediaplayer om dit af te spelen
  • de mediaplayer vraagt vervolgens de echte stream op bij de uitspeelserver die in het ASX bestand genoemd staat
  • en vervolgens kan de stream afgespeeld worden

In bovenstaand voorbeeld werd een ASX bestand gegenereerd. Dat is de default voor indowsmedia streams. Voor Quicktime wordt er smil gegenereerd en voor RealMedia wordt alleen de kale redirect link gegenereerd.

De gegenereerde urls kunnen we nog nader onder de loupe houden. Nemen we

mms://media.omroep.nl/public/ug-od/bobo03/1/media/test/wilhelmus.mp3?wmt=4ad5e411&wmhash=d52a1c2

dan valt die url op te delen in de volgende componenten:

protocol://server/prefix/clip?parameters
Naam Omschrijving Voorbeeld
protocol manier waarop de content uitgeserveerd wordt. B.v. mms of rtsp mms
server de server die de content uit gaat serveren media.omroep.nl
prefix extra string om b.v. publishing points in een windows media server te kunnen benoemen /public/ug-od/bobo03/1/media
clip de padnaam van het uit te serveren bestand /test/wilhelmus.mp3
parameters extra parameters o.a. om het request te kunnen valideren wmt=4ad5e411&wmhash=d52a1c2

In de gegenereerde url komen dus onderdelen terug die in het oorspronkelijke request zaten (nl de clip die uitgespeeld moet worden), maar ook een hele rits aan onderdelen die het streams script zelf “bedacht” heeft (protocol, server, prefix en parameters) en die afhankelijk zijn van zaken als de populariteit van een clip en de inrichting en beschikbaarheid van uitspeelservers. In de toekomst kan hier bijvoorbeeld ook Content Delivery Network (CDN) functionaliteit bijkomen, dat als er herkend wordt dat een request vanuit het netwerk van een specifieke ISP komt en deze ISP heeft een eigen uitspeelserver staan, dat er dan geredirect kan worden naar die server inplaats van naar een eigen NPO server.

Al met al vervult het streams script een redelijk complexe taak en het is dus af te raden om buiten het streams script om te werken. Door het streams script te gebruiken is het zeker dat de URLs die gegenereerd worden ook werkelijk leiden tot afspeelbare content.

Het streams script fungeert dus als redirector. Dat betekent dat het een zgn. “first level” url vertaalt naar een “second level” url. In bovenstaand voorbeeld werd de “first level” url

http://cgi.omroep.nl/cgi-bin/streams?/test/wilhelmus.mp3

vertaald naar naar de “second level” url:

mms://media.omroep.nl/public/ug-od/bobo03/1/media/test/wilhelmus.mp3?wmt=4ad5e411&wmhash=d52a1c2

waarbij die second level url verpakt was als een ASX bestandje.

Onderweg zijn daarbij een aantal keuzes gemaakt:

  • naar welk streaming platform moet dit request geredirect worden; we hebben er drie: windowsmedia, quicktime en realmedia
  • hoe moet de redirect verpakt worden, als ASX, SMIL of niet verpakken

Deze keuzes worden gemaakt op basis van de extensie van het opgevraagde bestand:

platform extensies
windowsmedia *.asf, *.wmv, *.wma, *.mp3
realmedia *.rm, *.ra
quicktime *.mp4, *.m4v, *.mov, *.qt, *.3gp, *.3gpp

Bij een extensie niet uit bovenstaand lijstje wordt er een redirect naar het quicktime platform gegenereerd.

Het gekozen platform bepaalt vervolgens de manier van inpakken:

platform inpakmethode
windowsmedia ASX
quicktime SMIL
realmedia kale url (dwz niet ingepakt)

In het streams script zit functionaliteit om uw content te beschermen tegen ongeauthoriseerd of out-of-context afspelen.

Omdat de content via een streaming protocol uitgeserveerd wordt is er al een zeker mate van bescherming tegen ongeauthoriseerd downloaden (“streaming content is niet downloadable”) Dat is niet helemaal waar, want sommige media players hebbent egenwoordig gewoon een “save” knop om gestreamde content op de lokale harde schijf op te kunnen slaan. Maar, het is minder aantrekkelijk dan progressive download, omdat er alleen in real time opgeslagen kan worden. Dwz het duurt 1 uur om een programma van 1 uur op te slaan. Dit in tegenstelling tot progressive download waarbij de tijd die het duurt om een programma op te slaan geen 1-op-1 relatie heeft met de duur van een programma.

Een streaming protocol alleen is dus niet zaligmakend, vandaar dat er extra functionaliteit is toegevoegd:

  • GeoIP afscherming
  • Hotlink bescherming

Deze vormen van afscherming vinden plaats in de redirector en worden in de volgende secties nader toegelicht. Maar, omdat dat redirector alleeen urls genereert en zelf geen content uitserveert zou het voor een kwaadwillende dus mogelijk zijn om die second level url op te slaan en deze te distribueren. (scenario: werk om GeoIP heen door via een .nl adres een GeoIP afgeschermd bestand op te vragen en de second level url zou dan overal ter wereld gebruikt kunnen worden)

Om dit beveiligingslek in de second level urls op te vangen is hier extra bescherming op aangebracht. In bovenstaand voorbeeld kwamen opeens twee extra parameters naar voren:

wmt=4ad5e411&wmhash=d52a1c2

Deze worden gegenereerd door de redirector en vervolgens gevalideerd door de uitspeelserver. De redirector en uitspeelserver delen een shared secret. De redirector genereert een hash (“wmhash”) op basis van een tijdscode (“wmt”), de opgevraagde clip en het shared secret. De uitspeelserver valideert de meegekregen hash op basis van de meegegeven tijdscode (“is de tijdscode nieuw genoeg en niet van drie weken geleden”) en kijkt of de meegegeven hash overeenkomt met wat ie zelf zou genereren op basis van diezelfde tijdscode, clip- en shared secret.

Nu kan een kwaadwillende dus nog steeds een second level url opvragen, maar omdat deze url maar zeer beperkt houdbaar is, heeft het geen nut om deze op een website te plaatsen.

Dit mechanisme is een second level hotlink bescherming; niet te verwarren met de first level hotlink bescherming welke hieronder uitgelegd wordt.

Het idee is dat er first level (dwz in de redirector) verschillende vormen van afscherming ingebouwd kunnen gaan worden; terwijl er second level slechts 1 uniforme vorm van afscherming nodig is.

Het is mogelijk om op bepaalde delen van het streaming platform GeoIP afscherming in te laten stellen.

Hiertoe kan een verzoek bij de NPO Servicedesk ingediend worden. In het verzoek moet aangegeven worden:

  • Welk deel van GeoIP afscherming voorzien moet worden. B.v.

/xrtv/clips/afgeschermd

  • Voor welke regio de GeoIP afscherming geldt. Dit kan uitsluitend op

landen niveau. B.v. Nederland of Nederland+Antillen.

  • Een redirect url waar naar verwezen kan worden indien men niet

door de geoip check komt. Bijvoorbeeld: http://www.xrtv.nl/geo-sorry-page.html

Nadat dit ingesteld is zullen alle requests op content onder http://cgi.omroep.nl/cgi-bin/streams?/xrtv/clips/afgeschermd tegen een GeoIP check aangehouden worden. Slaagt de check dan wordt men geredirect naar de eigenlijke content. Faalt de test dan gaat de redirect naar http://www.xrtv.nl/geo-sorry-page.html

Het is mogelijk om op bepaalde delen hotlink afscherming in te laten stellen. Met hotlink afscherming kan ervoor gezorgd worden dat er niet meer direct vanaf een externe site naar bepaalde content via het streams script gelinked kan worden. Links naar deze content worden alleen gehonoreerd indien er een juiste code meegegeven wordt die berekend is op basis van een geheim password, een timestamp en het pad naar de content. Op deze manier kan ervoor gezorgd worden dat b.v. alleen vanuit uw eigen website gelinkt kan worden naar deze content, om er zeker van te zijn dat de content in de gewenste context getoond wordt.

Het mechanisme werkt op basis van zgn tokens. Een token is een md5 hash van de concatenatie van:

  • een geheime string
  • het pad van de te downloaden content
  • een timestamp in hex

Gewapend met een token en een timestamp in hex kan er als volgt aan de content gelinked worden:

http://cgi.omroep.nl/cgi-bin/streams?pad/naar/clip.wmv&md5=$token&t=$t_hex

Hieronder is een stukje voorbeeld code in php voor het genereren van de urls. Voorbeelden in andere programmeertalen staan <url url=“http://trac.lighttpd.net/trac/wiki/Docs:ModSecDownload” name=“op de website van lighttpd”>

<?php
$secret = "heelgeheimpassword";
$uri = "/xrtv/clips/afgeschermd/file.wmv";
$streamsscript = "http://cgi.omroep.nl/cgi-bin/streams";
 
$t_hex = sprintf("%08x", time());
$token = md5($secret.$uri.$t_hex);
$url = sprintf("s%?s&md5=%s&t=%s", $streamsscript,$uri,$token,$t_hex);
 
printf('<a href="%s">%s</a>', $url, $url);
?>

Bij de NPO Servicedesk kan een verzoek ingediend worden om bepaalde delen van download van hotlink bescherming te voorzien. In het verzoek moet aangegeven worden:

  • Welk deel van hotlink bescherming voorzien moet worden. Bijvoorbeeld

/xrtv/clips/incontextonly

  • Het secret dat gebruikt wordt voor het genereren va het token

(dit secret moet tegelijkertijd aan beide kanten bekend zijn en kan dus niet zomaar aan een van beide kanten gewijzigd worden!)

  • Een timeout die aangeeft hoe lang de tijdelijke urls geldig

mogen blijven

  • Een optionele pagina waarheen verwezen kan worden als iemand een ongeldige

pagina bezoekt

Nadat dit is ingesteld zullen links voor content onder http://cgi.omroep.nl/cgi-bin/streams?xrtv/clips/incontextonly alleen gehonoreerd worden indien de correcte md5 hash en timestamp meegegeven worden. Requests met verkeerde waardes voor de md5 hash of requests op links waarvan de timeout verstreken is krijgen een “HTTP 403 Forbidden” statuscode terug.

FIXME: onderstaande beschermings methode is helaas nog niet beschikbaar in het streams script. In een volgende release wordt dit wel mogelijk.

In sectie Hotlink bescherming wordt uitgelegd hoe op bepaalde delen van de content ervoor gezorgd kan worden dat er niet meer vanaf externe (dwz ongeauthoriseerde) sites naar gelinkt kan worden. Deze stijl van hotlink bescherming heeft ook een tijdscode in zich en hier zou het dus ook kunnen gebeuren dat een browser te lang op een URL zit, waardoor deze niet meer geldig is op het moment dat ie opgevraagd wordt.

Een oplossing in dit geval is een challenge-response protocol.

De gedachte hier is dat we in de redirector state bij gaan houden en op basis van die state kunnen besluiten om na een redirect wegens timeout een nieuwe redirect te maken. De hotlink bescherming gebeurt hier dan niet door het maken van een /secure url, maar door een challenge/response conversatie. Inplaats van 1 request zijn er nu 2 requests; eerst een request om een challenge op te vragen, en daarna pas het “echte” request op de eigenlijke data, waar in het eigenlijke request (“geef mij clip x”) ook een response op de challenge zit.

De eerste stap is dat er vantevoren wordt ingesteld dat er op een bepaald gedeelte van de content challenge-response authenticatie plaats moet vinden. Hiertoe kan een verzoek bij de NPO Servicedesk ingediend worden. In het verzoek moet aangegeven worden:

  1. De prefix van de content die beschermd moet worden (b.v. /xrtv/clips/afgeschermd)
  2. Hoeveel maal een afgeschermde URL opgevraagd mag worden na een succesvolle challenge-response dialoog (default 1)
  3. Of er een IP check plaats moet vinden die kijkt of de aanvrager van de challenge hetzelfde IP adres heeft als de aanvrager van de content (default true)
  4. een geheime string die wordt gebruikt om een response te kunnen maken op basis van een gegeven challenge
  5. een redirect url waarnaartoe verwezen moet worden indien gepoogd wordt de content op te vragen zonder dat daar een succesvole challenge-response dialoog aan vooraf is gegaan

Nadat bovenstaande zaken zijn ingesteld werkt het als volgt:

De challenge is op te vragen door een extra parameter “getchallenge” mee te geven. Bijvoorbeeld:

http://cgi.omroep.nl/cgi-bin/streams?/xrtv/clips/afgeschermd/file.wmv&getchallenge

Deze levert een id en een challenge, welke zowel in de headers als in een stukje xml terugkomen. De headers zijn

X-Id: [het id]
X-Challenge: [de challenge]

De xml ziet er zo uit

<xml>
<id>[het id]</id>
<challenge>[de challenge]</challenge>
</xml>

Vervolgens moet uw applicatie de response uitrekenen en samen met het id aan download geven. De response is de md5 hash van de geheime string, de opgevraagde clip en de challenge. In php zou het er zo uit zien

$secret = "heelgeheimpassword";
$uri = "/xrtv/clips/afgeschermd/file.wmv";
$challenge = "2a9f101b"; # de challenge zoals die uit ?getchallenge kwam

$response = md5($secret . $uri . $challenge);

Het doorgeven van het id en de response gaat met de id en response parameters. Als in:

http://cgi.omroep.nl/cgi-bin/streams?/xrtv/clips/afgeschermd/file.wmv&id=$id&response=$response

Dit request wordt door de downloadserver gevalideerd en indien de validatie slaagt volgt er een redirect naar de eigenlijke content.

soms is het gewenst om niet een heel bestand af te spelen, maar slechts een gedeelte ervan. Dit kan geregeld worden met Start en Stop parameters. Hiermee kan aangegeven worden op welke tijscodes moet worden begonnen en geeindig met afspelen. Er worden drie parameters herkend:

Parameter Type
start HH:MM:SS
end HH:MM:SS
duration HH:MM:SS

Het is mogelijk om of een “end” danwel een “duration” parameter te gebruiken, niet allebei tegelijk. Zonder start parameter wordt vanaf het begin afgespeeld en zonder end of duration parameter wordt tot het eind afgespeeld.

Het is mogelijk om ASX of SMIL te genereren waar in een keer een lijstje van af te spelen bestanden benoemd staat (playlist). Hiervoor is een speciale aanroep van het streams script nodikg, nl met de list=… en dir=… parameters.

Indien er meerdere cliops afgespeeld moeten worden kan dat door aan het streams script een komma gesepareerd lijstje mee te als

list=clip1,clip2,..

Voorbeeld:

http://cgi.omroep.nl/streams?list=/duckstad/kwik.wmv,/duckstad/kwek.wmv,/duckstad/kwak.wmv

Indien alle clips in dezelfde directory staan (“/duckstad”) dan kan er een parameter “dir=…” meegegeven worden en dan worden de aangegeven bestanden relatief t.o.v. die directory genomen. De dir= en list= parameters moeten geschedeiden worden door een puntkomma (;) zie de volgende sectie “Syntax”

Voorbeeld:

http://cgi.omroep.nl/streams?dir=/duckstad/;list=kwik.wmv,kwek.wmv,kwak.wmv

Het is in theorie mogelijk om via een lijstje naar verschillende platformen te verwijzen (“list=windowsmedia.asf,realmedia.rm,quicktime.qt”) In zo'n geval bepaalt het eerste element in de lijst welk platform en dus ook welk inpak mechanisme (asx/smil/niks) gekozen wordt en worden de resterende clips via dat platform uitgespeeld. Dat gaat dan niet werken, omdat b.v. windowsmedia niks weet van de realmedia container formaten en vice versa. Kortom: geen platformen mixen in lijstjes.

Als er maar 1 bestandje afgespeeld hoeft te worden dan kan er een vrij standaard http style syntax gebruikt worden, met de bekende vraagtekens en ampersands. Maar als er een lijstje van bestanden opgegeven wordt, dan is dat anders omdat er per af te spelen bestand ook weer parameters doorgegeven moeten kunnen worden. Verder is er een stuk historie omdat bij realmedia dingen verbatim aan de realserver doorgegeven worden, en dat gaat met vraagtekens en ampersands. Je querystring kan dus vreemd genoeg meerdere vraagtekens bevatten.

In het verleden is ervoor gekozen om (aangezien de ampersand als parameter scheider niet meer beschikbaar was) de puntkomma (;) als principale scheider te gebruiken. Dat leidt tot merkwaardige urls die er niet erg http stijl uitzien.

Reguliere methodes van parameters doorgeven zijn dus:

streams?val
streams?val;var=val;var=val;...
streams?var=val;var=val;var=val;...

waarbij de eerste twee worden geinterpreteerd als

streams?list=val[;derest]

en val op zijn beurt weer ampersands en vraagtekens kan bevatten.

Mogelijke variabelen zijn:

var voorbeeld omschrijving
dir /path/ Geef gemeenschappelijke directory op
list clip,clip,… komma separated lijst van clips
checkqueue0 of 1 Legacy spul, niet gebruiken.
md5 hash tbv hotlink protectie
t hexcode secs sinds 1 jan 1970, in hex representatie

clip is in principe een pad naar een clip + optionele parameters:

      clip=/path[?param&param&param]

In principe worden alle parameters gewoon doorgegeven richting streaming server. Er zijn drie speciale parameters, de start/stop codes:

      start=HH:MM:SS
      duration=HH:MM:SS
      end=HH:MM:SS

Deze worden als zodanig herkend en in geval van windows media en quicktime naar de correcte parameters voor dat formaat herschreven.

Daarnaast zijn tbv hotlink protectie de md5 en t codes. Deze worden ook als zodanig herkend en gebruikt om hotlink protectie op te doen. Ze worden niet doorgegeven aan de uitspeelservers

Voorbeeld urls:

streams?/foo/bar.asf
streams?list=/foo/bar.asf
streams?list=/foo/bar.asf,/baz/bletch.asf
streams?dir=/foo/;list=bar1.asf,bar2.asf
streams?dir=/foo/;list=bar1.asf?var1=x&var2=y,bar2.asf?var1=p&var2=q
streams?dir=/foo/;list=bar1.asf?md5=XXXX&t=TTTT,bar2.asf?md5=YYYY&t=UUUU
streams?/foo/bar.asf&start=00:00:01&end=00:00:34&title=test,/baz/bletch.asf&start=00:12:12&end=00:55:34&title=boe

Voor vragen over download kunt u zich wenden tot de NPO ICT Servicedesk, welke te bereiken is via servicedesk@omroep.nl telefoon 035 67 73 555.

  • streaming/streams-script.txt
  • Last modified: 2019/05/28 10:47
  • (external edit)