A Python UPnP Media Server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.6 KiB

  1. #!/usr/bin/env python
  2. # Licensed under the MIT license
  3. # http://opensource.org/licenses/mit-license.php
  4. # (c) 2005, Tim Potter <tpot@samba.org>
  5. import random
  6. import socket
  7. import string
  8. import sys
  9. from twisted.python import log
  10. from twisted.internet import reactor
  11. def generateuuid():
  12. if False:
  13. return 'asdflkjewoifjslkdfj'
  14. return ''.join(map(lambda x: random.choice(string.letters), xrange(20)))
  15. listenAddr = sys.argv[1]
  16. if len(sys.argv) > 2:
  17. listenPort = int(sys.argv[2])
  18. if listenPort < 1024 or listenPort > 65535:
  19. raise ValueError, 'port out of range'
  20. else:
  21. listenPort = 8080
  22. log.startLogging(sys.stdout)
  23. # Create SSDP server
  24. from SSDP import SSDPServer, SSDP_PORT, SSDP_ADDR
  25. s = SSDPServer()
  26. port = reactor.listenMulticast(SSDP_PORT, s)
  27. port.joinGroup(SSDP_ADDR)
  28. port.setLoopbackMode(0) # don't get our own sends
  29. uuid = 'uuid:' + generateuuid()
  30. urlbase = 'http://%s:%d/' % (listenAddr, listenPort)
  31. # Create SOAP server
  32. from twisted.web import server, resource, static
  33. from ContentDirectory import ContentDirectoryServer
  34. from ConnectionManager import ConnectionManagerServer
  35. class WebServer(resource.Resource):
  36. def __init__(self):
  37. resource.Resource.__init__(self)
  38. class RootDevice(static.Data):
  39. def __init__(self):
  40. r = {
  41. 'hostname': socket.gethostname(),
  42. 'uuid': uuid,
  43. 'urlbase': urlbase,
  44. }
  45. d = file('root-device.xml').read() % r
  46. static.Data.__init__(self, d, 'text/xml')
  47. root = WebServer()
  48. root.putChild('ContentDirectory', ContentDirectoryServer())
  49. root.putChild('ConnectionManager', ConnectionManagerServer())
  50. root.putChild('root-device.xml', RootDevice())
  51. # Area of server to serve media files from
  52. from MediaServer import MediaServer
  53. root.putChild('media', static.File('media'))
  54. site = server.Site(root)
  55. reactor.listenTCP(listenPort, site)
  56. # we need to do this after the children are there, since we send notifies
  57. s.register('%s::upnp:rootdevice' % uuid,
  58. 'upnp:rootdevice',
  59. urlbase + 'root-device.xml')
  60. s.register(uuid,
  61. uuid,
  62. urlbase + 'root-device.xml')
  63. s.register('%s::urn:schemas-upnp-org:device:MediaServer:1' % uuid,
  64. 'urn:schemas-upnp-org:device:MediaServer:1',
  65. urlbase + 'root-device.xml')
  66. s.register('%s::urn:schemas-upnp-org:service:ConnectionManager:1' % uuid,
  67. 'urn:schemas-upnp-org:device:ConnectionManager:1',
  68. urlbase + 'root-device.xml')
  69. s.register('%s::urn:schemas-upnp-org:service:ContentDirectory:1' % uuid,
  70. 'urn:schemas-upnp-org:device:ContentDirectory:1',
  71. urlbase + 'root-device.xml')
  72. # Main loop
  73. reactor.run()