async def setRemoteDescription(self, sessionDescription):
        """
        Changes the remote description associated with the connection.

        :param: sessionDescription: An :class:`RTCSessionDescription` created from
                                    information received over the signaling channel.
        """
        # parse and validate description
        description = sdp.SessionDescription.parse(sessionDescription.sdp)
        description.type = sessionDescription.type
        self.__validate_description(description, is_local=False)

        # apply description
        trackEvents = []
        for i, media in enumerate(description.media):
            self.__seenMids.add(media.rtp.muxId)
            if media.kind in ['audio', 'video']:
                # find transceiver
                transceiver = None
                for t in self.__transceivers:
                    if t.kind == media.kind and t.mid in [None, media.rtp.muxId]:
                        transceiver = t
                if transceiver is None:
                    transceiver = self.__createTransceiver(direction='recvonly', kind=media.kind)
                if transceiver.mid is None:
                    transceiver._set_mid(media.rtp.muxId)
                    transceiver._set_mline_index(i)

                # negotiate codecs
                common = filter_preferred_codecs(
                    find_common_codecs(CODECS[media.kind], media.rtp.codecs),
                    transceiver._preferred_codecs)
                assert len(common)
                transceiver._codecs = common
                transceiver._headerExtensions = find_common_header_extensions(
                    HEADER_EXTENSIONS[media.kind], media.rtp.headerExtensions)

                # configure transport
                iceTransport = transceiver._transport.transport
                add_remote_candidates(iceTransport, media)
                self.__remoteDtls[transceiver] = media.dtls
                self.__remoteIce[transceiver] = media.ice

                # configure direction
                direction = reverse_direction(media.direction)
                if description.type in ['answer', 'pranswer']:
                    transceiver._currentDirection = direction
                else:
                    transceiver._offerDirection = direction

                # create remote stream track
                if direction in ['recvonly', 'sendrecv'] and not transceiver.receiver._track:
                    transceiver.receiver._track = RemoteStreamTrack(kind=media.kind)
                    trackEvents.append(RTCTrackEvent(
                        receiver=transceiver.receiver,
                        track=transceiver.receiver._track,
                        transceiver=transceiver,
                    ))

            elif media.kind == 'application':
                if not self.__sctp:
                    self.__createSctpTransport()
                if self.__sctp.mid is None:
                    self.__sctp.mid = media.rtp.muxId
                    self.__sctp_mline_index = i

                # configure sctp
                if media.profile == 'DTLS/SCTP':
                    self._sctpLegacySdp = True
                    self.__sctpRemotePort = int(media.fmt[0])
                else:
                    self._sctpLegacySdp = False
                    self.__sctpRemotePort = media.sctp_port
                self.__sctpRemoteCaps = media.sctpCapabilities

                # configure transport
                iceTransport = self.__sctp.transport.transport
                add_remote_candidates(iceTransport, media)
                self.__remoteDtls[self.__sctp] = media.dtls
                self.__remoteIce[self.__sctp] = media.ice

        # remove bundled transports
        bundle = next((x for x in description.group if x.semantic == 'BUNDLE'), None)
        if bundle and bundle.items:
            # find main media stream
            masterMid = bundle.items[0]
            masterTransport = None
            for transceiver in self.__transceivers:
                if transceiver.mid == masterMid:
                    masterTransport = transceiver._transport
                    break
            if self.__sctp and self.__sctp.mid == masterMid:
                masterTransport = self.__sctp.transport

            # replace transport for bundled media
            oldTransports = set()
            slaveMids = bundle.items[1:]
            for transceiver in self.__transceivers:
                if transceiver.mid in slaveMids and not transceiver._bundled:
                    oldTransports.add(transceiver._transport)
                    transceiver.receiver.setTransport(masterTransport)
                    transceiver.sender.setTransport(masterTransport)
                    transceiver._bundled = True
                    transceiver._transport = masterTransport
            if self.__sctp and self.__sctp.mid in slaveMids:
                oldTransports.add(self.__sctp.transport)
                self.__sctp.setTransport(masterTransport)
                self.__sctp._bundled = True

            # stop and discard old ICE transports
            for dtlsTransport in oldTransports:
                await dtlsTransport.stop()
                await dtlsTransport.transport.stop()
                self.__iceTransports.discard(dtlsTransport.transport)
            self.__updateIceGatheringState()
            self.__updateIceConnectionState()

        # FIXME: in aiortc 1.0.0 emit RTCTrackEvent directly
        for event in trackEvents:
            self.emit('track', event.track)

        # connect
        asyncio.ensure_future(self.__connect())

        # update signaling state
        if description.type == 'offer':
            self.__setSignalingState('have-remote-offer')
        elif description.type == 'answer':
            self.__setSignalingState('stable')

        # replace description
        if description.type == 'answer':
            self.__currentRemoteDescription = description
            self.__pendingRemoteDescription = None
        else:
            self.__pendingRemoteDescription = description
async def setRemoteDescription ( self , sessionDescription ) : description = sdp . SessionDescription . parse ( sessionDescription . sdp ) description . type = sessionDescription . type self . __validate_description ( description , is_local = False ) trackEvents = [ ] for i , media in enumerate ( description . media ) : self . __seenMids . add ( media . rtp . muxId ) if media . kind in [ 'audio' , 'video' ] : transceiver = None for t in self . __transceivers : if t . kind == media . kind and t . mid in [ None , media . rtp . muxId ] : transceiver = t if transceiver is None : transceiver = self . __createTransceiver ( direction = 'recvonly' , kind = media . kind ) if transceiver . mid is None : transceiver . _set_mid ( media . rtp . muxId ) transceiver . _set_mline_index ( i ) common = filter_preferred_codecs ( find_common_codecs ( CODECS [ media . kind ] , media . rtp . codecs ) , transceiver . _preferred_codecs ) assert len ( common ) transceiver . _codecs = common transceiver . _headerExtensions = find_common_header_extensions ( HEADER_EXTENSIONS [ media . kind ] , media . rtp . headerExtensions ) iceTransport = transceiver . _transport . transport add_remote_candidates ( iceTransport , media ) self . __remoteDtls [ transceiver ] = media . dtls self . __remoteIce [ transceiver ] = media . ice direction = reverse_direction ( media . direction ) if description . type in [ 'answer' , 'pranswer' ] : transceiver . _currentDirection = direction else : transceiver . _offerDirection = direction if direction in [ 'recvonly' , 'sendrecv' ] and not transceiver . receiver . _track : transceiver . receiver . _track = RemoteStreamTrack ( kind = media . kind ) trackEvents . append ( RTCTrackEvent ( receiver = transceiver . receiver , track = transceiver . receiver . _track , transceiver = transceiver , ) ) elif media . kind == 'application' : if not self . __sctp : self . __createSctpTransport ( ) if self . __sctp . mid is None : self . __sctp . mid = media . rtp . muxId self . __sctp_mline_index = i if media . profile == 'DTLS/SCTP' : self . _sctpLegacySdp = True self . __sctpRemotePort = int ( media . fmt [ 0 ] ) else : self . _sctpLegacySdp = False self . __sctpRemotePort = media . sctp_port self . __sctpRemoteCaps = media . sctpCapabilities iceTransport = self . __sctp . transport . transport add_remote_candidates ( iceTransport , media ) self . __remoteDtls [ self . __sctp ] = media . dtls self . __remoteIce [ self . __sctp ] = media . ice bundle = next ( ( x for x in description . group if x . semantic == 'BUNDLE' ) , None ) if bundle and bundle . items : masterMid = bundle . items [ 0 ] masterTransport = None for transceiver in self . __transceivers : if transceiver . mid == masterMid : masterTransport = transceiver . _transport break if self . __sctp and self . __sctp . mid == masterMid : masterTransport = self . __sctp . transport oldTransports = set ( ) slaveMids = bundle . items [ 1 : ] for transceiver in self . __transceivers : if transceiver . mid in slaveMids and not transceiver . _bundled : oldTransports . add ( transceiver . _transport ) transceiver . receiver . setTransport ( masterTransport ) transceiver . sender . setTransport ( masterTransport ) transceiver . _bundled = True transceiver . _transport = masterTransport if self . __sctp and self . __sctp . mid in slaveMids : oldTransports . add ( self . __sctp . transport ) self . __sctp . setTransport ( masterTransport ) self . __sctp . _bundled = True for dtlsTransport in oldTransports : await dtlsTransport . stop ( ) await dtlsTransport . transport . stop ( ) self . __iceTransports . discard ( dtlsTransport . transport ) self . __updateIceGatheringState ( ) self . __updateIceConnectionState ( ) for event in trackEvents : self . emit ( 'track' , event . track ) asyncio . ensure_future ( self . __connect ( ) ) if description . type == 'offer' : self . __setSignalingState ( 'have-remote-offer' ) elif description . type == 'answer' : self . __setSignalingState ( 'stable' ) if description . type == 'answer' : self . __currentRemoteDescription = description self . __pendingRemoteDescription = None else : self . __pendingRemoteDescription = description
Changes the remote description associated with the connection.

        :param: sessionDescription: An :class:`RTCSessionDescription` created from
                                    information received over the signaling channel.