#!/usr/bin/env python # Copyright 2009 John-Mark Gurney '''MPEG-TS clip''' __version__ = '$Change: 1308 $' # $Id: //depot/python/pymeds/main/shoutcast.py#22 $ import bisect import email import os.path from DIDLLite import VideoItem, Resource from FSStorage import registerklassfun from twisted.web import static class ClipProxyFile: def __init__(self, f, p): self.fp = open(f) self.p = p self.pos = 0 lp = p[-1] self.size = lp[0] + lp[1] def read(self, s=None): if s is None: s = self.size - self.pos p = bisect.bisect_right(self.p, (self.pos,)) if p > 0: p -= 1 # We might be able to do this with proper construction of # self.p, but this is easier. r = [] fp = self.fp records = iter(self.p[p:]) while s: rec = records.next() diff = self.pos - rec[0] rlen = min(s, rec[1] - diff) fp.seek(rec[2] + diff) r.append(fp.read(rlen)) s -= rlen self.pos += rlen return ''.join(r) def close(self): self.fp.close() def seek(self, p, d=0): assert d == 0 self.pos = p if self.pos > self.size: self.pos = self.size def tell(self): return self.pos class ClipProxy(static.File): isLeaf = True synchronized = [ 'parsefile', 'getsize', 'open' ] def __init__(self, f, *args): self.__mtime = None static.File.__init__(self, f, *args) self.parsefile(self.path) def parsefile(self, f): if self.getModificationTime() == self.__mtime: return self.__mtime = self.getModificationTime() i = email.message_from_file(open(f)) self.origfile = i['file'] self.date = eval(i['datetuple'], { '__builtins__': {} }) # date is UTC p = [ map(int, x.split()) for x in i.get_payload().split('\n') if x ] pos = 0 self.pos = par = [] for j in p: l = j[1] - j[0] + 188 par.append((pos, l, j[0])) pos += l self.__size = pos def getsize(self): return self.__size def open(self): return ClipProxyFile(self.origfile, self.pos) def restat(self): static.File.restat(self) self.parsefile(self.path) class ClipFile(VideoItem): def __init__(self, *args, **kwargs): file = kwargs.pop('file') mimetype = 'video/mpeg' kwargs['content'] = ClipProxy(file, mimetype) VideoItem.__init__(self, *args, **kwargs) self.url = '%s/%s' % (self.cd.urlbase, self.id) self.res = Resource(self.url, 'http-get:*:%s:*' % mimetype) def detectclipfile(origpath, fobj): path = os.path.basename(origpath) ext = os.path.splitext(path)[1] if ext == '.clip': return ClipFile, { 'file': origpath } return None, None registerklassfun(detectclipfile)