Browse Source

wh00t! get this working! I now have the ability to replicate a

hierarchy, and have the class do most of the work..    I will
probably need to figure out a better way to get at the hierarchy
than what I have now, but it works...

need to implement stuff like systemid, and containerid...  but I
managed to stream an mp3 file to Intel's media renderer!

[git-p4: depot-paths = "//depot/": change = 729]
replace/5b80aeb26dc425aaddcd5182126c969e5cc04cbb
John-Mark Gurney 20 years ago
parent
commit
83d5e90803
2 changed files with 82 additions and 36 deletions
  1. +47
    -35
      ContentDirectory.py
  2. +35
    -1
      pymediaserv

+ 47
- 35
ContentDirectory.py View File

@@ -29,9 +29,42 @@ from DIDLLite import DIDLElement, Container, Movie, Resource, MusicTrack
import traceback import traceback
from urllib import quote from urllib import quote


class ContentDirectoryControl(UPnPPublisher):
class ContentDirectoryControl(UPnPPublisher, dict):
"""This class implements the CDS actions over SOAP.""" """This class implements the CDS actions over SOAP."""


def getnextID(self):
ret = str(self.nextID)
self.nextID += 1
return ret

def addContainer(self, parent, title, **kwargs):
ret = self.addItem(parent, Container, title, **kwargs)
self.children[ret] = []
return ret

def addItem(self, parent, klass, *args, **kwargs):
assert isinstance(self[parent], Container)
nid = self.getnextID()
i = klass(nid, parent, *args, **kwargs)
self.children[parent].append(i)
self[i.id] = i
return i.id

def getchildren(self, item):
assert isinstance(self[item], Container)
return self.children[item][:]

def __init__(self, title, *args):
super(ContentDirectoryControl, self).__init__(*args)
fakeparent = '-1'
self.nextID = 0
self.children = { fakeparent: []}
self[fakeparent] = Container(None, '-1', 'fake')
root = self.addContainer(fakeparent, title)
assert root == '0'
del self[fakeparent]
del self.children[fakeparent]

# Required actions # Required actions


def soap_GetSearchCapabilities(self, *args, **kwargs): def soap_GetSearchCapabilities(self, *args, **kwargs):
@@ -61,6 +94,8 @@ class ContentDirectoryControl(UPnPPublisher):


(ObjectID, BrowseFlag, Filter, StartingIndex, RequestedCount, (ObjectID, BrowseFlag, Filter, StartingIndex, RequestedCount,
SortCriteria) = args SortCriteria) = args
StartingIndex = int(StartingIndex)
RequestedCount = int(RequestedCount)


log.msg('Browse(ObjectID=%s, BrowseFlags=%s, Filter=%s, ' log.msg('Browse(ObjectID=%s, BrowseFlags=%s, Filter=%s, '
'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % 'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' %
@@ -68,40 +103,16 @@ class ContentDirectoryControl(UPnPPublisher):
`RequestedCount`, `SortCriteria`)) `RequestedCount`, `SortCriteria`))


didl = DIDLElement() didl = DIDLElement()
result = {}


try: try:

if ObjectID == '0':
c = Container('media', '0', 'All media')
c.childCount = 5
c.searchable = 0
didl.addItem(c)

elif ObjectID == '0\\Music\\':
c = Container('0\\Music\\Spotty\\', '0\\Music\\', 'Spotty')
c.childCount = 6
c.searchable = 0
didl.addItem(c)

c = Container('0\\Music\\Foot\\', '0\\Music\\', 'Foot')
c.childCount = 1
c.searchable = 0
didl.addItem(c)


elif ObjectID == '0\\Music\\Spotty\\':

m = MusicTrack('0\\Music\\media\\foo.mp3', '0\\Music\\', 'foo.mp3')

m.res = Resource('http://192.168.1.105:8080/media/foo.mp3', 'http-get:*:audio/mpeg:*')
m.res.size = 1234
m.res.bitrate = 256
m.genre = 'Others'
m.artist = 'Others'
m.album = 'Others'
didl.addItem(m)
if BrowseFlag == 'BrowseDirectChildren':
ch = self.getchildren(ObjectID)[StartingIndex: StartingIndex + RequestedCount]
log.msg(ch)
log.msg(dict.__repr__(self))
filter(lambda x, s = self, d = didl: d.addItem(s[x.id]) and None, ch)
else:
didl.addItem(self[ObjectID])


result = {'BrowseResponse': {'Result': didl.toString() , result = {'BrowseResponse': {'Result': didl.toString() ,
'NumberReturned': didl.numItems(), 'NumberReturned': didl.numItems(),
@@ -205,7 +216,8 @@ class ContentDirectoryControl(UPnPPublisher):
(`ContainerID`, `ObjectID`)) (`ContainerID`, `ObjectID`))


class ContentDirectoryServer(resource.Resource): class ContentDirectoryServer(resource.Resource):
def __init__(self):
def __init__(self, title):
resource.Resource.__init__(self) resource.Resource.__init__(self)
self.putChild('scpd.xml', static.File('content-directory-scpd.xml')) self.putChild('scpd.xml', static.File('content-directory-scpd.xml'))
self.putChild('control', ContentDirectoryControl())
self.control = ContentDirectoryControl(title)
self.putChild('control', self.control)

+ 35
- 1
pymediaserv View File

@@ -5,10 +5,14 @@


# Copyright 2005, Tim Potter <tpot@samba.org> # Copyright 2005, Tim Potter <tpot@samba.org>


from DIDLLite import TextItem, AudioItem, VideoItem, Resource
import os
import os.path
import random import random
import socket import socket
import string import string
import sys import sys
import traceback
from twisted.python import log from twisted.python import log
from twisted.internet import reactor from twisted.internet import reactor


@@ -61,10 +65,13 @@ class RootDevice(static.Data):
static.Data.__init__(self, d, 'text/xml') static.Data.__init__(self, d, 'text/xml')


root = WebServer() root = WebServer()
root.putChild('ContentDirectory', ContentDirectoryServer())
cds = ContentDirectoryServer('My Media Server')
root.putChild('ContentDirectory', cds)
cds = cds.control
root.putChild('ConnectionManager', ConnectionManagerServer()) root.putChild('ConnectionManager', ConnectionManagerServer())
root.putChild('root-device.xml', RootDevice()) root.putChild('root-device.xml', RootDevice())



# Area of server to serve media files from # Area of server to serve media files from


from MediaServer import MediaServer from MediaServer import MediaServer
@@ -78,6 +85,33 @@ medianode.contentTypes.update( {
}) })
root.putChild('media', medianode) root.putChild('media', medianode)


# Set up media files
allmedia = cds.addContainer('0', 'All Media')
log.msg('allmedia: %s' % repr(allmedia))
for i in os.listdir('media'):
fpath = os.path.join('media', i)
try:
if not os.path.isfile(fpath):
log.msg('skipping: %s' % fpath)
continue
fn, ext = os.path.splitext(i)
mt = medianode.contentTypes[ext]
ty = mt.split('/')[0]
if ty == 'video':
klass = VideoItem
elif ty == 'audio':
klass = AudioItem
elif ty == 'text':
klass = TextItem
else:
raise KeyError, 'no item for mt: %s' % mt

item = cds.addItem(allmedia, klass, fn)
cds[item].res = Resource('%smedia/%s' % (urlbase, i), 'http-get:*:%s:*' % mt)
cds[item].res.size = os.path.getsize(fpath)
except KeyError:
traceback.print_exc(file=log.logfile)

site = server.Site(root) site = server.Site(root)
reactor.listenTCP(listenPort, site) reactor.listenTCP(listenPort, site)




Loading…
Cancel
Save