|
- #!/usr/bin/env python
-
- # Licensed under the MIT license
- # http://opensource.org/licenses/mit-license.php
- # Copyright 2005, Tim Potter <tpot@samba.org>
- # Copyright 2006 John-Mark Gurney <gurney_j@resnet.uroegon.edu>
-
- from DIDLLite import TextItem, AudioItem, VideoItem, ImageItem, Resource, StorageFolder
- from FSStorage import FSDirectory
- import os
- import os.path
- import random
- import socket
- import string
- import sys
- from twisted.python import log
- from twisted.internet import reactor
-
- def generateuuid():
- if False:
- return 'uuid:asdflkjewoifjslkdfj'
- return ''.join([ 'uuid:'] + map(lambda x: random.choice(string.letters), xrange(20)))
-
- listenAddr = sys.argv[1]
- if len(sys.argv) > 2:
- listenPort = int(sys.argv[2])
- if listenPort < 1024 or listenPort > 65535:
- raise ValueError, 'port out of range'
- else:
- listenPort = random.randint(10000, 65000)
-
- log.startLogging(sys.stdout)
-
- # Create SSDP server
-
- from SSDP import SSDPServer, SSDP_PORT, SSDP_ADDR
-
- s = SSDPServer()
-
- port = reactor.listenMulticast(SSDP_PORT, s)
- port.joinGroup(SSDP_ADDR)
- port.setLoopbackMode(0) # don't get our own sends
-
- uuid = generateuuid()
- urlbase = 'http://%s:%d/' % (listenAddr, listenPort)
-
- # Create SOAP server
-
- from twisted.web import server, resource, static
- from ContentDirectory import ContentDirectoryServer
- from ConnectionManager import ConnectionManagerServer
-
- class WebServer(resource.Resource):
- def __init__(self):
- resource.Resource.__init__(self)
-
- class RootDevice(static.Data):
- def __init__(self):
- r = {
- 'hostname': socket.gethostname(),
- 'uuid': uuid,
- 'urlbase': urlbase,
- }
- d = file('root-device.xml').read() % r
- static.Data.__init__(self, d, 'text/xml')
-
- root = WebServer()
- cds = ContentDirectoryServer('My Media Server')
- root.putChild('ContentDirectory', cds)
- cds = cds.control
- root.putChild('ConnectionManager', ConnectionManagerServer())
- root.putChild('root-device.xml', RootDevice())
-
-
- # Area of server to serve media files from
-
- from MediaServer import MediaServer
-
- medianode = static.File('media')
- medianode.contentTypes.update( {
- '.wmv': 'video/x-ms-wmv',
- #'.ts': 'video/mp2t',
- '.ts': 'video/mpeg', # we may want this instead of mp2t
- #'.mp4': 'video/mp4',
- '.mp4': 'video/mpeg',
- '.ogm': 'application/ogg',
- '.vob': 'video/mpeg',
- })
- root.putChild('media', medianode)
-
- # Set up media files
- def addFSPath(cds, parent, dpath):
- dlist = os.listdir(dpath)
- dlist.sort()
- for i in dlist:
- fpath = os.path.join(dpath, i)
- try:
- fn, ext = os.path.splitext(i)
- ext = ext.lower()
- if os.path.isdir(fpath):
- folder = cds.addContainer(parent, i, klass = StorageFolder)
- addFSPath(cds, folder, fpath)
- if not os.path.isfile(fpath):
- continue
- #if ext == '.ts':
- # continue
- mt = medianode.contentTypes[ext]
- ty = mt.split('/')[0]
- if ty == 'video':
- klass = VideoItem
- elif ty == 'audio':
- klass = AudioItem
- elif ty == 'text':
- klass = TextItem
- elif ty == 'image':
- klass = ImageItem
- else:
- raise KeyError, 'no item for mt: %s' % mt
-
- item = cds.addItem(parent, klass, i)
- cds[item].res = Resource('%s%s' % (urlbase, fpath), 'http-get:*:%s:*' % mt)
- cds[item].res.size = os.path.getsize(fpath)
- except KeyError:
- pass
-
- cds.addContainer('0', 'media', klass = FSDirectory, path = 'media', urlbase = urlbase)
- #addFSPath(cds, '0', 'media')
-
- site = server.Site(root)
- reactor.listenTCP(listenPort, site)
-
- # we need to do this after the children are there, since we send notifies
- s.register('%s::upnp:rootdevice' % uuid,
- 'upnp:rootdevice',
- urlbase + 'root-device.xml')
-
- s.register(uuid,
- uuid,
- urlbase + 'root-device.xml')
-
- s.register('%s::urn:schemas-upnp-org:device:MediaServer:1' % uuid,
- 'urn:schemas-upnp-org:device:MediaServer:1',
- urlbase + 'root-device.xml')
-
- s.register('%s::urn:schemas-upnp-org:service:ConnectionManager:1' % uuid,
- 'urn:schemas-upnp-org:device:ConnectionManager:1',
- urlbase + 'root-device.xml')
-
- s.register('%s::urn:schemas-upnp-org:service:ContentDirectory:1' % uuid,
- 'urn:schemas-upnp-org:device:ContentDirectory:1',
- urlbase + 'root-device.xml')
-
- # Main loop
-
- reactor.run()
|