4oD (Channel4 on Demand) plugin development
#1
Now that XBMC works with the new librtmp it is possible to stream rtmpe content from the 4oD website to a build of XBMC with the appropriate patch.

I've started on a plugin (I used this as a starting point) to look through their site. Currently it looks at the shows listed at http://www.channel4.com/programmes/4od for the current day. It returns all of the videos for those TV Shows. It retrieves Thumbnails, Fanart and media information for the shows and episodes and puts them together rather well in Library Mode. If you use PM3.HD it will default to the List view (rather than the usual Full List view) for the episodes.

The first 3 settings (under Image Acquisition) are the only ones that work. The others are just for show at the moment.

The one stumbling point at the moment is I haven't yet found a way to retrieve/generate the needed authkey. If I put in an authkey previously generated by rtmpsrv it works.

It's rather slow at retrieving the data at the moment and the code needs to be worked over, but it's a start.

To test:
  • Run the plugin and choose a TV Show from the generated list
  • Run rtmpsrv - you need to use ak.securestream.channel4.com as the host (see here for a guide on using rtmpsrv)
  • Go to the 4oD website in your browser and choose an episode from your TV Show and start playing it
  • After all of the adverts have finished (Angry) rtmpsrv should start outputting some rtmpe links
    Example rtmpsrv output:
    Code:
    rtmpdump -r "rtmpe://ak.securestream.channel4.com:1935/4oD/?ovpfv=1.1&[b]auth=da_bfa9bycrdnc6c2aUbnc.cjcDcqcecEcd-bl8zN.-eS-ixN-n9rhm8sCovqenLm7seteqeoBkdnnpGlSonqdnJsFofqfnHm8tstCqEoEkDnqo9lEncr6n4seo6q4mfm8[/b]&aifp=v002&slist=assets/CH4_08_02_16_47867018001002_001.mp4" -a "4oD/?ovpfv=1.1&[b]auth=da_bfa9bycrdnc6c2aUbnc.cjcDcqcecEcd-bl8zN.-eS-ixN-n9rhm8sCovqenLm7seteqeoBkdnnpGlSonqdnJsFofqfnHm8tstCqEoEkDnqo9lEncr6n4seo6q4mfm8[/b]&aifp=v002&slist=assets/CH4_08_02_16_47867018001002_001.mp4" -f "WIN 10,0,45,2" -W "http://www.channel4.com/static/programmes/asset/flash/swf/4odplayer-4.49.7.swf" -p "http://www.channel4.com/programmes/the-cleveland-show/4od#3069688" -C Z: -y "mp4:assets/CH4_08_02_16_47867018001002_001.mp4" -o CH4_08_02_16_47867018001002_001.mp4
  • Copy the auth string from rtmpsrv's output and add it to default.py at line 237 (auth='da_blahblah')
  • Don't forget to change your hosts file back to normal!
  • Save default.py and Click on your TV Show in the XBMC plugin (this will generate the episode list with the chosen authkey)
  • Click on the episode you chose before and enjoy!

Alternatively you can use GetFLV to get the authkey but it's a paid-for program.

My latest code is here:
4oD_20100518_0852.rar
This fixes:
  • Sorting (only in library mode - it's still broken in file mode [can't change sort direction, order locked to descending)
  • Shows missing airdates [A inaccurate hack atm - but at least you get the episodes listed]
  • Episodes with no Series OR Episode now display
  • Series with multiple Season now display correctly
  • Rubbish Episode Name detection has been improved

Please report any TV Shows that do not work correctly.

Older code:
4oD_20100517_2253.rar
Reply
#2
If you want to edit it so that it only shows the 1st TV Show and the 1st Episode show up (for testing) then change the following lines:
TV Show list count - default.py Lines 53 and 61:
Change
Code:
for url_orig, name in urls:
to
Code:
for url_orig, name in urls[0:1]:

Episode list count - default.py Line 172:
Change
Code:
for assetid in assetids:
to
Code:
for assetid in assetids[0:1]:

You can change the 1 to a different number to limit to the first n TV Shows/episodes.
Reply
#3
Taken from http://forum.xbmc.org/showthread.php?tid=51322&page=16 where I hijacked the Iplayer thread a little too much.

exobuzz Wrote:The auth key will either be generated from a user/password or be given by the service when a request for a file is made. For the IPlayer the auth keys are given in some xml provided by the bbc.

eddebaby Wrote:Thank you. I guess 'authString' is an XML field then. No wonder I couldn't find it in the code. The problem is the token field given in the xml file from 4oD is drastically different in format to the authtoken used in the rtmpe stream.

XML <token> field (http://www.channel4.com/programmes/how-i...et/3067315)
Code:
<token>MlLH/9DMq8EDwTI0vQuuk+B1knpSn2QUXDrV8OHQ86cX1NG1JLH21/TA4aChNrRT2Z+5Lu42Bf0A
Kkr0QRj862ADJt+EoV8kdRdxMmUANIlj1H2Ghvpwc7BNOpAyhUqT2OJSTBpaL8iwuYPprFkyPej2
52f6fZbGEI3QDIZY6AKTwlH14FHhLA==
</token>

Example actual authtokens:
Code:
da_a1dVaYdXaEcXcWbfdwdibdbncBakajbU-bl76LM-eS-gAT-kttDkpt7swpem8srnunsr3k2tTqvnsq7kYsckFtJsDphmMsfn6ndrbk3sfp8noqdkVtSkIt9sCoem2sw
da_cBb0bfbmdFbuaodPcPb0aLc4aLdka1bZ-bl78Zd-eS-kyO-pWmyl2k7oyldlxmnrVparJkqnIl2r4mvpCmzlnjbosl4kcmwr8qDr3k3m8lZrUmep3l9k8kZoWkelYmu

Any ideas? Does it need to be decrypted?


exobuzz Wrote:Could easily need to be modified in some way.

Is there any other software that has the source that can stream them like get_iplayer for example? If so, worth a check. Also worth snooping traffic when playing them in the browser, so see what is sent/received to make sure nothing has been missed.

eddebaby Wrote:wireshark hadn't really turned up very much, but I just gave URL Snooper a go and after checking all of the urls from the 4oD server this caught my eye:
http://www.channel4.com/static/global/js...macsha1.js

It looks like it's creating the auth key, hopefully from the token in the xml. I'm pretty new to javascript but hopefully the answer is in there somewhere. I'm too tired now - didn't get to sleep last night.Confused Hopefully tomorrow will bring results. Thanks for the pointers!

Oh and it looks like the current get_iplayer only works with the BBC and no other sources.

exobuzz Wrote:Please can you start a new thread on this and we can continue there?
Also this seems to the original more readable version of the file

http://pajhome.org.uk/crypt/md5/sha1.html

btw the token looks base64 encoded to me. When decoded it gives 136 bytes of data. However we need to see how that javascript sha1 code is used because this 136 bytes might consist of a key and some data that we need to process for example. I'm don't know that much about cryptography stuff I'm afraid.

PS. the code which calls the javascript sha1 stuff is in /static/programmes/js/controller/brand/catchup.js. I can't even say for sure though whether this is directly linked to the token in the xml or not or some other stuff. But it's a start.


I have since discovered that rtmpsrv does generate the needed authkey (I didn't think it could yesterday unless you did it through getFLV - I was very tired, and wrong). The answer should lie in the rtmpsrv sourcecode somewhere. (actually it only retrieves it - thanks highlandsun)
Reply
#4
eddebaby Wrote:I have since discovered that rtmpsrv does generate the needed authkey (I didn't think it could yesterday unless you did it through getFLV - I was very tired, and wrong). The answer should lie in the rtmpsrv sourcecode somewhere.

No, there is no magic code in rtmpsrv for generating keys. rtmpsrv merely relays whatever it got from the actual flash client (which did all of the key generation).
Reply
#5
highlandsun Wrote:No, there is no magic code in rtmpsrv for generating keys. rtmpsrv merely relays whatever it got from the actual flash client (which did all of the key generation).
Thank you, Do you know how this can be retrieved via XBMC's libRTMP (via a plugin)?
Reply
#6
eddebaby Wrote:Thank you, Do you know how this can be retrieved via XBMC's libRTMP (via a plugin)?

This has nothing to do with RTMP, so no, there is no way to use libRTMP to get the key. You have to figure out what the XML/javascript is doing and feed the proper value into libRTMP.
Reply
#7
highlandsun Wrote:This has nothing to do with RTMP, so no, there is no way to use libRTMP to get the key. You have to figure out what the XML/javascript is doing and feed the proper value into libRTMP.

Sorry, I was thinking that rtmpsrv's functionality would be within libRTMP. Now you've pointed it out I realise why my assumption was wrong. The hunt continues...

Another question - do you know how rtmpsrv might retrieve the auth string? I can see 'auth' mentioned several times in the code for rtmpsrv and other code in the rtmpdump project, but I can't see to find a function/command that actually retrieves the information. My C knowledge is next-to-nothing - which doesn't really help here.Smile How do you get the auth string for your hulu plugin?

There's a new version of the plugin in the first post.
Reply
#8
watching this thread with interest. Hope you can work it out! Smile
Reply
#9
exobuzz Wrote:watching this thread with interest. Hope you can work it out! Smile

So do I...

It looks to me like the javascript we've been looking at is a no go. If you b64 encode a HMAC-SHA1 hash the resulting base64 is not long enough. HMAC-SHA1 is certainly only a part of the auth if it is used.

I've been using this to play around with: Online Base64 Encoder/Decoder. I haven't yet managed to generate a b64 encoded string that includes '/'s and '+'s like the token in the XML file. Neither have I been able to generate a b64 string the same length as the one in the XML Weird.

Also, this whole token thing could still be a red herring.Confused

I would love to know the relevance of <fingerprint>v002</fingerprint> or aifp=v002. Every other (working) rtmp plugin has a stream with aifp=v001. Does anybody know what aifp stands for? Or what it's relevance is? Is it a difference between rtmp and rtmpe?
Reply
#10
eddebaby Wrote:So do I...

It looks to me like the javascript we've been looking at is a no go. If you b64 encode a HMAC-SHA1 hash the resulting base64 is not long enough. HMAC-SHA1 is certainly only a part of the auth if it is used.

I've been using this to play around with: Online Base64 Encoder/Decoder. I haven't yet managed to generate a b64 encoded string that includes '/'s and '+'s like the token in the XML file. Neither have I been able to generate a b64 string the same length as the one in the XML Weird.

Also, this whole token thing could still be a red herring.Confused

I don't think the token is a herring. But im not convinced the javascript has anything to do with it either. The flash itself may well be generating the auth value from it. the data is definitely base64, decode it and then reencode for example. if it wasnt valid base64 you would get errors on decode.
Reply
#11
For the hulu plugin we spent a long time decompiling everything in sight until we found the relevant code. In that case, all of the code was in the Flash player .swf file(s). Several people solved different pieces of that puzzle, and then eventually I assembled all of that knowledge into the current plugin so that it could generate all of the required parameters without any external code.

Definitely you should start with the player. I took a quick look at a page for a show (which I can't play from here) and I don't see any parameters being passed to the player SWF from the actual web page aside from the program's ID #. That implies that none of the javascript on the page is relevant.
Reply
#12
Interesting thanks.

So I'm now staring at a bunch of decompiled action script. see some base64 stuff, and some encryption related calls. A long painful job I suspect to work this out, at least for me.

[edit] found a call to decrypt, which in turns calls encrypt (something like an advanced rot13 type thing perhaps?) Not sure about this decompilers output mind. might try another.

looking closer it looks like rc4.
Reply
#13
I found the rc4 code they use which is more readable. I just have to work out what the key is and it should be simple! (i hope)

http://www.google.com/codesearch/p?hl=en...cd=3&ct=rc

[edit] and now im not certain for sure that they are using rc4 as they include a whole set of encryption libraries. ouch.. Infact I have no idea which one they are using, as they include the whole of http://code.google.com/p/as3crypto/ and I didn't manage to trace the code that well.
Reply
#14
You're definitely on to something with the RC4 encryption. auth>RC4 encryption>base64 encoding>token looks pretty likely. As you say we just need to find the RC4 key.

Example Flow:
Code:
[b]auth=[/b]da_czapb_asbEadbFbDded_bDbHdYc8doaA-bl8CQ_-eS-ixR-nqrak8n1lwtgoxnWtKnCk9kGoVpgpmpcmcsBkmnHl2tio8nYsenikZjcnbp8pqpdn5s4kAnxl4t6ofnd

encrypted with RC4 (key "SECRET"):
F8 0F 33 1C 75 41 53 AA BD 07 CF D1 24 63 81 65 EA 0B 45 69 B6 3B 29 A9 BC B6 2E 96 53 FB 7D FD 18 A2 29 C5 93 20 F8 53 0B 28 19 DC 10 DB B4 D9 AD 05 D3 98 CB 00 64 26 90 0E B5 9C 56 11 C7 65 9B 65 67 38 14 ED 4F 37 BD 5C 09 60 1D 42 45 F0 97 BB 26 AF 98 68 B6 C5 20 3E AC 90 F3 A8 26 02 BA 06 69 33 71 1D E7 F9 7B A6 91 7E 24 D8 9C 88 2D 18 1D B0 9A 3D 36 07 E6 0E D8 F5 1C 6B 20 25 14 00

encoded in base64:
+A8zHHVBU6q9B8/RJGOBZeoLRWm2OympvLYullP7ff0YoinFkyD4UwsoGdwQ27TZrQXTmMsAZCaQDrWcVhHHZZtlZzgU7U83vVwJYB1CRfCXuyavmGi2xSA+rJDzqCYCugZpM3Ed5/l7ppF+JNiciC0YHbCaPTYH5g7Y9RxrICUUAA==

The final result looks very much like our existing tokens and is exactly the same length (Edit: No it isn't! I was comparing the wrong tokens!). There could still be some more steps in there but it seems so close.Nerd

Here is the online RC4 tool I used: http://www.fyneworks.com/encryption/RC4-Encryption/
Reply
#15
My theory now is the string that is encrypted to produce the b64 encoded token is:
&auth=dsdgasdfdfhdfhadghdfdf.....

These additional 6 characters give the correct length b64 encoded token.

So token>b64 decode>decryption>&auth=<authkey>

Possible decryption methods are:
RC4, DES, 3DES (they produce a correct length b64 string)

Eliminated decryption methods:
AES (only works on data 128bits in length - unless it's somehow called recursively)

To be confirmed:
RSA, BlowFish, XTEA (I'm sure blowfish and xtea are candidates though)


I've also found one particular actionscript file that looks like it contains a load of obfuscated strings: _-4G\_-8a.as (Named by Sothink's software)

See my thoughts as to why here here
Reply

Logout Mark Read Team Forum Stats Members Help
4oD (Channel4 on Demand) plugin development1