Workaround for bug with VLC on Windows: subtitles file not used
authorAlex Lätsch <lexx911@users.schwerkraft.elitedvb.net>
Wed, 28 May 2008 16:46:43 +0000 (16:46 +0000)
committerAlex Lätsch <lexx911@users.schwerkraft.elitedvb.net>
Wed, 28 May 2008 16:46:43 +0000 (16:46 +0000)
vlcplayer/src/VlcControlHttp.py

index 0bf282c..b76fa57 100755 (executable)
-# -*- coding: ISO-8859-1 -*-
-#===============================================================================
-# VLC Player Plugin by A. Lätsch 2007
-#
-# This is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation; either version 2, or (at your option) any later
-# version.
-#===============================================================================
-
-from urllib import urlencode
-from urllib2 import urlopen
-from xml.dom.minidom import parse
-from Components.config import config
-from socket import socket as socket_socket, AF_INET as socket_AF_INET, SOCK_STREAM as socket_SOCK_STREAM
-
-def getText(nodelist):
-    rc = ""
-    for node in nodelist:
-        if node.nodeType == node.TEXT_NODE:
-            rc = rc + node.data
-    return rc
-
-def getLocalHostIP( remote = ("www.python.org", 80)):
-       '''Get the "public" address of the local machine, i.e.
-       that address which is connected to the general internet.
-       Code by Donn Cave, posted to comp.lang.python'''
-       s = socket_socket(socket_AF_INET, socket_SOCK_STREAM)
-       s.connect( remote )
-       ip, localport = s.getsockname()
-       s.close()
-       return ip
-
-class VlcControlHttp:
-       defaultStreamName = None
-       
-       def __init__(self, servernum):
-               cfg = config.plugins.vlcplayer.servers[servernum]
-               self.servercfg = cfg
-               self.host = cfg.host.value + ":" + str(cfg.httpport.value)
-               self.lastError = None
-               if VlcControlHttp.defaultStreamName is None:
-                       try:
-                               ip = getLocalHostIP( (cfg.host.value, cfg.httpport.value) )
-                               VlcControlHttp.defaultStreamName = "dream" + str(ip)
-                       except Exception, e:
-                               VlcControlHttp.defaultStreamName = "dreambox"
-
-       def connect(self):
-               pass
-
-       def close(self):
-               pass
-       
-       def xmlRequest(self, request, params):
-               uri = "/requests/"+request+".xml"
-               if params is not None: uri = uri + "?" + urlencode(params)
-               #print "[VLC] SEND:", self.host+uri
-               resp = urlopen("http://"+self.host+uri)
-               return parse(resp)
-
-       def playfile(self, filename, output):
-               filename = filename.replace("\\", "\\\\")
-               filename = filename.replace("'", "\\'")
-               input = filename
-               if output is not None:
-                       input += " :sout=" + output;
-               print "[VLC] playfile", input
-               xml = self.xmlRequest("status", {"command": "in_play", "input": input})
-               error = xml.getElementsByTagName("error")
-               if error is not None and len(error) > 0:
-                       self.lastError = getText(error[0].childNodes).strip()
-                       if len(self.lastError) == 0:
-                               self.lastError = None
-                       else:
-                               print "[VLC] VlcControl error:", self.lastError
-               else:
-                       self.lastError = None
-               return self.lastError
-
-       def status(self):
-               xml = self.xmlRequest("status", None)
-               stats = {}
-               for e in xml.documentElement.childNodes:
-                       if e.nodeType == e.ELEMENT_NODE:
-                               if e.firstChild is None:
-                                       stats[e.nodeName.encode("latin_1", "replace")] = None
-                               else:
-                                       stats[e.nodeName.encode("latin_1", "replace")] = e.firstChild.nodeValue.encode("latin_1", "replace")
-               return stats
-
-       def get_playlist(self):
-               xml = self.xmlRequest("playlist", None)
-               flist = []
-               for e in xml.getElementsByTagName("leaf"):
-                       fentry = {}
-                       fentry["id"] = int(e.getAttribute("id"))
-                       fentry["current"] = e.hasAttribute("current")
-                       if e.hasAttribute("uri") is not None:
-                               fentry["name"] = e.getAttribute("uri").encode("latin_1", "replace")
-                       flist.append(fentry)
-               return flist
-       
-       def get_current_id(self):
-               flist = self.get_playlist()
-               for f in flist:
-                       if f["current"]:
-                               return f["id"]
-               return -1
-
-       def play(self, listid=None):
-               if listid is None:
-                       self.xmlRequest("status", {"command": "pl_pause"})
-               else:
-                       self.xmlRequest("status", {"command": "pl_play", "id": str(listid)})
-               
-       def stop(self):
-               self.xmlRequest("status", {"command": "pl_stop"})
-
-       def pause(self):
-               self.xmlRequest("status", {"command": "pl_pause"})
-               
-       def delete(self, listid=None):
-               if listid is None:
-                       listid = self.get_current_id()
-               self.xmlRequest("status", {"command": "pl_delete", "id": str(listid)})
-               
-       def seek(self, value):
-               """  Allowed values are of the form:
-  [+ or -][<int><H or h>:][<int><M or m or '>:][<int><nothing or S or s or ">]
-  or [+ or -]<int>%
-  (value between [ ] are optional, value between < > are mandatory)
-examples:
-  1000 -> seek to the 1000th second
-  +1H:2M -> seek 1 hour and 2 minutes forward
-  -10% -> seek 10% back"""
-               self.xmlRequest("status", {"command": "seek", "val": str(value)})
-               
+# -*- coding: ISO-8859-1 -*-\r
+#===============================================================================\r
+# VLC Player Plugin by A. Lätsch 2007\r
+#\r
+# This is free software; you can redistribute it and/or modify it under\r
+# the terms of the GNU General Public License as published by the Free\r
+# Software Foundation; either version 2, or (at your option) any later\r
+# version.\r
+#===============================================================================\r
+\r
+from urllib import urlencode\r
+from urllib2 import urlopen\r
+from xml.dom.minidom import parse\r
+from Components.config import config\r
+from socket import socket as socket_socket, AF_INET as socket_AF_INET, SOCK_STREAM as socket_SOCK_STREAM\r
+import re\r
+\r
+def getText(nodelist):\r
+       if nodelist is None:\r
+               return None\r
+       rc = ""\r
+       for node in nodelist:\r
+               if node.nodeType == node.TEXT_NODE:\r
+                       rc = rc + node.data\r
+       return rc\r
+\r
+def getLocalHostIP( remote = ("www.python.org", 80)):\r
+       '''Get the "public" address of the local machine, i.e.\r
+       that address which is connected to the general internet.\r
+       Code by Donn Cave, posted to comp.lang.python'''\r
+       s = socket_socket(socket_AF_INET, socket_SOCK_STREAM)\r
+       s.connect( remote )\r
+       ip, localport = s.getsockname()\r
+       s.close()\r
+       return ip\r
+\r
+class VlcControlHttp:\r
+       defaultStreamName = None\r
+       \r
+       def __init__(self, servernum):\r
+               cfg = config.plugins.vlcplayer.servers[servernum]\r
+               self.servercfg = cfg\r
+               self.host = cfg.host.value + ":" + str(cfg.httpport.value)\r
+               self.lastError = None\r
+               if VlcControlHttp.defaultStreamName is None:\r
+                       try:\r
+                               ip = getLocalHostIP( (cfg.host.value, cfg.httpport.value) )\r
+                               VlcControlHttp.defaultStreamName = "dream" + str(ip)\r
+                       except Exception, e:\r
+                               VlcControlHttp.defaultStreamName = "dreambox"\r
+\r
+       def connect(self):\r
+               pass\r
+\r
+       def close(self):\r
+               pass\r
+       \r
+       def xmlRequest(self, request, params):\r
+               uri = "/requests/"+request+".xml"\r
+               if params is not None: uri = uri + "?" + urlencode(params)\r
+               #print "[VLC] SEND:", self.host+uri\r
+               resp = urlopen("http://"+self.host+uri)\r
+               return parse(resp)\r
+\r
+       def playfile(self, filename, output):\r
+               # workaround for VLC on Windows: subtitle files are not found, if path is\r
+               # written with '/' instead of '\' on Windows. Detect a Windows pathname if\r
+               # it starts with a drive-letter like "C:"\r
+               if re.match("[a-zA-Z]:", filename):\r
+                       filename = filename.replace("/", "\\")\r
+               filename = filename.replace("\\", "\\\\")\r
+               filename = filename.replace("'", "\\'")\r
+               input = filename\r
+               if output is not None:\r
+                       input += " :sout=" + output;\r
+               print "[VLC] playfile", input\r
+               xml = self.xmlRequest("status", {"command": "in_play", "input": input})\r
+               error = xml.getElementsByTagName("error")\r
+               if error is not None and len(error) > 0:\r
+                       self.lastError = getText(error[0].childNodes).strip()\r
+                       if len(self.lastError) == 0:\r
+                               self.lastError = None\r
+                       else:\r
+                               print "[VLC] VlcControl error:", self.lastError\r
+               else:\r
+                       self.lastError = None\r
+               return self.lastError\r
+\r
+       def status(self):\r
+               xml = self.xmlRequest("status", None)\r
+               stats = {}\r
+               for e in xml.documentElement.childNodes:\r
+                       if e.nodeType == e.ELEMENT_NODE:\r
+                               if e.firstChild is None:\r
+                                       stats[e.nodeName.encode("utf8", "replace")] = None\r
+                               else:\r
+                                       stats[e.nodeName.encode("utf8", "replace")] = e.firstChild.nodeValue.encode("utf8", "replace")\r
+               return stats\r
+       \r
+       def getStreamInfo(self):\r
+               xml = self.xmlRequest("status", None)\r
+               si = []\r
+               infoElem = xml.getElementsByTagName("information")\r
+               if infoElem is None:\r
+                       return None\r
+               infoElem = infoElem[0]\r
+               for e in infoElem.getElementsByTagName("category"):\r
+                       info = { "Name": e.getAttribute("name").encode("utf8", "replace") }\r
+                       for i in e.getElementsByTagName("info"):\r
+                               info[i.getAttribute("name").encode("utf8", "replace")] = getText(i.childNodes).encode("utf8", "replace")\r
+                       si.append(info)\r
+               return si\r
+\r
+       def get_playlist(self):\r
+               xml = self.xmlRequest("playlist", None)\r
+               flist = []\r
+               for e in xml.getElementsByTagName("leaf"):\r
+                       fentry = {}\r
+                       fentry["id"] = int(e.getAttribute("id"))\r
+                       fentry["current"] = e.hasAttribute("current")\r
+                       if e.hasAttribute("uri") is not None:\r
+                               fentry["name"] = e.getAttribute("uri").encode("latin_1", "replace")\r
+                       flist.append(fentry)\r
+               return flist\r
+       \r
+       def get_current_id(self):\r
+               flist = self.get_playlist()\r
+               for f in flist:\r
+                       if f["current"]:\r
+                               return f["id"]\r
+               return -1\r
+\r
+       def play(self, listid=None):\r
+               if listid is None:\r
+                       self.xmlRequest("status", {"command": "pl_pause"})\r
+               else:\r
+                       self.xmlRequest("status", {"command": "pl_play", "id": str(listid)})\r
+               \r
+       def stop(self):\r
+               self.xmlRequest("status", {"command": "pl_stop"})\r
+\r
+       def pause(self):\r
+               self.xmlRequest("status", {"command": "pl_pause"})\r
+               \r
+       def delete(self, listid=None):\r
+               if listid is None:\r
+                       listid = self.get_current_id()\r
+               self.xmlRequest("status", {"command": "pl_delete", "id": str(listid)})\r
+               \r
+       def seek(self, value):\r
+               """  Allowed values are of the form:\r
+  [+ or -][<int><H or h>:][<int><M or m or '>:][<int><nothing or S or s or ">]\r
+  or [+ or -]<int>%\r
+  (value between [ ] are optional, value between < > are mandatory)\r
+examples:\r
+  1000 -> seek to the 1000th second\r
+  +1H:2M -> seek 1 hour and 2 minutes forward\r
+  -10% -> seek 10% back"""\r
+               self.xmlRequest("status", {"command": "seek", "val": str(value)})\r
+       \r
+       def next(self):\r
+               self.xmlRequest("status", {"command": "pl_next"})\r
+       \r
+       def previous(self):\r
+               self.xmlRequest("status", {"command": "pl_previous"})\r