[RELEASE] Hulu (Video) Plugin for XBMC

  Thread Rating:
  • 1 Votes - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Thread Closed
ptaylor Offline
Junior Member
Posts: 17
Joined: Feb 2009
Reputation: 0
Post: #571
mr.b Wrote:since this is not running from within an SWF file (in a browser), it might be easier to have the code pic up a list of encrypted PIDs in a file (xml maybe) and do it in a batch type process.

Or, simply have it read a file in with a single PID? That would translate well to the xbmc plug-in logic (write encrypted pid to file, run decryption tool, read decrypted pid, continue as usual.)
find
angrycamel Offline
Senior Member
Posts: 234
Joined: Dec 2008
Reputation: 8
Post: #572
rectalogic Wrote:Yes, but to access the command line we need an AS3 host swf which get the args from parameters then load the AS2 swf I wrote and pass it the args as query-string. Not too complicated, I'll look at it tonight.

Another approach other than using the AIR SDK would be to use Boxees open source flashlib http://dl.boxee.tv/flashlib-shared-src.tar.gz - i.e. use this to write a small app that loaded and ran the swf to spit out the decrypted pid. This could then be invoked from a Python XBMC plugin to do the decryption.

Great stuff. I like the idea of running the swf directly in XBMC but is that limited to Windows only or would the Boxee flashlib run on the Xbox?

Integrating with XBMC through the JSON-RPC interface?

Try the JSON-RPC Browser

[Image: hUryuD3.png]
find
rectalogic Offline
Junior Member
Posts: 30
Joined: Feb 2009
Reputation: 0
Post: #573
angrycamel Wrote:Great stuff. I like the idea of running the swf directly in XBMC but is that limited to Windows only or would the Boxee flashlib run on the Xbox?

I think the flashlib stuff is Windows, Mac and Linux. Not sure about Xbox.

In any case, I'm sure AIR won't work on Xbox.

So maybe something like Gnash would be a better approach.

Basically we just need some way to invoke a flash AS2 interpreter via the command line and get stdout from it.
find
angrycamel Offline
Senior Member
Posts: 234
Joined: Dec 2008
Reputation: 8
Post: #574
Ya I see what you're getting at. If I have some time, I will try and play around with gnash on the xbox to see if it will run the code.

Integrating with XBMC through the JSON-RPC interface?

Try the JSON-RPC Browser

[Image: hUryuD3.png]
find
ribs15183 Offline
Junior Member
Posts: 1
Joined: Feb 2009
Reputation: 0
Post: #575
So I had the Hulu plugin working just fine for a few days with the latest version of XBMC from T3CH.

The past couple days when I fire up the Hulu plugin, I get the directory listings just fine but when I try to play a movie the current directory I'm in is reloaded and no movie is played.

Any ideas?

Thanks!

EDIT: Sorry for the quick post without scrolling back a few pages.
(This post was last modified: 2009-02-21 04:04 by ribs15183.)
find
angrycamel Offline
Senior Member
Posts: 234
Joined: Dec 2008
Reputation: 8
Post: #576
angrycamel Wrote:Ya I see what you're getting at. If I have some time, I will try and play around with gnash on the xbox to see if it will run the code.

Bummer...

ysbox Wrote:I took a look at gnash a while ago, and imho it has too heavy dependencies like glib, boost, libmad, not mentioning cairo/gtk... (and so on, http://www.gnu.org/software/gnash/ma...tml#codedepend), the least thing XBMC needs is more library ports to xbox for a "niche" functionality.

http://forum.xbmc.org/showpost.php?p=149...stcount=50

Integrating with XBMC through the JSON-RPC interface?

Try the JSON-RPC Browser

[Image: hUryuD3.png]
find
rectalogic Offline
Junior Member
Posts: 30
Joined: Feb 2009
Reputation: 0
Post: #577
angrycamel Wrote:http://forum.xbmc.org/showpost.php?p=149...stcount=50

We don't need all that stuff from gnash, we don't need any of the visual pieces or video support etc. - just the AS2 interpreter. So possibly that can be compiled separately with minimal dependencies, haven't looked yet.
find
TheEvilHammer Offline
Senior Member
Posts: 238
Joined: Nov 2006
Reputation: 0
Post: #578
ribs15183 Wrote:So I had the Hulu plugin working just fine for a few days with the latest version of XBMC from T3CH.

The past couple days when I fire up the Hulu plugin, I get the directory listings just fine but when I try to play a movie the current directory I'm in is reloaded and no movie is played.

Any ideas?

Thanks!

Go back to post #531 and start reading from there.
find
TheEvilHammer Offline
Senior Member
Posts: 238
Joined: Nov 2006
Reputation: 0
Post: #579
ptaylor Wrote:You should be able to pick them out of a tcpdump when viewing a video via a browser. I did so last night with wireshark. I was thinking that perhaps something could be automated to learn the pids and store them in a central database.

Here's a Wireshark display filter that will help you get the pid:

Code:
http.request.method == "GET" and http.request.uri contains "pid="

As whirlwind mentioned, you can also use the Live HTTP Headers plugin for Firefox and search through all the headers for "pid=".

As an aside, if you're looking to download Hulu videos (as opposed to streaming them from XBMC, which is what this thread is about), you can get rtmpdump and edit the get_hulu Perl script to either hardcode the pid or take the pid as a parameter for the particular video you want.
find
afail Offline
Senior Member
Posts: 121
Joined: Feb 2007
Reputation: 0
Post: #580
just wanted to thank you all for your efforts to keep the hulu plugin alive
find
w3__ Offline
Senior Member
Posts: 130
Joined: Jul 2008
Reputation: 0
Post: #581
That goes for me too!
find
angrycamel Offline
Senior Member
Posts: 234
Joined: Dec 2008
Reputation: 8
Rainbow  Something to get us back online for now
Post: #582
Here is something to hold us over...

Using rectalogic's ActionScript as a starting point and compiling with mtasc, I created an SWF that will decrypt the passed in encrypted pid and redirect to a PHP that puts it into an easily consumable xml format.

Here is how it works:

Here is the test data I used while putting it together:
Code:
Heroes PID Conversion Test

URL:           http://www.hulu.com/watch/56972/heroes-trust-and-blood
Content_ID:    14083985
Encrypted PID:    183442a1469fe64906e11e4ccde6f550ae33747d7f27dddc3fef0d4369c19665~fc3f25e17f​446c6d6d5f4d35b407b1f90e157cbc68a409838b1968d345cd040b
Decrypted PID:    Y_jW38tecJlXH6n77uxR4osxRM6qCagy

The modified version of rectalogic's code. I had it outputting to a text field in the swf for testing, but as you can see, that gets commented out so that you don't even see the swf... just an auto redirect to the output xml.

Code:
import mx.controls.*;
class DecryptPid {
    var pid:String;

    function DecryptPid() {
            System.security.allowDomain("www.angrycamel.com");
            System.security.allowDomain("www.hulu.com");
            System.security.allowDomain("www.qa.hulu.com");
            System.security.allowDomain("static.hulu.com");
            System.security.allowDomain("assets.hulu.com");
            System.security.allowDomain("ads.hulu.com");
            System.security.allowDomain("localhost");
    }

    function decrypt(pid:String) {
        this.pid = pid;
        var loader:MovieClipLoader = new MovieClipLoader();
        loader.addListener(this);
        var sec:MovieClip = _root.createEmptyMovieClip("sec", 10)
        sec._lockroot = true;
        //loader.loadClip("http://www.hulu.com/sec.swf", sec);
        loader.loadClip("sec.swf", sec);
    }

    function onLoadInit(sec:MovieClip) {
        var s:String = sec.dec(this.pid);
        //_root.output.text = "Encrypted Pid:\n   " + this.pid + "\n\n" +
        //                    "Decrypted Pid:\n   " + s;
        getURL("http://angrycamel.com/huluPidDecryptor.php?encrypted=" + this.pid + "&decrypted=" + s);
    }
    
    function createOutput() {
                _root.createTextField("output", _root.getNextHighestDepth(), 0, 0, 750, 200);
            _root.output.multiline = true;
                _root.output.wordWrap = true;
        }

    static function main(mc) {
            var dpid = new DecryptPid();
            //dpid.createOutput();
        dpid.decrypt(_level0.pid);
        //dpid.decrypt("183442a1469fe64906e11e4ccde6f550ae33747d7f27dddc3fef0d4369c19665~fc3f25e17f446c6​d6d5f4d35b407b1f90e157cbc68a409838b1968d345cd040b");
    }
}

The PHP that outputs the XML is about as simple as it get's, but here it is anyways.

PHP Code:
<?php
    
    
function genOutput() {
        
$output header("Content-type: text/xml");
        
$output .= "<?xml version=\"1.0\" standalone=\"no\"?>\r\n";
        
$output .= "<!-- XBMC Hulu Plugin | PID Decrypter -->\r\n";
        
$output .= "<Pid>\r\n";
        
$output .= "  <encrypted>".$_REQUEST["encrypted"]."</encrypted>\r\n";
        
$output .= "  <decrypted>".$_REQUEST["decrypted"]."</decrypted>\r\n";
        
$output .= "</Pid>\r\n";
        return 
$output;
    }
    
    echo 
genOutput();
?>



Try it yourself... (replace the pid in the url with whatever pid you want to test out)

http://angrycamel.com/DecryptPid.swf?pid...d345cd040b

Let me know if you run into any problems, and test as many PID's as you can.

I had trouble getting the SWF to reference the sec.swf directly from hulu.com, so I have it looking at a copy on my site right now. If anyone can offer any suggestions, please do.

Integrating with XBMC through the JSON-RPC interface?

Try the JSON-RPC Browser

[Image: hUryuD3.png]
find
ptaylor Offline
Junior Member
Posts: 17
Joined: Feb 2009
Reputation: 0
Post: #583
rectalogic Wrote:Yeah, I think they put the encryption logic in sec.swf so they can change it often independent of the player.swf code itself.

mtasc is here http://www.mtasc.org/
AIR SDK is here http://www.adobe.com/products/air/tools/sdk/

I'm been messing with this for a bit and find that adl doesn't seem to exit when it is complete... Not sure how to make it exit.

Here's what I've done to your code so far:

PHP Code:
class DecryptPid {
    var 
pid:String;

    function 
DecryptPid() {
    }

    function 
decrypt(pid:String) {
        
this.pid pid;
        var 
loader:MovieClipLoader = new MovieClipLoader();
        
loader.addListener(this);
        var 
sec:MovieClip _root.createEmptyMovieClip("sec"10)
        
sec._lockroot true;
        
loader.loadClip("http://www.hulu.com/sec.swf"sec);
    }

    function 
onLoadInit(sec:MovieClip) {
        var 
s:String sec.dec(this.pid);
        
trace(this.pid "  =  " s)
    }

    static function 
main(mc) {
        
/* first create a new instance of the LoadVars object */ 
        
var myVars:LoadVars = new LoadVars(); 
        
myVars.onLoad = function (success) {
              if (
success) {
                (new 
DecryptPid()).decrypt(myVars.pid);
              }
        };
        
        
// call the load method
        
myVars.load("encryptedPid.txt");
        
    }


That reads the file encryptedPid.txt and decrypts it.

Note: The contents of encryptedPid.txt should be pid={encrypted pid here}

I read here that you can pass command line parameters via adl by using -- followed by whatever parameter you want to pass. I just ran across this, so I haven't tried yet... The bigger problem I'm having is just exiting adl when it is done.
(This post was last modified: 2009-02-20 04:42 by ptaylor.)
find
angrycamel Offline
Senior Member
Posts: 234
Joined: Dec 2008
Reputation: 8
Post: #584
check my post from a few min ago to see how to take in a parameter

Edit: oops I just realized you were talking about win cmd line parms not URL parms, sorry.

Integrating with XBMC through the JSON-RPC interface?

Try the JSON-RPC Browser

[Image: hUryuD3.png]
(This post was last modified: 2009-02-20 04:35 by angrycamel.)
find
rectalogic Offline
Junior Member
Posts: 30
Joined: Feb 2009
Reputation: 0
Post: #585
ptaylor Wrote:I'm been messing with this for a bit and find that adl doesn't seem to exit when it is complete... Not sure how to make it exit.

You can exit using NativeApplication.nativeApplication.exit(0) - but that can only be done in AS3. So you need an AS3 swf that hosts the AS2 swf that loads sec.swf and calls dec().

Anyway, I think gnash is a better approach. I just tested with gnash and it works, and it exits and it can take command line args to specify the input pid.

e.g.

Code:
$ gnash --render-mode 0 --once --verbose --param FlashVars=pid=a9d2af515205989ce1d8bd20fa36db2c29a307b089a3351401012878b8b399d9~3​9474f6e3096ab2e5252d39741bd99994a4f0750bac32ef01c2c79a4845a5d37 DecryptPid.swf
[...]
069:2692241184] 22:05:13 TRACE: a9d2af515205989ce1d8bd20fa36db2c29a307b089a3351401012878b8b399d9~39474f6e3096ab2​e5252d39741bd99994a4f0750bac32ef01c2c79a4845a5d37  =  tkZDMTeYiZvqZTmTv1Bc3CmNMJnNjhEF
Main loop ended, cleaning up

Modified code to take command line "pid" arg from gnash:

Code:
class DecryptPid {
    var pid:String;

    function DecryptPid() {
    }

    function decrypt(pid:String) {
        this.pid = pid;
        var loader:MovieClipLoader = new MovieClipLoader();
        loader.addListener(this);
        var sec:MovieClip = _root.createEmptyMovieClip("sec", 10)
        sec._lockroot = true;
        loader.loadClip("http://www.hulu.com/sec.swf", sec);
    }

    function onLoadInit(sec:MovieClip) {
        var s:String = sec.dec(this.pid);
        trace(this.pid + "  =  " + s)
    }

    static function main(mc) {
        (new DecryptPid()).decrypt(_root.pid);
    }
}
find
Thread Closed