Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- import sys
- import subprocess
- import tornado.httpserver
- import tornado.ioloop
- import tornado.web
- import signal
- import shlex
- import os
- class Ring:
- def __init__( self, packets = 100 ):
- self.packets = packets
- self.queue = [ ]
- self.read = 0
- self.write = 0
- self.closed = False
- def put( self, data ):
- if self.closed: return
- if self.write % self.packets == len( self.queue ):
- self.queue.append( data )
- else:
- self.queue[ self.write % self.packets ] = data
- self.write += 1
- def get( self ):
- if self.closed and self.read >= self.write: return ''
- result = self.queue[ self.read % self.packets ]
- self.queue[ self.read % self.packets ] = None
- self.read += 1
- return result
- def has( self ):
- return self.read < self.write
- def close( self ):
- self.closed = True
- def done( self ):
- return self.closed
- class stream_handler( tornado.web.RequestHandler ):
- @tornado.web.asynchronous
- def get( self ):
- url = self.get_argument( 'url', '' )
- if url != "":
- self.ring = Ring( packets )
- self.call_subprocess( shlex.split( str( backend % url ) ) )
- tornado.ioloop.IOLoop.instance( ).add_callback( self.callback )
- else:
- self.write( 'Content-Type: text/plain\n' )
- self.write( 'Unable to handle request' )
- def callback( self ):
- try:
- if self.ring.has( ):
- data = self.ring.get( )
- if len( data ) == 0: return
- self.write( data )
- self.flush( )
- if not self.ring.done( ) or self.ring.has( ):
- tornado.ioloop.IOLoop.instance( ).add_callback( self.callback )
- except:
- pass
- def call_subprocess( self, command ):
- self.ioloop = tornado.ioloop.IOLoop.instance( )
- self.pipe = subprocess.Popen( command, stdin = subprocess.PIPE, stdout = subprocess.PIPE, close_fds = True )
- self.ioloop.add_handler( self.pipe.stdout.fileno( ), self.async_callback( self.on_subprocess_result, None ), self.ioloop.READ )
- def on_subprocess_result(self, callback, fd, result):
- try:
- data = self.pipe.stdout.read( 10240 )
- if len( data ) == 0:
- self.ring.close( )
- self.ioloop.remove_handler( fd )
- else:
- self.ring.put( data )
- except:
- self.ioloop.remove_handler( fd )
- self.ring.close( )
- def on_connection_close( self ):
- self.ring.close( )
- self.pipe.stdout.close( )
- self.pipe.kill( )
- port = 57740
- packets = 50000
- size = 10240
- backend = 'ffmpeg -i "%s" -s 640x360 -deinterlace -f mpegts -qscale 2 -vcodec mpeg4 pipe:'
- if __name__ == "__main__":
- signal.signal( signal.SIGCHLD, signal.SIG_IGN )
- application = tornado.web.Application( [ ( r"/stream", stream_handler ), ] )
- http_server = tornado.httpserver.HTTPServer( application, no_keep_alive=True )
- http_server.listen( port )
- tornado.ioloop.IOLoop.instance( ).start( )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement