From: Roman Bazalevsky Date: Fri, 23 Oct 2015 05:10:09 +0000 (+0300) Subject: Добавлено отладочный интерфейс. X-Git-Url: https://git.rvb.name/vpproxy.git/commitdiff_plain/8960711387d2b34c7f8b8d8a0cc036e52c6c6f06?ds=sidebyside;hp=f4c36b837c66078d1dd496481b82439377d5709a Добавлено отладочный интерфейс. Запрещено кеширование потоков на стороне клиента. Добавлен перезапуск VLC в случае отсутствия передаваемых данных. --- diff --git a/plugins/debug_plugin.py b/plugins/debug_plugin.py new file mode 100644 index 0000000..ffa0079 --- /dev/null +++ b/plugins/debug_plugin.py @@ -0,0 +1,60 @@ +__author__ = 'rvb' +''' +Local Playlist Plugin +(based on ytv plugin by ValdikSS) + +plsylist index + +http://ip:port/index + +m3u playlists + +http://ip:port/m3u +http://ip:port/m3u/ +http://ip:port/m3u/list-name + +plain-tet channel names + +http://ip:port/list +http://ip:port/list/ +http://ip:port/list/list-name + +forward to player + +http://ip:port/play/channel-name +http://ip:port/play/list-name/channel-name +http://ip:port/play/{list-name}/(get|mp4|webm)/channel-name + +''' +import logging +import gc +from modules.PluginInterface import VPProxyPlugin +import os +from guppy import hpy +h = hpy() + +class Debug(VPProxyPlugin): + + handlers = ('debug',) + + logger = logging.getLogger('mem_debug') + + def handle(self, connection): + + connection.send_response(200) + connection.send_header('Content-Type', 'text/plain') + connection.end_headers() + + gc.set_debug(gc.DEBUG_LEAK) + + connection.wfile.write('{} objects collected\n'.format(gc.collect())) + + connection.wfile.write(h.heap()) + + def getparam(self, key): + if key in self.params: + return self.params[key][0] + else: + return None + + \ No newline at end of file diff --git a/plugins/m3u_plugin.py b/plugins/m3u_plugin.py index 90f529f..2ea921a 100644 --- a/plugins/m3u_plugin.py +++ b/plugins/m3u_plugin.py @@ -38,7 +38,7 @@ import os class M3u(VPProxyPlugin): - handlers = ('m3u', 'm3ut', 'm3uw', "list", "play", "index") + handlers = ('m3u', 'm3ut', 'm3uw', 'list', 'play', 'index') logger = logging.getLogger('plugin_m3u') playlist = None diff --git a/plugins/m3u_plugin.py~ b/plugins/m3u_plugin.py~ new file mode 100644 index 0000000..3d2de5c --- /dev/null +++ b/plugins/m3u_plugin.py~ @@ -0,0 +1,171 @@ +__author__ = 'rvb' +''' +Local Playlist Plugin +(based on ytv plugin by ValdikSS) + +plsylist index + +http://ip:port/index + +m3u playlists + +http://ip:port/m3u +http://ip:port/m3u/ +http://ip:port/m3u/list-name + +plain-tet channel names + +http://ip:port/list +http://ip:port/list/ +http://ip:port/list/list-name + +forward to player + +http://ip:port/play/channel-name +http://ip:port/play/list-name/channel-name +http://ip:port/play/{list-name}/(get|mp4|webm)/channel-name + +''' +import json +import logging +import urlparse +import urllib +from modules.PluginInterface import VPProxyPlugin +from modules.PlaylistGenerator import PlaylistGenerator +from modules.M3uParser import parseM3U +import config.m3u as config +import os + +class M3u(VPProxyPlugin): + + handlers = ('m3u', 'm3ut', 'm3uw', "list", "play", "index") + + logger = logging.getLogger('plugin_m3u') + playlist = None + + def handle(self, connection): + + hostport = connection.headers['Host'] + + self.splitted_path=connection.path.split('/') + + if self.splitted_path[1]=='m3u': + prefix='get' + elif self.splitted_path[1]=='m3uw': + prefix='ogg' + elif self.splitted_path[1]=='m3ut': + prefix='mp4' + elif self.splitted_path[1] in ("list","play","index"): + None + else: + connection.dieWithError(404) + + if len(self.splitted_path)>3 and self.splitted_path[1]!="play": + connection.dieWithError() + return + + if self.splitted_path[1]=='index': + + for dir in os.walk(config.m3u_directory): + if dir[0]==config.m3u_directory: + text='\n'.join(dir[2]) + + connection.send_response(200) + connection.send_header('Content-Type', 'text/plain; charset=utf-8') + connection.end_headers() + + listing = text.encode('utf-8') + connection.wfile.write(listing) + + return + + if len(self.splitted_path)<3 or (len(self.splitted_path)==3 and self.splitted_path[1]=="play"): + + m3u_file=config.m3u_directory+'/'+config.m3u_default + + else: + + filename = self.splitted_path[2] + if filename: + m3u_file=config.m3u_directory+'/'+self.splitted_path[2] + else: + m3u_file=config.m3u_directory+'/'+config.m3u_default + + try: + playlist=parseM3U(m3u_file) + except: + connection.dieWithError(404) + return + + if self.splitted_path[1]=="list": + connection.send_response(200) + connection.send_header('Content-Type', 'text/plain; charset=utf-8') + connection.end_headers() + elif self.splitted_path[1]=="play": + channel=self.splitted_path[len(self.splitted_path)-1] + channel=urllib.unquote(channel).decode('utf-8') + if len(self.splitted_path)<=4: + prefix="get" + elif len(self.splitted_path)==5: + prefix=self.splitted_path[len(self.splitted_path)-2] + if prefix not in ('get','mp4','webm'): + connection.dieWithError() + else: + connection.dieWithError() + url=None + for record in playlist: + if record.title.decode('utf-8').replace('/','')==channel: + url=record.path.decode('utf-8') + if url: + redirect='/'+prefix+'/'+url + connection.send_response(302) + connection.send_header('Location', redirect) + connection.end_headers() + else: + connection.dieWithError(404) + + else: + connection.send_response(200) + connection.send_header('Content-Type', 'application/x-mpegurl') + connection.end_headers() + + try: + playlist=parseM3U(m3u_file) + except: + connection.dieWithError(404) + return + + if not playlist: + connection.dieWithError() + return + + if self.splitted_path[1]=="list": + + exported = "" + + for record in playlist: + if record.title: + exported = exported + "" + record.title.decode('utf-8').replace('/','') + "\n" + + else: + + playlistgen = PlaylistGenerator() + + for record in playlist: + print record + channel=dict() + channel['name']=record.title.decode('utf-8') + channel['url']=record.path.decode('utf-8') + playlistgen.addItem(channel) + + exported = playlistgen.exportm3u(hostport,prefix) + + exported = exported.encode('utf-8') + + connection.wfile.write(exported) + + def getparam(self, key): + if key in self.params: + return self.params[key][0] + else: + return None diff --git a/vphttp.py b/vphttp.py index bda3485..0a6ae43 100644 --- a/vphttp.py +++ b/vphttp.py @@ -27,6 +27,7 @@ import hashlib import vpconfig from vpconfig import VPConfig import vlcclient +import gc import plugins.modules.ipaddr as ipaddr from clientcounter import ClientCounter from plugins.modules.PluginInterface import VPProxyPlugin @@ -235,6 +236,7 @@ class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler): logger.debug( "Sending fake headers for " + useragent) self.send_response(200) + self.send_header('Cache-Control','no-cache'); if self.reqtype=="ogg": self.send_header("Content-Type", "video/ogg") else: @@ -295,6 +297,8 @@ class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler): for key in self.video.info().dict: self.send_header(key, self.video.info().dict[key]) + self.send_header('Cache-Control','no-cache'); + if self.reqtype=="ogg": self.send_header("Content-Type", "video/ogg") else: @@ -335,7 +339,11 @@ class HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler): except: pass self.vp.destroy() - + if not self.headersent: + logger.error("Problem receiving video stream, no headers!") + if VPStuff.clientcounter.total == 0: + logger.error("Probably VLC hang") + VPStuff.vlc.kill() class HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): @@ -402,6 +410,7 @@ for i in pluginslist: continue logger.debug('Plugin loaded: ' + plugname) for j in plugininstance.handlers: + logger.info("Registering handler '" + j +"'") VPStuff.pluginshandlers[j] = plugininstance VPStuff.pluginlist.append(plugininstance)