1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Tivo Proxy Server

Discussion in 'Developers Corner' started by Allanon, Jul 22, 2012.

  1. Jul 22, 2012 #1 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    Hi, I'm writing a simple proxy server for my TiVo that will stream and decode .tivo files directly from the TiVo. This will allow media players like VLC and media servers like TVersity to play and server the files. I am also going to server a RSS feed so media servers can find the Tivo files.

    Right now I have a simple prototype that works with VLC:

    Code:
    import cgi, os, SocketServer, sys, time, subprocess
    import urllib2
    from SimpleHTTPServer import SimpleHTTPRequestHandler
    from StringIO import StringIO
    
    Tivo_MAK = '***********'
    Tivo_URL = 'http://192.168.1.106'
    Port = 8000
    
    
    def findPID(exename):
        a = os.popen4('tasklist /FI "IMAGENAME eq '+exename+'"')
        a[0].flush()
        try:
             info=a[1].readlines()[3].split()
        except:
            info=[exename,"NotFound"]
        return info[1]
    
    
    
    class DirectoryHandler(SimpleHTTPRequestHandler):
       
        def do_GET(self):
            global Tivo_MAK
            global Tivo_URL
                
            # create TiVo URL
            link = Tivo_URL + self.path
            print link
       
            # Send header
            self.send_response(200)
            self.send_header("Content-Type", "video/mpeg")
            self.end_headers()
             
            # Get and decode the Tivo file     
            decode = subprocess.Popen('curl.exe --digest -k -c cookies.txt -u tivo:{0:s} "{1:s}" | tivodecode -m {0:s} -- -'.format(Tivo_MAK,link),shell=True,bufsize=1000,stdout=subprocess.PIPE)
            processID = findPID('curl.exe')
    
            # send decoded data to the client
            while True:
                chunk = decode.stdout.read(4096)
                if not chunk:
                    break
                try:
                    self.wfile.write(chunk)
                except:
                    os.popen('TASKKILL /PID '+ processID +' /F')
                    time.sleep(1)
                    break
            
             
    httpd = SocketServer.TCPServer(("", Port), DirectoryHandler)
    print "serving at port", Port
    httpd.serve_forever()
    
    With this running I can open VLC and pass an URL that looks like this:
    Code:
    http://192.168.1.100:8000/download/Auction%20Kings.tivo?Container=%2FNowPlaying&id=4707752&Format=video/x-tivo-mpeg
    And the server will change the URL to the TiVo URL and run curl and tivodecode then pass the output back to VLC.

    This works in VLC, but I can't get any other media player or media server to recognize the output. I think it's because they can't determine the codec to use, they will open and close the link a few times before saying it can't play. My question is what exactly is output from tivodecode and what content-type and header info should I send? I tried "video/mpeg","video/mp4","video/mpgv" but windows media player won't play the output.
     
  2. Jul 23, 2012 #2 of 133
    wmcbrine

    wmcbrine Ziphead

    10,367
    22
    Aug 2, 2003
    The output from tivodecode should be an MPEG-2 program stream. I believe "video/mpeg" is the correct MIME type for this. But I don't know what other software besides VLC you've tried, what its capabilities are, or what it expects.
     
  3. Jul 23, 2012 #3 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    I tried VLC, Windows Media Player and Serviio media server. VLC played the stream no mater what MIME was on the stream. And Serviio Media Server would only play the stream if it was designated as an internet stream and a MIME of "video/mpeg" but if the same exact URL was passed using an RSS feed it would not play. Windows Media Player would not play the stream at all. It starts the stream a few times then says it can't play it.

    My goal is to stream videos from my TiVo to my Sony TV which has an UPNP/DLNA client. I would like to feed Serviio media server an RSS feed with proxy links to all the videos on the TiVo. Then I can use the UPNP/DLNA client to select videos and have them streamed using the proxy server. I don't want to store TiVo files on my computer.

    Update:
    I got RSS and video working with the PS3 Media Server. This media server satisfies all my media server needs so I am going to stop trying to get this proxy server working with other players and servers. I will post here the final code to my proxy server when it's complete.
     
  4. Aug 9, 2012 #4 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    Below is the final code that I'm using for the Tivo Proxy Server. It isn't pretty and doesn't do a lot of error checking but it works for me. You can use this code for whatever you like without restrictions.

    To use just run the Tivo Proxy Server.py code then pass a URL that looks like this:
    Code:
    http://192.168.1.100:10000/rss
    This assumes:
    Server_URL = 192.168.1.100
    Port = 10000

    That url will return an RSS FEED to the specified Tivo's now playing list. The .tivo URLs in the RSS feed will point to the proxy server and when a .tivo file is requested the proxy server will download the .tivo file and convert it to an .mpg and stream it to the requesting application.

    This has been tested with VLC and PS3 Media Server. I use this proxy server to stream videos from the TiVo to my Sony TV which has a UPNP / DNLA client which connect to the PS3 Media Server.
     

    Attached Files:

  5. Nov 16, 2012 #5 of 133
    ejonesss

    ejonesss New Member

    116
    0
    Aug 13, 2007
    after i set up the server i get invalid syntax at print link

    i guess print is not a valid command
     
  6. Jan 10, 2013 #6 of 133
    vanclute

    vanclute New Member

    154
    0
    Aug 3, 2003
    I just stumbled across this thread and am very intrigued to try this. I hope I'm doing something wrong because it doesn't seem to function at all for me.

    I run the .py file in Terminal after editing it to include my MAK, Tivo IP, and server IP (my Mac media server which is running the .py script).

    This is what I get:

    Any idea where I've gone wrong?
     
  7. Jan 10, 2013 #7 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    Only thing I can think of is to make sure you have all the modules installed. I'm not really a Python expert and I don't have a Mac. I taught myself how to program Python so there can be numerous things wrong with the code. It works on my Windows XP computer but I have no knowledge of how to get it working on other operating systems.

    Also checkout this thread where I explain some of the problems other operating systems might have:
    http://www.tivocommunity.com/tivo-vb/showthread.php?t=496286
     
  8. Jan 11, 2013 #8 of 133
    wmcbrine

    wmcbrine Ziphead

    10,367
    22
    Aug 2, 2003
    It's treating it as a shell script rather than as Python. You can either launch it as "python scriptname", or add this as the first line:

    Code:
    #!/usr/bin/env python
     
  9. Jan 11, 2013 #9 of 133
    vanclute

    vanclute New Member

    154
    0
    Aug 3, 2003
    Aha good point. OK I added the line, but now I get this:

    Code:
    users-Mac:~ user$ /Users/user/Desktop/Tivo\ Proxy\ Server.py ; exit;
    Traceback (most recent call last):
      File "/Users/user/Desktop/Tivo Proxy Server.py", line 121, in <module>
        httpd = SocketServer.TCPServer(("", Port), Handler)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 408, in __init__
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 419, in server_bind
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
    socket.error: [Errno 48] Address already in use
    logout
    
    [Process completed]
    I quit PyTivoX in case that was conflicting but that didn't help.
     
  10. Jan 11, 2013 #10 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    Since there seemed to be some interest in this program I went ahead and made the code less OS dependent. I removed all Windows specific code such as the process ID check function and the need for curl.exe. I tested the program using Python 2.7. You will still need to place tivodecode in the same path as the program. You can get a tivodecode binary file from kmttg's Helper Tools. Also you will still need to replace the IP, port and MAK parameters located near the top of the code to reflect your computer and Tivo network settings.
     

    Attached Files:

  11. Jan 12, 2013 #11 of 133
    vanclute

    vanclute New Member

    154
    0
    Aug 3, 2003
    Aha! I missed this requirement and had not done so at all. Hopefully that, combined with your new OS-independence changes, will yield better results for me at last. I shall report back ASAP!
     
  12. Jan 12, 2013 #12 of 133
    vanclute

    vanclute New Member

    154
    0
    Aug 3, 2003
    Well rats... no joy. :( Here is the result:

    Code:
    users-Mac:~ user$ /Applications/kmttg_v0p8u/tivodecode/Tivo\ Proxy\ Server\ 2.py ; exit;
    Traceback (most recent call last):
      File "/Applications/kmttg_v0p8u/tivodecode/Tivo Proxy Server 2.py", line 148, in <module>
        httpd = SocketServer.TCPServer(("", Port), Handler)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 408, in __init__
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 419, in server_bind
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
    socket.error: [Errno 48] Address already in use
    logout
    
    [Process completed]
    Any suggestions on where to go from here?
     
  13. Jan 12, 2013 #13 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    Did you try changing the port number?

    Edit:

    I also went online to see if I can find a solution and you might try using this line of code:

    Replace:
    Code:
    # Start Proxy Server
    httpd = SocketServer.TCPServer(("", Port), Handler)
    
    With:
    Code:
    # Start Proxy Server
    SocketServer.TCPServer.allow_reuse_address = True
    httpd = SocketServer.TCPServer(("", Port), Handler)
    
     
  14. Jan 12, 2013 #14 of 133
    wmcbrine

    wmcbrine Ziphead

    10,367
    22
    Aug 2, 2003
    Yes, change the port number. (Don't do the reuse mod.)
     
  15. Jan 12, 2013 #15 of 133
    bradleys

    bradleys It'll be fine....

    3,687
    4
    Oct 31, 2007
    I have the script running and I can see the rss feed. When I try to play the video in VLN I get nothing.

    Looks properly formated...

    "http://192.168.1.6:10000/download/Fringe.tivo?Container=%2FNowPlaying&id=2337518&Format=video/x-tivo-mpeg"

    [​IMG]


    Is it possible we could have a DNLA server built into PyTiVo? :)
     

    Attached Files:

    • play.jpg
      play.jpg
      File size:
      32.9 KB
      Views:
      633
  16. Jan 12, 2013 #16 of 133
    vanclute

    vanclute New Member

    154
    0
    Aug 3, 2003
    ok, progress! The server is now serving on port 10001 and I can see a list of programs on the tivo! Playing one however, still fails thusly:

    Code:
    Video URL:  [url]http://192.168.2.10/download/The%20Owl%20and%20the%20Pussycat.TiVo?Container=%2FNowPlaying&id=1337050[/url]
    
    192.168.2.16 - - [12/Jan/2013 17:50:29] "GET /download/The%20Owl%20and%20the%20Pussycat.TiVo?Container=%2FNowPlaying&id=1337050 HTTP/1.1" 200 -
    
    Decoding video
    
    ----------------------------------------
    Exception happened during processing of request from ('192.168.2.16', 53674)
    Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 284, in _handle_request_noblock
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 310, in process_request
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 323, in finish_request
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 639, in __init__
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 337, in handle
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/BaseHTTPServer.py", line 325, in handle_one_request
      File "/Applications/kmttg_v0p8u/tivodecode/Tivo Proxy Server 2.py", line 127, in do_GET
        decode = subprocess.Popen('tivodecode -m {0:s} -- -'.format(Tivo_MAK),shell=False,bufsize=0,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 672, in __init__
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1202, in _execute_child
    OSError: [Errno 2] No such file or directory
    ----------------------------------------
    So it's missing something... can you tell what?

    So close!

    Also I notice it's showing only a handful of programs, certainly nowhere near everything that's on the Tivo.
     
  17. Jan 12, 2013 #17 of 133
    bradleys

    bradleys It'll be fine....

    3,687
    4
    Oct 31, 2007
    Looks like you and I are seeing something very similar....

    I am also only seeing a subset of the actual content on my TiVo in the RSS feed.

    Code:
    Video URL:  http://192.168.1.7/download/Fringe.tivo?Container=%2FNowPlaying&id=2337518&Format=video/x-tivo-mpeg
    
    HOME_OFFICE.home - - [12/Jan/2013 19:33:48] "GET /download/Fringe.tivo?Container=%2FNowPlaying&id=2337518&Format=video/x-tivo-mpeg HTTP/1.1" 200 -
    
    Decoding video
    
    ----------------------------------------
    Exception happened during processing of request from ('192.168.1.6', 57892)
    Traceback (most recent call last):
      File "C:\Python27\lib\SocketServer.py", line 284, in _handle_request_noblock
        self.process_request(request, client_address)
      File "C:\Python27\lib\SocketServer.py", line 310, in process_request
        self.finish_request(request, client_address)
      File "C:\Python27\lib\SocketServer.py", line 323, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "C:\Python27\lib\SocketServer.py", line 638, in __init__
        self.handle()
      File "C:\Python27\lib\BaseHTTPServer.py", line 340, in handle
        self.handle_one_request()
      File "C:\Python27\lib\BaseHTTPServer.py", line 328, in handle_one_request
        method()
      File "C:\Program Files (x86)\TivoProxy\Tivo Proxy Server.py", line 125, in do_GET
        decode = subprocess.Popen('tivodecode -m {0:s} -- -'.format(Tivo_MAK),shell=False,bufsize=0,stdin=subprocess.PIPE,stdout=subprocess.PIPE)
      File "C:\Python27\lib\subprocess.py", line 679, in __init__
        errread, errwrite)
      File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
        startupinfo)
    WindowsError: [Error 2] The system cannot find the file specified
    ----------------------------------------
    /
    
    Definately looks like some file is not being found...
     
  18. Jan 12, 2013 #18 of 133
    vanclute

    vanclute New Member

    154
    0
    Aug 3, 2003
    My first thought was that it's not finding something it needs from tivodecode, but I would have expected the error message to be a bit more specific if that were the case. I don't have any other theory at this moment. =(
     
  19. Jan 12, 2013 #19 of 133
    bradleys

    bradleys It'll be fine....

    3,687
    4
    Oct 31, 2007
    That was my thought as well... So I tried placing the TiVodecode files in the root directory (C:\Program Files (x86)\TivoProxy) to see if that would help. It didn't.

    I am sure we are doing something simple wrong.
     
  20. Jan 13, 2013 #20 of 133
    Allanon

    Allanon Member

    580
    0
    Nov 2, 2005
    The URL posted in the image looks different than the ones I'm getting. My URLs are formatted like this:
    Code:
    http://192.168.1.114:10000/download/NFL%20Football.TiVo?Container=%2FNowPlaying&id=5377217
    
    Try removing the "&Format=video/x-tivo-mpeg" in your URL and see if it plays.

    What type of Tivo do you guys have? I have a Tivo HD and I did a hack to convert the XML file from the Tivo to an RSS feed. If you guys have a Premiere then maybe the XML file is different and the hack is messing up. I will fix the code to use XMLLib and read the XML file properly.

    Can someone post the XML Now Playing List from their Premiere so I can do a comparison?

    Also, in VLC you can add the RSS feed as a podcast and have the Tivo Now Playing List show up in the VLC playlist. This will prevent you from having to enter the URLs manually.
     

Share This Page