Browse Source

add new clip module... document it and the addition of item...

document DMC-250 and add it to the QA check list...

[git-p4: depot-paths = "//depot/": change = 1347]
main
John-Mark Gurney 15 years ago
parent
commit
fe90575e58
4 changed files with 127 additions and 3 deletions
  1. +115
    -0
      Clip.py
  2. +3
    -1
      QACheckList
  3. +7
    -1
      README
  4. +2
    -1
      pymeds.py

+ 115
- 0
Clip.py View File

@@ -0,0 +1,115 @@
#!/usr/bin/env python
# Copyright 2009 John-Mark Gurney <jmg@funkthat.com>
'''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)

+ 3
- 1
QACheckList View File

@@ -1,7 +1,7 @@
General Functionality General Functionality
error w/o media dir error w/o media dir


PS3 DSM-520 Cidero Intel
PS3 DSM-520 Cidero Intel DMC-250
Discovered Discovered
remains after 30m remains after 30m
FSStorage FSStorage
@@ -12,3 +12,5 @@ mpegtsmod
shoutcast shoutcast
dvd dvd
pyvr pyvr
Clip
item

+ 7
- 1
README View File

@@ -14,6 +14,7 @@ Tested basic functionality with the following devices and/or programs:
Intel's Media Control Point and Media Renderer Intel's Media Control Point and Media Renderer
D-Link DSM-520 D-Link DSM-520
Sony PlayStation 3 Sony PlayStation 3
Linksys DMC-250


The Intel tools are good for testing (though Windows only) and are The Intel tools are good for testing (though Windows only) and are
available at: available at:
@@ -82,7 +83,7 @@ v0.x:
Ignore AppleDouble Resource Fork Files. (Maybe we should ignore all Ignore AppleDouble Resource Fork Files. (Maybe we should ignore all
dot files.) dot files.)
Readded SOAPpy/fpconst requirement as it is necessary for twisted. Readded SOAPpy/fpconst requirement as it is necessary for twisted.
Made it a bit closer to a real twisted proejct, in the process,
Made it a bit closer to a real twisted project, in the process,
pymediaserv looks more like a normal program. It allows you to pymediaserv looks more like a normal program. It allows you to
override the media path and title of the server. override the media path and title of the server.
Minor change to checkUpdate API, we didn't use the return value, so Minor change to checkUpdate API, we didn't use the return value, so
@@ -91,6 +92,11 @@ v0.x:
This means that you can support streaming radio stations that This means that you can support streaming radio stations that
provides a .pls file such as KCSM 91.1. provides a .pls file such as KCSM 91.1.
Fix ShoutCast error handling to be correct. Fix ShoutCast error handling to be correct.
Add support for an XML file containing an object so you can create
an item that points to an mp3 streaming url that isn't a .pls.
Add support for playing parts of TS streams. This is useful for
splitting apart a TS stream w/ multiple clips (like HDV) w/o
creating the files.


v0.5: v0.5:
Support multiple SSDP servers on the same box. Support multiple SSDP servers on the same box.


+ 2
- 1
pymeds.py View File

@@ -3,7 +3,7 @@
# Licensed under the MIT license # Licensed under the MIT license
# http://opensource.org/licenses/mit-license.php # http://opensource.org/licenses/mit-license.php
# Copyright 2005, Tim Potter <tpot@samba.org> # Copyright 2005, Tim Potter <tpot@samba.org>
# Copyright 2006 John-Mark Gurney <jmg@funkthat.com>
# Copyright 2006-2009 John-Mark Gurney <jmg@funkthat.com>


__version__ = '$Change$' __version__ = '$Change$'
# $Id$ # $Id$
@@ -29,6 +29,7 @@ def tryloadmodule(mod):
# mpegtsmod can be really expensive. # mpegtsmod can be really expensive.
modules = [ modules = [
'shoutcast', 'shoutcast',
'Clip',
'pyvr', 'pyvr',
'item', 'item',
'dvd', 'dvd',


Loading…
Cancel
Save