Inleiding
De Nederlandse Publieke Omroepen stellen een live stream beschikbaar met 24 uur per dag het laatste nieuws. Deze pagina vereist echter onder Linux nog steeds het gebruik van Adobe Flash. Deze plug-in staat bekend om zijn talloze beveiligingslekken op alle platformen.
Daarom wilde ik graag een manier om de livestream te bekijken in mijn favoriete mediaspeler: VLC, buiten de site en lekke browser-plug-in om.
Update (2)
Vanaf begin 2019 is alle content van de NPO beveiligd met DRM-technologie. Hierdoor is het wel in een browser of via hun eigen app te bekijken, maar niet te voor offline gebruik te downloaden. Jammer, maar helaas.
Update
Het onderstaande script werkt niet meer naar behoren en is per mei 2017 achterhaald. Ik heb inmiddels een opvolger geschreven die voor alle NPO live-streams geschikt is.
Onderzoek
Aldus zocht ik een manier om de video-playlist die door de Flash plug-in wordt
afgespeeld zelfstandig op te roepen. Maar, wat blijkt? De URL van dit
.m3u8
-bestand wordt dynamisch bepaald op het moment van opvragen. Dit werd
toch een stukje complexer dan een simpele URL kopiëren... Met behulp van
FireBug onderzocht ik alle HTTP-verzoeken.
Script
In onderstaand script wordt in de variable PLAYER
de aan te spreken
mediaspeler ingesteld (in dit geval vlc
). Daarna wordt gecontroleerd of de
mediaspeler en cURL geïnstalleerd en toegankelijk zijn. Dan volgt de rest
van het script in vier stappen:
- Als eerste wordt de stream-pagina opgeroepen
- Daarna wordt in het antwoord gezocht naar een URL met de string
callback=?
- Deze callback-URL wordt opgeroepen
- In het antwoord bevindt zich de uiteindlijke
.m3u8
-URL
De cURL
-headers, zoals Host
, User-Agent
, Referer
en Cookie
zijn
rechtstreeks overgenomen van mijn eerste HTTP-verzoek met FireFox en FireBug.
Let met name op de -d
parameter waarin de data wordt meegestuurd (stap 1).
Uiteindelijk wordt de ingestelde mediaspeler gestart met de gevonden URL als argument. De livestream verschijnt nu, zonder gebruik van een internetbrowser of plug-in, desgewenst in volledig scherm.
#!/bin/bash
# Set prefered video player
PLAYER="vlc";
# Check whether the video player is installed
if ! hash "${PLAYER}" 2>/dev/null; then
echo "${PLAYER} is needed for playing back the downloaded playlist. Please
install it, or add it to your PATH.";
exit 1;
fi;
# Check whether cURL is installed
if ! hash "curl" 2>/dev/null; then
echo "cURL is needed for downloading the playlist. Please install it, or add
it to your PATH.";
exit 1;
fi;
# Step 1, request page
STEP1="$(
curl -X POST --silent \
-H "Host: www-ipv4.nos.nl" \
-H "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0)
Gecko/20100101 Firefox/44.0" \
-H "Accept: */*" \
-H "Accept-Language: en-US,en;q=0.5" \
-H "Accept-Encoding: gzip, deflate" \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
-H "Referer: http://nos.nl/livestream/npo-nieuws.html" \
-H "Content-Length: 73" \
-H "Origin: http://nos.nl" \
-H "Connection: keep-alive" \
-d '{"stream":"/live/npo/thematv/journaal24/journaal24.isml/journaal24.m3u8"}' \
--compressed \
\
http://www-ipv4.nos.nl/livestream/resolve/ \
)";
# Step 2, filter response from step 1
STEP2="$(
echo -n ""${STEP1}"" | grep -oP 'http.*?callback=\?' | sed -e 's/\\\//\//g'
)";
# Step 3, request new URL
STEP3="$(
curl -X GET --silent \
-b "balancer%3A%2F%2Flive2cluster=balancer.live2b" \
-H "Host: livestreams.omroep.nl" \
-H "User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:44.0)
Gecko/20100101 Firefox/44.0" \
-H "Accept: */*" \
-H "Accept-Language: en-US,en;q=0.5" \
-H "Accept-Encoding: gzip, deflate" \
-H "Referer: http://nos.nl/livestream/npo-nieuws.html" \
-H "Cookie: balancer://live2cluster=balancer.live2b" \
-H "Connection: keep-alive" \
-d '' \
\
""${STEP2}""
)";
# Step 4, filter response from step 3
STEP4="$(
echo -n ""${STEP3}"" | grep -oP 'http.*?\.m3u8' | sed -e 's/\\\//\//g'
)";
# Start player with the final .m3u8-URL
eval "${PLAYER} ${STEP4} &";
# Exit normally
exit 0;