Mein Script zum Runterladen und transkodieren von Sendungen vom Tivo
This commit is contained in:
parent
3a2f7dd812
commit
b946f14051
1 changed files with 168 additions and 0 deletions
168
src/tivomirror/tivomirror
Executable file
168
src/tivomirror/tivomirror
Executable file
|
@ -0,0 +1,168 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# $Schlepperbande$
|
||||
#
|
||||
# Stefans Script, um die Sendungen vom Tivo runterzuladen und in MPEG4
|
||||
# zu transkodieren.
|
||||
# Wird auf disklesslibber per Crontab-Eintrag stuendlich gestartet:
|
||||
# flock -n /tmp/tivomirror.log -c 'tivomirror >.tivomirror.log 2>&1 </dev/null'
|
||||
|
||||
import anydbm
|
||||
import cookielib
|
||||
import datetime
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import urllib2
|
||||
import xml.dom.minidom
|
||||
|
||||
host = "tivo.lassitu.de"
|
||||
mak = "7194378159"
|
||||
|
||||
class flushfile(object):
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
def write(self, x):
|
||||
self.f.write(x)
|
||||
self.f.flush()
|
||||
sys.stdout = flushfile(sys.stdout)
|
||||
|
||||
try:
|
||||
os.makedirs("tivo")
|
||||
except OSError:
|
||||
pass
|
||||
pwmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||
authhandler = urllib2.HTTPDigestAuthHandler(pwmgr)
|
||||
cookiejar = cookielib.MozillaCookieJar("tivo/.cookies.txt")
|
||||
opener = urllib2.build_opener(authhandler, urllib2.HTTPCookieProcessor(cookiejar))
|
||||
urllib2.install_opener(opener)
|
||||
transcode_srcopts = []
|
||||
transcode_srcopts.extend(["-aspect", "4:3"])
|
||||
transcode_srcopts.append("-i")
|
||||
transcode_dstopts = []
|
||||
transcode_dstopts.extend(["-threads", "8"])
|
||||
transcode_dstopts.extend(["-vcodec", "libx264", "-b", "1200kb"])
|
||||
#transcode_dstopts.extend(["-croptop", "8", "-cropbottom", "8", "-cropleft", "8", "-cropright", "8"])
|
||||
transcode_dstopts.extend(["-croptop", "60", "-cropbottom", "60", "-cropleft", "4", "-cropright", "4"])
|
||||
transcode_dstopts.extend(["-y", "-deinterlace"])
|
||||
transcode_dstopts.extend(["-aspect", "4:3"])
|
||||
tmpmp2 = "/mnt/fast/tmp/tivo.mpg"
|
||||
tmpmp4 = "/mnt/fast/tmp/tivo.mp4"
|
||||
|
||||
def gettoc():
|
||||
url = "https://" + host + "/TiVoConnect?Command=QueryContainer&Container=%2FNowPlaying&Recurse=Yes"
|
||||
pwmgr.add_password(None, url, "tivo", mak)
|
||||
|
||||
req = urllib2.Request(url)
|
||||
h = urllib2.urlopen(req)
|
||||
r = h.read()
|
||||
h.close()
|
||||
return r
|
||||
|
||||
def getText(nodelist):
|
||||
rc = ""
|
||||
for node in nodelist:
|
||||
if node.nodeType == node.TEXT_NODE:
|
||||
rc = rc + node.data
|
||||
return rc
|
||||
|
||||
def getTagText(element, tagname):
|
||||
try:
|
||||
return getText(i.getElementsByTagName(tagname)[0].childNodes)
|
||||
except IndexError:
|
||||
return ""
|
||||
|
||||
|
||||
def transcode(file, passno):
|
||||
print "--- transcoding pass %d" % passno
|
||||
try:
|
||||
os.remove(tmpmp4)
|
||||
except OSError:
|
||||
pass
|
||||
transcode_opts = [ "ffmpeg" ];
|
||||
transcode_opts.extend(transcode_srcopts)
|
||||
transcode_opts.append(tmpmp2)
|
||||
transcode_opts.extend(transcode_dstopts)
|
||||
if passno == 2:
|
||||
transcode_opts.extend(["-acodec", "libfaac", "-ab", "96kb"])
|
||||
transcode_opts.extend(["-pass", "%d" % passno])
|
||||
transcode_opts.append(tmpmp4)
|
||||
subprocess.check_call(transcode_opts)
|
||||
|
||||
|
||||
def download_decode(file, url, mak):
|
||||
try:
|
||||
os.makedirs(dir)
|
||||
except OSError:
|
||||
pass
|
||||
print "--- dowloading \"%s\"" % url
|
||||
p_curl = subprocess.Popen(["curl", "--anyauth", "--fail", \
|
||||
"--insecure", "--cookie", "tivo/.cookies.txt", \
|
||||
"--user", "tivo:%s" % mak, "--url", url], \
|
||||
stdout=subprocess.PIPE)
|
||||
p_decode = subprocess.Popen(["tivodecode", "--mak", mak, \
|
||||
"--out", tmpmp2, "-"], stdin=p_curl.stdout)
|
||||
status = {}
|
||||
(spid, sse) = os.wait()
|
||||
status.update({spid: sse})
|
||||
(spid, sse) = os.wait()
|
||||
status.update({spid: sse})
|
||||
if status.get(p_curl.pid) >> 8 != 0:
|
||||
print "error downloading file: %d" % (status.get(p_curl.pid) >> 8)
|
||||
exit(1)
|
||||
if status.get(p_decode.pid) >> 8 != 0:
|
||||
print "error decoding file: %d" % (status.get(p_decode.pid) >> 8)
|
||||
exit(1)
|
||||
transcode(file, 1)
|
||||
transcode(file, 2)
|
||||
print "--- copying to \"%s\"" % file
|
||||
shutil.copy(tmpmp4, "%s.mp4" % file)
|
||||
os.remove(tmpmp2)
|
||||
os.remove(tmpmp4)
|
||||
|
||||
def savetoc():
|
||||
fd=open("foo.xml", "w")
|
||||
fd.write(gettoc())
|
||||
fd.close()
|
||||
exit(0)
|
||||
|
||||
|
||||
downloaddb = anydbm.open("tivo/.downloads", "c")
|
||||
print "*** Getting listing"
|
||||
dom = xml.dom.minidom.parseString(gettoc())
|
||||
cookiejar.save()
|
||||
|
||||
items = dom.getElementsByTagName("Item")
|
||||
print "*** %d shows listed" % (items.length)
|
||||
for i in items:
|
||||
title = getTagText(i, "Title")
|
||||
episode = getTagText(i, "EpisodeTitle")
|
||||
date = getTagText(i, "CaptureDate")
|
||||
date = datetime.datetime.utcfromtimestamp(int(date, 16))
|
||||
date = date.strftime("%Y%m%d-%H%M")
|
||||
url = getTagText(i, "Url")
|
||||
inprogress = getTagText(i, "InProgress")
|
||||
if episode == "":
|
||||
episode = date
|
||||
name = "%s - %s" % (title, episode)
|
||||
dir = "tivo/%s" % (title)
|
||||
file = "%s/%s" % (dir, name)
|
||||
name = name.encode("utf-8");
|
||||
dir = dir.encode("utf-8");
|
||||
file = file.encode("utf-8");
|
||||
|
||||
if inprogress == "Yes":
|
||||
print "*** skipping \"%s\": is currently being recorded" % name
|
||||
continue
|
||||
if downloaddb.has_key(name):
|
||||
print "*** skipping \"%s\": already downloaded" % name
|
||||
continue
|
||||
print "*** downloading \"%s\"" % name
|
||||
download_decode(file, url, mak)
|
||||
downloaddb[name] = date
|
||||
if getattr(downloaddb, "sync", None) and callable(downloaddb.sync):
|
||||
downloaddb.sync()
|
||||
print "*** Completed"
|
||||
|
||||
downloaddb.close()
|
Loading…
Reference in a new issue