--- /dev/null
+AceProxy: Ace Stream HTTP Proxy
+===============================
+AceProxy allows you to watch [Ace Stream](http://acestream.org/) live streams or BitTorrent files over HTTP.
+It's written in Python + gevent and should work on both Linux and Windows (Mac OS should work too, but was not tested)
+
+Currently it supports Ace Stream Content-ID hashes (PIDs), .acestream files and usual torrent files.
+
+**For installation, configuration and using info, visit** [Wiki](https://github.com/ValdikSS/aceproxy/wiki)
else:
return False
+ print "Total:", self.total
return self.clients[id][0]
class M3u(VPProxyPlugin):
- handlers = ('m3u', )
+ handlers = ('m3u', 'm3ut' )
logger = logging.getLogger('plugin_m3u')
playlist = None
self.splitted_path=connection.path.split('/')
+ if self.splitted_path[1]=='m3u':
+ prefix='get'
+ elif self.splitted_path[1]=='m3ut':
+ prefix='mp4'
+ else:
+ connection.dieWithError(404)
+
if len(self.splitted_path)>3:
connection.dieWithError()
return
try:
playlist=parseM3U(m3u_file)
except:
- connection.dieWithError()
+ connection.dieWithError(404)
return
if not playlist:
channel['url']=record.path.decode('utf-8')
playlistgen.addItem(channel)
- exported = playlistgen.exportm3u(hostport)
+ exported = playlistgen.exportm3u(hostport,prefix)
exported = exported.encode('utf-8')
connection.wfile.write(exported)
item.get('group', ''), item.get('tvg', ''), item.get('logo', ''),
item.get('name'), item.get('url'))
- def exportm3u(self, hostport, add_ts=False, empty_header=False, archive=False):
+ def exportm3u(self, hostport, prefix="get", add_ts=False, empty_header=False, archive=False):
'''
Exports m3u playlist
'''
item['tvg'] = item.get('tvg', '') if item.get('tvg') else \
item.get('name').replace(' ', '_')
# For .acelive and .torrent
- item['url'] = 'http://' + hostport + '/get/'+item['url']
+ item['url'] = 'http://' + hostport + '/' + prefix + '/' + item['url']
itemlist += PlaylistGenerator._generatem3uline(item)
return itemlist
except EOFError as e:
raise VlcException("Vlc Write error! ERROR: " + repr(e))
- def _broadcast(self, brtype, stream_name, input=None, muxer='ts', pre_access=''):
+ def _broadcast(self, brtype, stream_name, input=None, muxer='ts', pre_access='', qtype='default'):
if self._shuttingDown.isSet():
return
self._resultlock.acquire()
# Write message to VLC socket
if brtype == True:
- self._write(VlcMessage.request.startBroadcast(
- stream_name, input, self._out_port, muxer, pre_access))
+ msg = VlcMessage.request.startBroadcast(stream_name, input, self._out_port, muxer, pre_access, qtype)
+ self._write(msg)
else:
self._write(VlcMessage.request.stopBroadcast(stream_name))
else:
logger.debug("Broadcast stopped")
- def startBroadcast(self, stream_name, input, muxer='ts', pre_access=''):
- return self._broadcast(True, stream_name, input, muxer, pre_access)
+ def startBroadcast(self, stream_name, input, muxer='ts', pre_access='', qtype='default'):
+ print "Starting broadcast......"
+ return self._broadcast(True, stream_name, input, muxer, pre_access, qtype)
def stopBroadcast(self, stream_name):
return self._broadcast(False, stream_name)
SHUTDOWN = 'shutdown'
@staticmethod
- def startBroadcast(stream_name, input, out_port, muxer='ts', pre_access=''):
- return 'new "' + stream_name + '" broadcast input "' + input + '" output ' + (pre_access + ':' if pre_access else '#') + \
- 'http{mux=' + muxer + ',dst=:' + \
+ def startBroadcast(stream_name, input, out_port, muxer='ts', pre_access='',qtype='default'):
+ command = 'new "' + stream_name + '" broadcast input "' + input + '" output ' + (pre_access + ':' if pre_access else '#')
+ if qtype=='mp4':
+ command = command + 'transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128}:'
+ command = command +'http{mux=' + muxer + ',dst=:' + \
str(out_port) + '/' + stream_name + '} option sout-keep option sout-all enabled' + \
"\r\n" + 'control "' + stream_name + '" play'
+ return command
@staticmethod
def stopBroadcast(stream_name):
httpport = 8001
# If started as root, drop privileges to this user.
# Leave empty to disable.
- vpproxyuser = 'aceproxy'
+ vpproxyuser = 'vpproxy'
# Enable firewall
firewall = False
# Firewall mode. True for blackilst, False for whitelist
# Logging to a file
loggingtoafile = False
# Path for logs, default is current directory. For example '/tmp/'
- logpath = ''
+ logpath = '/var/log/vpproxy/'
#
# ----------------------------------------------------
# VLC configuration
# Spawn VLC automaticaly
vlcspawn = True
# VLC cmd line (use `--file-logging --logfile=filepath` to write log)
- vlccmd = "vlc -I telnet --clock-jitter -1 --network-caching -1 --sout-mux-caching 2000 --telnet-password admin --telnet-port 4212"
+ vlccmd = "vlc -I telnet --clock-jitter 0 --network-caching 500 --sout-mux-caching 2000 --telnet-password admin --telnet-port 4212"
# VLC spawn timeout
# Adjust this if you get error 'Cannot spawn VLC!'
- vlcspawntimeout = 4
+ vlcspawntimeout = 15
# VLC host
vlchost = '127.0.0.1'
# VLC telnet interface port
# before the headers sent.
# We send them 200 OK and MPEG MIME-type right after connection has been initiated
fakeheaderuas = ('HLS Client/2.0 (compatible; LG NetCast.TV-2012)',
- 'Mozilla/5.0 (DirectFB; Linux armv7l) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+ LG Browser/5.00.00(+mouse+3D+SCREEN+TUNER; LGE; 42LM670T-ZA; 04.41.03; 0x00000001;); LG NetCast.TV-2012 0'
+ 'Mozilla/5.0 (DirectFB; Linux armv7l) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+ LG Browser/5.00.00(+mouse+3D+SCREEN+TUNER; LGE; 42LM670T-ZA; 04.41.03; 0x00000001;); LG NetCast.TV-2012 0',
)
self.reqtype = self.splittedpath[1].lower()
# If first parameter is 'pid' or 'torrent' or it should be handled
# by plugin
- if not (self.reqtype=='get' or self.reqtype in VPStuff.pluginshandlers):
+ if not (self.reqtype in ('get','mp4') or self.reqtype in VPStuff.pluginshandlers):
self.dieWithError(400) # 400 Bad Request
return
except IndexError:
def handleRequest(self, headers_only):
# Limit concurrent connections
+ print VPStuff.clientcounter.total
if 0 < VPConfig.maxconns <= VPStuff.clientcounter.total:
logger.debug("Maximum connections reached, can't serve this")
self.dieWithError(503) # 503 Service Unavailable
# Pretend to work fine with Fake UAs or HEAD request.
useragent = self.headers.get('User-Agent')
+ logger.debug("HTTP User Agent:"+useragent)
fakeua = useragent and useragent in VPConfig.fakeuas
if headers_only or fakeua:
if fakeua:
self.params.append('0')
# Adding client to clientcounter
- clients = VPStuff.clientcounter.add(self.path_unquoted, self.clientip)
+ clients = VPStuff.clientcounter.add(self.reqtype+'\\'+self.path_unquoted, self.clientip)
# If we are the one client, but sucessfully got vp instance from clientcounter,
# then somebody is waiting in the videodestroydelay state
# Check if we are first client
- if VPStuff.clientcounter.get(self.path_unquoted)==1:
+ if VPStuff.clientcounter.get(self.reqtype+'\\'+self.path_unquoted)==1:
logger.debug("First client, should create VLC session")
shouldcreatevp = True
else:
logger.debug("Can reuse existing session")
shouldcreatevp = False
- self.vlcid = hashlib.md5(self.path_unquoted).hexdigest()
+ self.vlcid = hashlib.md5(self.reqtype+'\\'+self.path_unquoted).hexdigest()
# Send fake headers if this User-Agent is in fakeheaderuas tuple
if fakeua:
logger.debug("hangDetector spawned")
gevent.sleep()
- # Initializing VPClient
-
# Getting URL
self.errorhappened = False
- print shouldcreatevp
if shouldcreatevp:
logger.debug("Got url " + self.path_unquoted)
# Force ffmpeg demuxing if set in config
else:
self.vlcprefix = ''
+ logger.debug("Ready to start broadcast....")
VPStuff.vlcclient.startBroadcast(
- self.vlcid, self.vlcprefix + self.path_unquoted, VPConfig.vlcmux, VPConfig.vlcpreaccess)
+ self.vlcid, self.vlcprefix + self.path_unquoted, VPConfig.vlcmux, VPConfig.vlcpreaccess, self.reqtype)
# Sleep a bit, because sometimes VLC doesn't open port in
# time
gevent.sleep(0.5)
# Unknown exception
logger.error(traceback.format_exc())
self.errorhappened = True
- raise
self.dieWithError()
finally:
logger.debug("END REQUEST")
- VPStuff.clientcounter.delete(self.path_unquoted, self.clientip)
- if not VPStuff.clientcounter.get(self.path_unquoted):
+ VPStuff.clientcounter.delete(self.reqtype+'\\'+self.path_unquoted, self.clientip)
+ if not VPStuff.clientcounter.get(self.reqtype+'\\'+self.path_unquoted):
try:
logger.debug("That was the last client, destroying VPClient")
VPStuff.vlcclient.stopBroadcast(self.vlcid)
# Spawning procedures
def spawnVLC(cmd, delay = 0):
try:
- VPStuff.vlc = psutil.Popen(cmd, stdout=DEVNULL, stderr=DEVNULL)
+ VPStuff.vlc = psutil.Popen(cmd) #, stdout=DEVNULL, stderr=DEVNULL)
gevent.sleep(delay)
return True
except:
out_port=VPConfig.vlcoutport)
return True
except vlcclient.VlcException as e:
- print repr(e)
return False
def isRunning(process):