<div dir="ltr"><div>Hi, <br>I'm writing a test video distributor tool for serving gstreamer mpeg-ts and mjpeg streams over http connection. I'm using python basehttpserver and gstreamer as core parts. I got over initial connection part very fast, I can actually watch video from a number of vlc players just fine. However when one of the players disconnect, I get 100% cpu usage for my tool and socket still open due to some thread locking I think... ( since both httpserver and handle loop intend to run in foreground). How can I solve this issue?<br><br></div>I don't now if it's good practice to include source at email nor I don't now what's the policy on file attachments on this list, so I tried to minimize the example. This code distributes the test pipeline over http very well but fails to handle disconnects. Thanks in advance!<br><br>import gi<br>gi.require_version('Gst', '1.0')<br>from gi.repository import GObject, Gio, Gst<br><br>Gst.init(None)<br>GObject.threads_init()<br><br><br>class gst_broadcaster:<br>       <br>    def __init__(self):<br>        self.pipeline = Gst.parse_launch('videotestsrc name=source ! videoconvert ! videorate ! jpegenc name=encode ! multipartmux name=mux ! multisocketsink name=sink')<br>        self.source = self.pipeline.get_by_name('source')<br>        self.mux = self.pipeline.get_by_name('mux')<br>        self.sink = self.pipeline.get_by_name('sink')<br>        self.bus = self.pipeline.get_bus()<br>        self.bus.add_signal_watch()<br>        self.bus.connect('message',self.message_handler)<br>        self.sink.connect('client-added',self.add_client)<br>        self.sink.connect('client-socket-removed',self.remove_client)<br>        self.clients = []<br>        self.pipeline.set_state(Gst.State.READY)<br><br><br>    def kill(self):<br>        self.pipeline.set_state(Gst.State.NULL)<br>    <br>    def handles(self):<br>        return self.sink.get_property('num-handles')<br>    <br>    def add_client(self,sink,gsock):<br>        print 'Adding client socket:', gsock<br>        self.pipeline.set_state(Gst.State.PLAYING)<br>        self.clients.append(gsock)<br><br>    def remove_client(self,sink,gsock):<br>        print 'Removing socket:',gsock<br>        self.sink.emit('remove-flush',gsock)<br>        if gsock in self.clients:<br>            self.clients.remove(gsock)<br>    <br>    def handle(self, wfile):<br>        client_id = Gio.Socket().new_from_fd(wfile.fileno())<br>        print 'adding'<br>        self.sink.emit("add", client_id)<br>        while client_id in self.clients:<br>            print 'Waiting'<br>            time.sleep(1)<br>            #self.sink.emit("remove-flush", client_id)<br>            <br>    def cleanup(self,client_addr):<br>        if client_addr in self.clients:<br>            self.clients.remove(client_addr)<br>    <br>    def message_handler(self,bus,message):<br>        msgType = message.type<br>        if msgType == Gst.MessageType.ERROR:<br>            self.kill()<br>            print "\n Unable to play Video. Error: ", \<br>            message.parse_error()<br>        elif msgType == Gst.MessageType.EOS:<br>            self.kill()<br><br><br>player =  gst_broadcaster()<br>    <br>class GetHandler(BaseHTTPRequestHandler):<br>    <br>    <br>    def do_GET(self):<br>        self.send_response(200)<br>        self.send_header("Content-type", "multipart/x-mixed-replace")<br>        self.end_headers()<br>        print self.client_address<br>        try:<br>            print 'Adding handle'<br>            player.handle(self.wfile)<br>        except:<br>            print 'Exception'<br>            self.wfile = StringIO()<br>            <br><br><br>class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):<br>    """Handle requests in a separate thread."""<br>    <br>class ForkingHTTPServer(ForkingMixIn,HTTPServer):<br>    """Handle requests in a separate process."""<br><br>def http_server():<br>    server = ThreadedHTTPServer(('0.0.0.0', 8080), GetHandler)<br>    print 'Starting http server\n'<br>    server.serve_forever()<br><br>http_server()<br><br></div>