@@ -4,6 +4,8 @@
# $Id$
#
ffmpeg_path = '/Users/jgurney/src/ffmpeg/ffmpeg'
import FileDIDL
import errno
import itertools
@@ -12,8 +14,10 @@ import sets
import stat
from DIDLLite import StorageFolder, Item, VideoItem, AudioItem, TextItem, ImageItem, Resource
from twisted.web import static
from twisted.web import resource, server, static
from twisted.python import log
from twisted.internet import abstract, interfaces, process, protocol, reactor
from zope.interface import implements
__all__ = [ 'registerklassfun', 'FSObject', 'FSItem', 'FSVideoItem',
'FSAudioItem', 'FSTextItem', 'FSImageItem', 'mimetoklass',
@@ -69,13 +73,105 @@ class FSObject(object):
return '<%s.%s: path: %s>' % (self.__class__.__module__,
self.__class__.__name__, self.FSpath)
class NullConsumer(file, abstract.FileDescriptor):
implements(interfaces.IConsumer)
def __init__(self):
file.__init__(self, '/dev/null', 'w')
abstract.FileDescriptor.__init__(self)
def write(self, data):
pass
class DynamTransfer(protocol.ProcessProtocol):
def __init__(self, path, mods, request):
self.path = path
self.mods = mods
self.request = request
def outReceived(self, data):
self.request.write(data)
def outConnectionLost(self):
if self.request:
self.request.unregisterProducer()
self.request.finish()
self.request = None
def errReceived(self, data):
pass
#log.msg(data)
def stopProducing(self):
if self.request:
self.request.unregisterProducer()
self.request.finish()
if self.proc:
self.proc.loseConnection()
self.proc.signalProcess('INT')
self.request = None
self.proc = None
pauseProducing = lambda x: x.proc.pauseProducing()
resumeProducing = lambda x: x.proc.resumeProducing()
def render(self):
mods = self.mods
path = self.path
request = self.request
vcodec = mods[0]
if mods[0] not in ('xvid', 'mpeg2', ):
vcodec = 'xvid'
mimetype = { 'xvid': 'video/avi', 'mpeg2': 'video/mpeg', }
request.setHeader('content-type', mimetype[vcodec])
if request.method == 'HEAD':
return ''
optdict = {
'xvid': [ '-vcodec', 'xvid',
#'-mv4', '-gmc', '-g', '240',
'-f', 'avi', ],
'mpeg2': [ '-vcodec', 'mpeg2video', #'-g', '60',
'-f', 'mpeg', ],
}
audio = [ '-acodec', 'mp3', '-ab', '192', ]
args = [ 'ffmpeg', '-i', path, '-b', '8000',
#'-sc_threshold', '500000', '-b_strategy', '1', '-max_b_frames', '6',
] + optdict[vcodec] + audio + [ '-', ]
#log.msg(*args)
self.proc = process.Process(reactor, ffmpeg_path, args,
None, None, self)
self.proc.closeStdin()
request.registerProducer(self, 1)
return server.NOT_DONE_YET
class DynamicTrans(resource.Resource):
isLeaf = True
def __init__(self, path, notrans):
self.path = path
self.notrans = notrans
def render(self, request):
if request.postpath:
# Translation request
return DynamTransfer(self.path, request.postpath, request).render()
else:
return self.notrans.render(request)
class FSItem(FSObject, Item):
def __init__(self, *args, **kwargs):
FSObject.__init__(self, kwargs['path'])
del kwargs['path']
mimetype = kwargs['mimetype']
del kwargs['mimetype']
kwargs['content'] = static.File(self.FSpath)
kwargs['content'] = DynamicTrans(self.FSpath,
static.File(self.FSpath, mimetype))
Item.__init__(self, *args, **kwargs)
self.url = '%s/%s' % (self.cd.urlbase, self.id)
self.mimetype = mimetype
@@ -83,6 +179,9 @@ class FSItem(FSObject, Item):
def doUpdate(self):
self.res = Resource(self.url, 'http-get:*:%s:*' % self.mimetype)
self.res.size = os.path.getsize(self.FSpath)
self.res = [ self.res ]
self.res.append(Resource(self.url + '/mpeg2', 'http-get:*:%s:*' % 'video/mpeg'))
self.res.append(Resource(self.url + '/xvid', 'http-get:*:%s:*' % 'video/avi'))
Item.doUpdate(self)
def defFS(path, fobj):