Пример #1
0
    def __init__(self, id):
        super(ServerSocket, self).__init__(name='serversoc ')
        self.connection = None
        self.id = id
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            # close gracefully from this end
            l_onoff = 1
            l_linger = 0
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                                   struct.pack('ii', l_onoff, l_linger))
            # and detect peers that didn't close gracefully with a reset
            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            self.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 2)
            self.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 2)
            self.socket.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 2)
            self.socket.bind((util.local_ip(), 0))
            self.socket.listen(1)
        except socket.error as e:
            if e.errno == 98:  # Address already in use
                log.critical(str(e) + ' - cant start')
                raise e
        except Exception as e:
            log.critical('serversocket %s caught %s' % (self.id, str(e)))

        self.start()
Пример #2
0
    def run(self):
        while not self.terminated:
            time.sleep(0.1)

            if self.server_lost_time < time.time():
                log.critical('server lost')
                self.server_lost_time = time.time() + self.SERVER_LOST_SECONDS
Пример #3
0
    def construct_pipeline(self):
        if self.pipeline:
            self.pipeline.set_state(Gst.State.NULL)

        try:
            # playing a sine wave through this source (always remember the volume or be prepared for a wakeup call):
            # gst-launch-1.0 audiotestsrc freq=1000 volume=0.004 is-live=true ! audioconvert ! audio/x-raw, channels=2 !
            # faac ! aacparse ! avmux_adts ! tcpclientsink host=<hostname> port=4666
            #
            # for playing the pipeline above directly on a second command line (without the server running):
            # gst-launch-1.0 tcpserversrc host=<hostname> port=4666 ! decodebin ! audioconvert ! alsasink
            #
            ip = util.local_ip()
            pipeline = 'tcpserversrc host=%s port=%i ! appsink name=appsink emit-signals=true sync=false' % \
                       (ip, self.port)

            log.info('launching %s pipeline listening at %s:%i' %
                     (self.name, ip, self.port))
            self.pipeline = Gst.parse_launch(pipeline)

            appsink = self.pipeline.get_by_name('appsink')
            appsink.connect('new-sample', self.new_sample)

            bus = self.pipeline.get_bus()
            bus.add_signal_watch()
            bus.enable_sync_message_emission()
            bus.connect('message', self.bus_message)

            self.pipeline.set_state(Gst.State.PLAYING)

        except Exception as e:
            log.critical("couldn't construct pipeline, %s" % str(e))
Пример #4
0
    def construct_pipeline(self):
        try:
            if self.config['device']:
                device = 'device=%s' % self.config['device']
            else:
                device = ''

            pipeline = 'alsasrc %s ! ' \
                       'cutter name=cutter leaky=false run-length=%i threshold-dB=%f ! ' \
                       'faac ! aacparse ! avmux_adts ! appsink name=appsink' % \
                       (device,
                        int(float(self.config['timeout']) * util.NS_IN_SEC),
                        float(self.config['threshold_dB']))

            log.info('launching pipeline listening to alsa %s' % device)
            self.pipeline = Gst.parse_launch(pipeline)

            appsink = self.pipeline.get_by_name('appsink')
            appsink.set_property('emit-signals', True)
            appsink.connect('new-sample', self.new_sample)

            bus = self.pipeline.get_bus()
            bus.add_signal_watch()
            bus.enable_sync_message_emission()
            bus.connect('message', self.bus_message)
            bus.connect('message::element', self.cutter_message)

            self.pipeline.set_state(Gst.State.PLAYING)

        except Exception as e:
            log.critical("[%s] couldn't construct pipeline, %s" %
                         (self.name, str(e)))
Пример #5
0
def parse(data):
    _json = None
    _audio = None
    if len(data) < header_length:
        return data, _json, _audio

    length = struct.unpack('!H', data[0:2])[0]
    type = struct.unpack_from('!B', data, 2)[0]
    _serial = struct.unpack_from('!B', data, 3)[0]

    data_length = len(data)

    if data_length >= length + header_length:
        payload = data[header_length:header_length + length]

        if type == Payload.AUDIO.value:
            if trace_packets:
                log.info('rx audio serial %i - %i bytes' % (_serial, data_length - header_length))
            _audio = payload
        elif type == Payload.JSON.value:
            if trace_packets:
                log.info('rx json serial %i - %i bytes' % (_serial, data_length - header_length))
            _json = json.loads(payload.decode())
        elif type == Payload.FLUSHING.value:
            if trace_packets:
                log.info('rx flushing serial %i - %i bytes' % (_serial, data_length - header_length))
            pass
        else:
            log.critical('got malformed data, %i bytes' % len(data))
            log.critical(' '.join(format(x, '02x') for x in data[:min(500, len(data))]))
            raise util.MalformedPacketException
        data = data[header_length + length:]

    return data, _json, _audio
Пример #6
0
    def state_changed(self, new_state):
        global AudioQueue

        if new_state == group.State.BUFFERING:
            self.silence_samples = 0
            self.silence_samples_pending = 0
            self.silence_samples_sent = 0
            self.development_audio_drop_prescaler = 100

        if self.m_state != new_state:
            log.debug('state changing from %s to %s' %
                      (self.m_state, new_state))
            self.m_state = new_state
            play_groups = self.playing_groups()

            for _group in play_groups:
                if new_state == group.State.BUFFERING:
                    _group.send({'runtime': {'command': 'buffering'}})
                elif new_state == group.State.STOPPED:
                    _group.stop_playing()
                elif new_state == group.State.PLAYING:
                    _group.start_playing()
                else:
                    log.critical('internal error #0082')
        else:
            log.debug('ignoring a state change request from %s to %s' %
                      (self.m_state, new_state))
Пример #7
0
    def run(self):
        try:
            log.debug('player starting')

            while not self.terminated:
                time.sleep(0.1)

                if self.server_audio_state != ServerAudioState.STOPPED:
                    self.pipeline_silence_monitor()

                if self.last_status_time and (
                        time.time() - self.last_status_time > 2.0):
                    if self.playing_start_time and self.is_playing():
                        self.print_stats()

                    if self.bytes_per_sec and self.nof_bps_messages:
                        self.nof_bps_messages -= 1
                        log.debug(
                            'receiving %i bytes/sec%s' %
                            (int(self.bytes_per_sec / 2.0),
                             '' if self.nof_bps_messages else ' (automute)'))
                        self.bytes_per_sec = 0

                    self.last_status_time += 2.0

        except Exception as e:
            log.critical('player thread exception %s' % str(e))

        log.debug('player exits')
Пример #8
0
 def handleConnected(self):
     try:
         log.info('new websocket connection from %s' % self.address[0])
         clients.append(self)
         emitter.send_message(self, {'command': 'connected'})
     except Exception as e:
         log.critical('exception in handleConnected: %s' % str(e))
Пример #9
0
    def set_play_time(self, play_time_ns):
        """
        :param play_time_ns: the wall clock at which playing should start
        :return: False if the play time wasn't set
        """
        try:
            now_ns = time.time() * util.NS_IN_SEC

            # If the server and client clocks are too far off then we might end up with a negative
            # relative playing start time which gstreamer understandably refuses to accept. If this is
            # the case then bail out now.
            if play_time_ns <= now_ns:
                log.critical(
                    'unable to start audio %3.1f seconds ago, server and client times are not in sync'
                    % (now_ns - play_time_ns))
                return False

            # Another sign of clock mismatches will be a start time too far in the future. For now it
            # will be a relative start time more than 1 second from now that triggers a log error.
            # For now don't bail out on this one.
            if play_time_ns > now_ns + util.NS_IN_SEC:
                log.error(
                    'will start audio in %3.1f seconds, server and client times are not in sync ?'
                    % (now_ns - play_time_ns))

            self.filter_pipeline.set_base_time(
                self.filter_pipeline.get_pipeline_clock().get_time() +
                play_time_ns - time.time() * util.NS_IN_SEC)
        except Exception as e:
            log.error(f'got fatal exception {e}')
            log.error(
                f'{self.filter_pipeline.get_pipeline_clock().get_time()} + {play_time_ns} - {time.time() * util.NS_IN_SEC}'
            )
            raise e
        return True
Пример #10
0
    def run(self):
        try:
            while not self.terminated:
                try:
                    event = self.input_mux.event_poll()
                except queue.Empty:
                    continue

                key = event['key']
                value = event['value']

                if key == 'audio':
                    self.play_sequencer.new_audio(value)
                elif key == 'codec':
                    self.play_sequencer.set_codec(value)
                elif key == 'state':
                    self.play_sequencer.set_state(value)
                elif key == 'volume':
                    self.play_sequencer.set_volume(value)
                else:
                    log.critical('got an unknown key %s' % key)

        except Exception as e:
            log.critical("server loop caught exception '%s'" % str(e))
            self.terminate()

        log.debug('server exits')
Пример #11
0
def execute(command):
    # log.debug('NOT executing "%s"' % command)
    # return 0

    ret = subprocess.run(command, shell=True)
    if ret.returncode:
        log.critical('command failed with exitcode %i' % ret.returncode)
    return ret.returncode
Пример #12
0
 def ctrl_c_handler(_, __):
     try:
         print(' ctrl-c handler')
         if _client:
             log.info('terminating by user')
             _client.terminate()
             _client.join()
         sys.exit(1)
     except Exception as e:
         log.critical('ctrl-c handler got ' + str(e))
Пример #13
0
 def handleMessage(self):
     global emitter
     try:
         data = self.data
         log.debug('websocket message: %s' % data)
         message = json.loads(data)
         message['ip'] = self.address[0]
         emitter.emit('message', message)
     except Exception as e:
         log.critical('exception in handleMessage: %s' % str(e))
Пример #14
0
    def cutter_message(self, bus, message):
        try:
            if message.has_name("cutter"):
                above = message.get_structure().get_value('above')
                if above:
                    self.emit('status', 'rt_play')
                else:
                    self.emit('status', 'rt_stop')

        except Exception as e:
            log.critical('[%s] parsing cutter message gave "%s"' % (self.name, str(e)))
Пример #15
0
 def bus_message(self, bus, message):
     if message.type == Gst.MessageType.EOS:
         log.debug('EOS')
     elif message.type == Gst.MessageType.ERROR:
         err, deb = message.parse_error()
         log.critical("pipeline error: %s '%s'" % (err, deb))
         self.emit('status', 'pipeline_error')
     elif message.type == Gst.MessageType.STATE_CHANGED:
         old_state, new_state, pending_state = message.parse_state_changed()
         if message.src == self.pipeline:
             log.debug('* pipeline state changed to %s' % Gst.Element.state_get_name(new_state))
Пример #16
0
 def ctrl_c_handler(_, __):
     try:
         print(' ctrl-c handler')
         if _server:
             log.info('terminating by user')
             _server.terminate()
             log.debug('terminate done, waiting..')
             _server.join()
         sys.exit(1)
     except Exception as e:
         log.critical('ctrl-c handler got ' + str(e))
Пример #17
0
    def cutter_message(self, bus, message):
        try:
            if message.has_name("cutter"):
                above = message.get_structure().get_value('above')
                if not above and self.is_playing:
                    self.stop_playing()
                elif above and not self.is_playing:
                    self.start_playing()

        except Exception as e:
            log.critical('[%s] parsing cutter message gave "%s"' %
                         (self.name, str(e)))
Пример #18
0
 def multicast_rx(self, message):
     command = message['command']
     if command == 'server_socket':
         if not self.socket:
             endpoint = message['endpoint']
             if endpoint == "None":
                 log.critical("server refused the connection (check the group and device name)")
                 time.sleep(1)
                 util.die('exiting..', 1, True)
             log.info('server found, connecting to %s' % endpoint)
             self.server_endpoint = util.split_tcp(endpoint)
             self.start_socket()
Пример #19
0
    def server_connector(self):
        delay = 0.1
        connected = False
        while not self.terminated:
            if self.terminate_socket:
                self.socket_lock.acquire()
                self.terminate_socket = False
                if self.socket:
                    self.socket.join()
                    self.socket = None
                self.server_endpoint = None
                self.player.process_server_message({'runtime': {'command': 'stopping'}})
                log.info('waiting for server connection')
                self.server_offline_counter = 10
                self.socket_lock.release()
                if connected:
                    self.hwctrl.connected_to_server(False)
                    connected = False

            if not self.server_endpoint:
                if connected:
                    self.hwctrl.connected_to_server(False)
                    connected = False

                if self.server_offline_counter:
                    self.server_offline_counter -= 1
                    if not self.server_offline_counter:
                        log.critical('server seems to be offline')
                try:
                    self.multicast.send({'command': 'get_server_socket',
                                         'to': 'server',
                                         'from': self.id,
                                         'version': util.LUDIT_VERSION})
                except OSError:
                    log.warning('got a multicast send exception. Bummer.')

                if delay < 5.0:
                    delay += 0.1
            else:
                if not connected:
                    self.hwctrl.connected_to_server(True)
                    connected = True

                delay = 0.1

            _delay = delay
            while _delay > 0.0 and not self.terminated:
                time.sleep(0.1)
                _delay -= 0.1

        log.debug('server connector exits')
        return False
Пример #20
0
    def launch_playsequencer(self):
        try:
            log.info('launching playsequencer')
            if self.play_sequencer:
                self.play_sequencer.terminate()

            self.play_sequencer = playsequencer.PlaySequencer(
                self.configuration)
            self.play_sequencer.connect('allgroupsdisconnected',
                                        self.all_groups_disconnected)
            self.cant_play_warning = 5
        except Exception as e:
            log.critical('playsequencer failed with %s' % str(e))
Пример #21
0
def transfer_to_game(cmd, request, conn):
    conn_id = conn.get('id', None)
    conn_ip = conn.get('ip', None)
    conn_port = conn.get('port', None)

    # logger.debug('cmd:%s', cmd)
    # 登录消息绑定这些
    if cmd == 1001:
        # 组装传到内部的消息
        request = dict(
            body=request,
            connid=conn_id,
            ip=conn_ip,
        )
    # 为了适配微信登录和绑定
    elif cmd == 1002:
        uin = FireflyMap().get_user_by_conn(conn_id)
        request = dict(
            body=request,
            connid=conn_id,
            ip=conn_ip,
            uin=uin,
        )
    elif cmd >= 4001:
        # 内部消息不做任何处理
        if cmd == proto.CMD_TIME_OUT_CHECK:
            pass
        else:
            # 没有inner说明是外部消息
            if not isinstance(request, dict) or 'inner' not in request:
                uin = FireflyMap().get_user_by_conn(conn_id)
                if not uin:
                    logger.critical('not found user, cmd:%s, conn_id:%s, ip:%s, port:%s', cmd, conn_id, conn_ip, conn_port)
                    return
                request = dict(
                    body=request,
                    uin=uin,
                )
    # 到时候调试好了记得把desk加进来
    # if 9999 >= cmd >= 7001:
    #     request['desk'] =

    # 分发消息到game server
    if cmd in range(1001, 4001):
        return GlobalObject().root.callChild("_auth_", "auth_function_" + str(cmd), request)
    elif cmd in range(4001, 7001):
        return GlobalObject().root.callChild("_hall_", "hall_function_" + str(cmd), request)
    elif cmd in range(7001, 10001):
        return GlobalObject().root.callChild("_play_", "play_function_" + str(cmd), request)
    elif cmd in range(10001, 13001):
        return GlobalObject().root.callChild("_common_", "common_function_" + str(cmd), request)
Пример #22
0
    def run(self):
        while not self.terminated:
            try:
                self.loop.run_until_complete(self.ws_listen())
            except ConnectionRefusedError:
                pass
            except websockets.ConnectionClosed:
                log.info('mopidy websocket was closed')
            except Exception as e:
                log.critical('unexpected exception in sourcemopidy, %s' % str(e))

            time.sleep(1)

        log.debug('sourcemopidy exits')
Пример #23
0
    async def ws_listen(self):

        address = util.tcp2str((self.mopidy_address, self.mopidy_port))

        async with websockets.connect('ws://%s/mopidy/ws' % address) as self.ws:
            try:
                log.info('connected to mopidy websocket')
                while 1:
                    response = await self.ws.recv()
                    message = json.loads(response)
                    event = message['event']

                    try:
                        uri = message['tl_track']['track']['uri']
                    except KeyError:
                        uri = ''

                    if event == 'track_playback_started':
                        log.info('mopidy started ' + uri)
                        self.start_playing()
                    elif event == 'track_playback_ended':
                        log.info('mopidy stopped ' + uri)
                        self.stop_playing()
                    elif event == 'track_playback_paused':
                        log.info('mopidy paused ' + uri)
                        self.stop_playing()
                    elif event == 'track_playback_resumed':
                        log.info('mopidy resumes ' + uri)
                        self.start_playing()
                    elif event == 'playback_state_changed':
                        old_state = message['old_state']
                        new_state = message['new_state']
                        log.info('mopidy state change from %s to %s' % (old_state, new_state))
                    elif event == 'volume_changed':
                        volume = message['volume']
                        if volume != self.volume:
                            self.volume = volume
                            log.info('mopidy volume %i' % volume)
                            self.new_volume(volume)
                    elif event == 'tracklist_changed':
                        pass
                    else:
                        log.info('mopidy event not recognized: %s' % message)
            except Exception as e:
                log.critical('sourcespotify caught %s' % str(e))
                raise e

            log.debug('sourcemopidy websocket exits')
Пример #24
0
    def run(self):
        while not self.terminated:
            try:
                time.sleep(0.1)
                if self.timeout_counter:
                    self.timeout_counter -= 1
                    if not self.timeout_counter:
                        log.warning(
                            'timeout from source "%s", no data for 4 seconds' %
                            self.now_playing)
                        self.stop_playing()

            except Exception as e:
                log.critical('exception in inputmux, %s' % str(e))

        log.debug('inputmux exits')
Пример #25
0
    def run(self):
        try:
            while not self.terminated:
                self.construct_pipeline()

                while not self.eos and not self.terminated:
                    time.sleep(0.1)

                if self.eos:
                    self.send_event('state', 'stop')
                    self.eos = False

        except Exception as e:
            log.critical("source %s exception '%s'" %
                         (self.source_name(), str(e)))
            self.terminate()

        log.debug('sourcetcp exits')
Пример #26
0
    def bus_message(self, bus, message):
        try:
            if message.type == Gst.MessageType.EOS:
                log.debug('EOS')
            elif message.type == Gst.MessageType.ERROR:
                err, deb = message.parse_error()
                log.critical("pipeline error: %s '%s'" % (err, deb))
                self.send_event('status', 'pipeline_error')
            elif message.type == Gst.MessageType.STATE_CHANGED:
                old_state, new_state, pending_state = message.parse_state_changed(
                )
                if message.src == self.pipeline:
                    log.debug('pipeline state changed to %s' %
                              Gst.Element.state_get_name(new_state))

        except Exception as e:
            log.critical('[%s] parsing bus message gave "%s"' %
                         (self.name, str(e)))
Пример #27
0
 def state_changed(self, new_state):
     global AudioQueue
     if self.m_state != new_state:
         log.debug('state changing from %s to %s' %
                   (self.m_state, new_state))
         self.m_state = new_state
         now = time.time()
         for _group in self.playing_groups():
             if new_state == group.State.BUFFERING:
                 _group.send({'runtime': {'command': 'buffering'}})
             elif new_state == group.State.STOPPED:
                 _group.stop_playing()
             elif new_state == group.State.PLAYING:
                 _group.start_playing(now)
             else:
                 log.critical('internal error #0082')
     else:
         log.debug('ignoring a state change request from %s to %s' %
                   (self.m_state, new_state))
Пример #28
0
    def run(self):
        try:
            while not self.terminated:
                try:
                    data = self.socket.recv(1024)
                except socket.timeout:
                    continue

                message = json.loads(data)
                try:
                    self.emit('socket_receive', message)
                except Exception as e:
                    log.critical('emit message failed with %s' % str(e))

        except Exception as e:
            log.critical('multicast got ' + str(e))

        self.socket.close()
        log.debug('multicast exits')
Пример #29
0
    def run(self):
        try:
            log.debug('player starting')

            while not self.terminated:
                time.sleep(0.1)

                if self.server_audio_state != ServerAudioState.STOPPED:
                    self.pipeline_monitor()

                    if (self.is_playing() and self.last_status_time
                            and (time.time() - self.last_status_time > 2)):
                        self.last_status_time = time.time()
                        self.print_stats()

        except Exception as e:
            log.critical('player thread exception %s' % str(e))

        log.debug('player exits')
Пример #30
0
    def process_message(self, message):
        command = message['command']

        if command == 'setcodec':
            self.codec = message['codec']
            log.info("setting codec to '%s'" % self.codec)
            self.realtime = False
            self.start_pipelines()

        elif command == 'setvolume':
            volume = int(message['volume']) / 127.0
            log.debug('setting volume %.3f' % volume)
            self.set_volume(volume)

        elif command == 'configure' or command == 'setparam':
            param = message['param']
            self.set_pipeline_parameter(param)

        else:
            log.critical("got unknown server command '%s'" % command)