code: public synchronized String publish(SdpType sdpType, String sdpString, boolean doLoopback,
  			MediaElement loopbackAlternativeSrc, MediaType loopbackConnectionType) {
  		registerOnIceCandidateEventListener(this.getOwner().getParticipantPublicId());
  		if (doLoopback) {
  			if (loopbackAlternativeSrc == null) {
  				connect(this.getEndpoint(), loopbackConnectionType);
  			} else {
  				connectAltLoopbackSrc(loopbackAlternativeSrc, loopbackConnectionType);
  			}
  		} else {
  			innerConnect();
  		}
  		String sdpResponse = null;
  		switch (sdpType) {
  		case ANSWER:
  			sdpResponse = processAnswer(sdpString);
  			break;
  		case OFFER:
  			sdpResponse = processOffer(sdpString);
  			break;
  		default:
  			throw new OpenViduException(Code.MEDIA_SDP_ERROR_CODE, "Sdp type not supported: " + sdpType);
  		}
  		gatherCandidates();
  		this.createdAt = System.currentTimeMillis();
  		return sdpResponse;
  	}
docs: Initializes this media endpoint for publishing media and processes the SDP
  offer or answer. If the internal endpoint is an {@link WebRtcEndpoint}, it
  first registers an event listener for the ICE candidates and instructs the
  endpoint to start gathering the candidates. If required, it connects to
  itself (after applying the intermediate media elements and the
  {@link PassThrough}) to allow loopback of the media stream.
  
  @param sdpType                indicates the type of the sdpString (offer or
  answer)
  @param sdpString              offer or answer from the remote peer
  @param doLoopback             loopback flag
  @param loopbackAlternativeSrc alternative loopback source
  @param loopbackConnectionType how to connect the loopback source
  @return the SDP response (the answer if processing an offer SDP, otherwise is
  the updated offer generated previously by this endpoint)