All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.webrtc.PeerConnection Maven / Gradle / Ivy

There is a newer version: 2.3.3.1
Show newest version
/*
 *  Copyright 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

package org.webrtc;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

/**
 * Java-land version of the PeerConnection APIs; wraps the C++ API
 * http://www.webrtc.org/reference/native-apis, which in turn is inspired by the
 * JS APIs: http://dev.w3.org/2011/webrtc/editor/webrtc.html and
 * http://www.w3.org/TR/mediacapture-streams/
 */
public class PeerConnection {
  /** Tracks PeerConnectionInterface::IceGatheringState */
  public enum IceGatheringState {
    NEW,
    GATHERING,
    COMPLETE;

    @CalledByNative("IceGatheringState")
    static IceGatheringState fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  /** Tracks PeerConnectionInterface::IceConnectionState */
  public enum IceConnectionState {
    NEW,
    CHECKING,
    CONNECTED,
    COMPLETED,
    FAILED,
    DISCONNECTED,
    CLOSED;

    @CalledByNative("IceConnectionState")
    static IceConnectionState fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  /** Tracks PeerConnectionInterface::TlsCertPolicy */
  public enum TlsCertPolicy {
    TLS_CERT_POLICY_SECURE,
    TLS_CERT_POLICY_INSECURE_NO_CHECK,
  }

  /** Tracks PeerConnectionInterface::SignalingState */
  public enum SignalingState {
    STABLE,
    HAVE_LOCAL_OFFER,
    HAVE_LOCAL_PRANSWER,
    HAVE_REMOTE_OFFER,
    HAVE_REMOTE_PRANSWER,
    CLOSED;

    @CalledByNative("SignalingState")
    static SignalingState fromNativeIndex(int nativeIndex) {
      return values()[nativeIndex];
    }
  }

  /** Java version of PeerConnectionObserver. */
  public static interface Observer {
    /** Triggered when the SignalingState changes. */
    @CalledByNative("Observer") void onSignalingChange(SignalingState newState);

    /** Triggered when the IceConnectionState changes. */
    @CalledByNative("Observer") void onIceConnectionChange(IceConnectionState newState);

    /** Triggered when the ICE connection receiving status changes. */
    @CalledByNative("Observer") void onIceConnectionReceivingChange(boolean receiving);

    /** Triggered when the IceGatheringState changes. */
    @CalledByNative("Observer") void onIceGatheringChange(IceGatheringState newState);

    /** Triggered when a new ICE candidate has been found. */
    @CalledByNative("Observer") void onIceCandidate(IceCandidate candidate);

    /** Triggered when some ICE candidates have been removed. */
    @CalledByNative("Observer") void onIceCandidatesRemoved(IceCandidate[] candidates);

    /** Triggered when media is received on a new stream from remote peer. */
    @CalledByNative("Observer") void onAddStream(MediaStream stream);

    /** Triggered when a remote peer close a stream. */
    @CalledByNative("Observer") void onRemoveStream(MediaStream stream);

    /** Triggered when a remote peer opens a DataChannel. */
    @CalledByNative("Observer") void onDataChannel(DataChannel dataChannel);

    /** Triggered when renegotiation is necessary. */
    @CalledByNative("Observer") void onRenegotiationNeeded();

    /**
     * Triggered when a new track is signaled by the remote peer, as a result of
     * setRemoteDescription.
     */
    @CalledByNative("Observer") void onAddTrack(RtpReceiver receiver, MediaStream[] mediaStreams);

    /**
     * Triggered when the signaling from SetRemoteDescription indicates that a transceiver
     * will be receiving media from a remote endpoint. This is only called if UNIFIED_PLAN
     * semantics are specified. The transceiver will be disposed automatically.
     */
    @CalledByNative("Observer") default void onTrack(RtpTransceiver transceiver){};
  }

  /** Java version of PeerConnectionInterface.IceServer. */
  public static class IceServer {
    // List of URIs associated with this server. Valid formats are described
    // in RFC7064 and RFC7065, and more may be added in the future. The "host"
    // part of the URI may contain either an IP address or a hostname.
    @Deprecated public final String uri;
    public final List urls;
    public final String username;
    public final String password;
    public final TlsCertPolicy tlsCertPolicy;

    // If the URIs in |urls| only contain IP addresses, this field can be used
    // to indicate the hostname, which may be necessary for TLS (using the SNI
    // extension). If |urls| itself contains the hostname, this isn't
    // necessary.
    public final String hostname;

    // List of protocols to be used in the TLS ALPN extension.
    public final List tlsAlpnProtocols;

    // List of elliptic curves to be used in the TLS elliptic curves extension.
    // Only curve names supported by OpenSSL should be used (eg. "P-256","X25519").
    public final List tlsEllipticCurves;

    /** Convenience constructor for STUN servers. */
    @Deprecated
    public IceServer(String uri) {
      this(uri, "", "");
    }

    @Deprecated
    public IceServer(String uri, String username, String password) {
      this(uri, username, password, TlsCertPolicy.TLS_CERT_POLICY_SECURE);
    }

    @Deprecated
    public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy) {
      this(uri, username, password, tlsCertPolicy, "");
    }

    @Deprecated
    public IceServer(String uri, String username, String password, TlsCertPolicy tlsCertPolicy,
        String hostname) {
      this(uri, Collections.singletonList(uri), username, password, tlsCertPolicy, hostname, null,
          null);
    }

    private IceServer(String uri, List urls, String username, String password,
        TlsCertPolicy tlsCertPolicy, String hostname, List tlsAlpnProtocols,
        List tlsEllipticCurves) {
      if (uri == null || urls == null || urls.isEmpty()) {
        throw new IllegalArgumentException("uri == null || urls == null || urls.isEmpty()");
      }
      for (String it : urls) {
        if (it == null) {
          throw new IllegalArgumentException("urls element is null: " + urls);
        }
      }
      if (username == null) {
        throw new IllegalArgumentException("username == null");
      }
      if (password == null) {
        throw new IllegalArgumentException("password == null");
      }
      if (hostname == null) {
        throw new IllegalArgumentException("hostname == null");
      }
      this.uri = uri;
      this.urls = urls;
      this.username = username;
      this.password = password;
      this.tlsCertPolicy = tlsCertPolicy;
      this.hostname = hostname;
      this.tlsAlpnProtocols = tlsAlpnProtocols;
      this.tlsEllipticCurves = tlsEllipticCurves;
    }

    @Override
    public String toString() {
      return urls + " [" + username + ":" + password + "] [" + tlsCertPolicy + "] [" + hostname
          + "] [" + tlsAlpnProtocols + "] [" + tlsEllipticCurves + "]";
    }

    public static Builder builder(String uri) {
      return new Builder(Collections.singletonList(uri));
    }

    public static Builder builder(List urls) {
      return new Builder(urls);
    }

    public static class Builder {
      @Nullable private final List urls;
      private String username = "";
      private String password = "";
      private TlsCertPolicy tlsCertPolicy = TlsCertPolicy.TLS_CERT_POLICY_SECURE;
      private String hostname = "";
      private List tlsAlpnProtocols;
      private List tlsEllipticCurves;

      private Builder(List urls) {
        if (urls == null || urls.isEmpty()) {
          throw new IllegalArgumentException("urls == null || urls.isEmpty(): " + urls);
        }
        this.urls = urls;
      }

      public Builder setUsername(String username) {
        this.username = username;
        return this;
      }

      public Builder setPassword(String password) {
        this.password = password;
        return this;
      }

      public Builder setTlsCertPolicy(TlsCertPolicy tlsCertPolicy) {
        this.tlsCertPolicy = tlsCertPolicy;
        return this;
      }

      public Builder setHostname(String hostname) {
        this.hostname = hostname;
        return this;
      }

      public Builder setTlsAlpnProtocols(List tlsAlpnProtocols) {
        this.tlsAlpnProtocols = tlsAlpnProtocols;
        return this;
      }

      public Builder setTlsEllipticCurves(List tlsEllipticCurves) {
        this.tlsEllipticCurves = tlsEllipticCurves;
        return this;
      }

      public IceServer createIceServer() {
        return new IceServer(urls.get(0), urls, username, password, tlsCertPolicy, hostname,
            tlsAlpnProtocols, tlsEllipticCurves);
      }
    }

    @Nullable
    @CalledByNative("IceServer")
    List getUrls() {
      return urls;
    }

    @Nullable
    @CalledByNative("IceServer")
    String getUsername() {
      return username;
    }

    @Nullable
    @CalledByNative("IceServer")
    String getPassword() {
      return password;
    }

    @CalledByNative("IceServer")
    TlsCertPolicy getTlsCertPolicy() {
      return tlsCertPolicy;
    }

    @Nullable
    @CalledByNative("IceServer")
    String getHostname() {
      return hostname;
    }

    @CalledByNative("IceServer")
    List getTlsAlpnProtocols() {
      return tlsAlpnProtocols;
    }

    @CalledByNative("IceServer")
    List getTlsEllipticCurves() {
      return tlsEllipticCurves;
    }
  }

  /** Java version of PeerConnectionInterface.IceTransportsType */
  public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }

  /** Java version of PeerConnectionInterface.BundlePolicy */
  public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }

  /** Java version of PeerConnectionInterface.RtcpMuxPolicy */
  public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }

  /** Java version of PeerConnectionInterface.TcpCandidatePolicy */
  public enum TcpCandidatePolicy { ENABLED, DISABLED }

  /** Java version of PeerConnectionInterface.CandidateNetworkPolicy */
  public enum CandidateNetworkPolicy { ALL, LOW_COST }

  // Keep in sync with webrtc/rtc_base/network_constants.h.
  public enum AdapterType {
    UNKNOWN,
    ETHERNET,
    WIFI,
    CELLULAR,
    VPN,
    LOOPBACK,
  }

  /** Java version of rtc::KeyType */
  public enum KeyType { RSA, ECDSA }

  /** Java version of PeerConnectionInterface.ContinualGatheringPolicy */
  public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }

  /** Java version of rtc::IntervalRange */
  public static class IntervalRange {
    private final int min;
    private final int max;

    public IntervalRange(int min, int max) {
      this.min = min;
      this.max = max;
    }

    @CalledByNative("IntervalRange")
    public int getMin() {
      return min;
    }

    @CalledByNative("IntervalRange")
    public int getMax() {
      return max;
    }
  }

  /**
   * Java version of webrtc::SdpSemantics.
   *
   * Configure the SDP semantics used by this PeerConnection. Note that the
   * WebRTC 1.0 specification requires UNIFIED_PLAN semantics. The
   * RtpTransceiver API is only available with UNIFIED_PLAN semantics.
   *
   * 

PLAN_B will cause PeerConnection to create offers and answers with at * most one audio and one video m= section with multiple RtpSenders and * RtpReceivers specified as multiple a=ssrc lines within the section. This * will also cause PeerConnection to ignore all but the first m= section of * the same media type. * *

UNIFIED_PLAN will cause PeerConnection to create offers and answers with * multiple m= sections where each m= section maps to one RtpSender and one * RtpReceiver (an RtpTransceiver), either both audio or both video. This * will also cause PeerConnection to ignore all but the first a=ssrc lines * that form a Plan B stream. * *

For users who wish to send multiple audio/video streams and need to stay * interoperable with legacy WebRTC implementations, specify PLAN_B. * *

For users who wish to send multiple audio/video streams and/or wish to * use the new RtpTransceiver API, specify UNIFIED_PLAN. */ public enum SdpSemantics { PLAN_B, UNIFIED_PLAN } /** Java version of PeerConnectionInterface.RTCConfiguration */ // TODO(qingsi): Resolve the naming inconsistency of fields with/without units. public static class RTCConfiguration { public IceTransportsType iceTransportsType; public List iceServers; public BundlePolicy bundlePolicy; public RtcpMuxPolicy rtcpMuxPolicy; public TcpCandidatePolicy tcpCandidatePolicy; public CandidateNetworkPolicy candidateNetworkPolicy; public int audioJitterBufferMaxPackets; public boolean audioJitterBufferFastAccelerate; public int iceConnectionReceivingTimeout; public int iceBackupCandidatePairPingInterval; public KeyType keyType; public ContinualGatheringPolicy continualGatheringPolicy; public int iceCandidatePoolSize; public boolean pruneTurnPorts; public boolean presumeWritableWhenFullyRelayed; // The following fields define intervals in milliseconds at which ICE // connectivity checks are sent. // // We consider ICE is "strongly connected" for an agent when there is at // least one candidate pair that currently succeeds in connectivity check // from its direction i.e. sending a ping and receives a ping response, AND // all candidate pairs have sent a minimum number of pings for connectivity // (this number is implementation-specific). Otherwise, ICE is considered in // "weak connectivity". // // Note that the above notion of strong and weak connectivity is not defined // in RFC 5245, and they apply to our current ICE implementation only. // // 1) iceCheckIntervalStrongConnectivityMs defines the interval applied to // ALL candidate pairs when ICE is strongly connected, // 2) iceCheckIntervalWeakConnectivityMs defines the counterpart for ALL // pairs when ICE is weakly connected, and // 3) iceCheckMinInterval defines the minimal interval (equivalently the // maximum rate) that overrides the above two intervals when either of them // is less. @Nullable public Integer iceCheckIntervalStrongConnectivityMs; @Nullable public Integer iceCheckIntervalWeakConnectivityMs; @Nullable public Integer iceCheckMinInterval; // The time period in milliseconds for which a candidate pair must wait for response to // connectivitiy checks before it becomes unwritable. @Nullable public Integer iceUnwritableTimeMs; // The minimum number of connectivity checks that a candidate pair must sent without receiving // response before it becomes unwritable. @Nullable public Integer iceUnwritableMinChecks; // The interval in milliseconds at which STUN candidates will resend STUN binding requests // to keep NAT bindings open. // The default value in the implementation is used if this field is null. @Nullable public Integer stunCandidateKeepaliveIntervalMs; public boolean disableIPv6OnWifi; // By default, PeerConnection will use a limited number of IPv6 network // interfaces, in order to avoid too many ICE candidate pairs being created // and delaying ICE completion. // // Can be set to Integer.MAX_VALUE to effectively disable the limit. public int maxIPv6Networks; @Nullable public IntervalRange iceRegatherIntervalRange; // These values will be overridden by MediaStream constraints if deprecated constraints-based // create peerconnection interface is used. public boolean disableIpv6; public boolean enableDscp; public boolean enableCpuOveruseDetection; public boolean enableRtpDataChannel; public boolean suspendBelowMinBitrate; @Nullable public Integer screencastMinBitrate; @Nullable public Boolean combinedAudioVideoBwe; @Nullable public Boolean enableDtlsSrtp; // Use "Unknown" to represent no preference of adapter types, not the // preference of adapters of unknown types. public AdapterType networkPreference; public SdpSemantics sdpSemantics; // This is an optional wrapper for the C++ webrtc::TurnCustomizer. @Nullable public TurnCustomizer turnCustomizer; // Actively reset the SRTP parameters whenever the DTLS transports underneath are reset for // every offer/answer negotiation.This is only intended to be a workaround for crbug.com/835958 public boolean activeResetSrtpParams; // TODO(deadbeef): Instead of duplicating the defaults here, we should do // something to pick up the defaults from C++. The Objective-C equivalent // of RTCConfiguration does that. public RTCConfiguration(List iceServers) { iceTransportsType = IceTransportsType.ALL; bundlePolicy = BundlePolicy.BALANCED; rtcpMuxPolicy = RtcpMuxPolicy.REQUIRE; tcpCandidatePolicy = TcpCandidatePolicy.ENABLED; candidateNetworkPolicy = CandidateNetworkPolicy.ALL; this.iceServers = iceServers; audioJitterBufferMaxPackets = 50; audioJitterBufferFastAccelerate = false; iceConnectionReceivingTimeout = -1; iceBackupCandidatePairPingInterval = -1; keyType = KeyType.ECDSA; continualGatheringPolicy = ContinualGatheringPolicy.GATHER_ONCE; iceCandidatePoolSize = 0; pruneTurnPorts = false; presumeWritableWhenFullyRelayed = false; iceCheckIntervalStrongConnectivityMs = null; iceCheckIntervalWeakConnectivityMs = null; iceCheckMinInterval = null; iceUnwritableTimeMs = null; iceUnwritableMinChecks = null; stunCandidateKeepaliveIntervalMs = null; disableIPv6OnWifi = false; maxIPv6Networks = 5; iceRegatherIntervalRange = null; disableIpv6 = false; enableDscp = false; enableCpuOveruseDetection = true; enableRtpDataChannel = false; suspendBelowMinBitrate = false; screencastMinBitrate = null; combinedAudioVideoBwe = null; enableDtlsSrtp = null; networkPreference = AdapterType.UNKNOWN; sdpSemantics = SdpSemantics.PLAN_B; activeResetSrtpParams = false; } @CalledByNative("RTCConfiguration") IceTransportsType getIceTransportsType() { return iceTransportsType; } @CalledByNative("RTCConfiguration") List getIceServers() { return iceServers; } @CalledByNative("RTCConfiguration") BundlePolicy getBundlePolicy() { return bundlePolicy; } @CalledByNative("RTCConfiguration") RtcpMuxPolicy getRtcpMuxPolicy() { return rtcpMuxPolicy; } @CalledByNative("RTCConfiguration") TcpCandidatePolicy getTcpCandidatePolicy() { return tcpCandidatePolicy; } @CalledByNative("RTCConfiguration") CandidateNetworkPolicy getCandidateNetworkPolicy() { return candidateNetworkPolicy; } @CalledByNative("RTCConfiguration") int getAudioJitterBufferMaxPackets() { return audioJitterBufferMaxPackets; } @CalledByNative("RTCConfiguration") boolean getAudioJitterBufferFastAccelerate() { return audioJitterBufferFastAccelerate; } @CalledByNative("RTCConfiguration") int getIceConnectionReceivingTimeout() { return iceConnectionReceivingTimeout; } @CalledByNative("RTCConfiguration") int getIceBackupCandidatePairPingInterval() { return iceBackupCandidatePairPingInterval; } @CalledByNative("RTCConfiguration") KeyType getKeyType() { return keyType; } @CalledByNative("RTCConfiguration") ContinualGatheringPolicy getContinualGatheringPolicy() { return continualGatheringPolicy; } @CalledByNative("RTCConfiguration") int getIceCandidatePoolSize() { return iceCandidatePoolSize; } @CalledByNative("RTCConfiguration") boolean getPruneTurnPorts() { return pruneTurnPorts; } @CalledByNative("RTCConfiguration") boolean getPresumeWritableWhenFullyRelayed() { return presumeWritableWhenFullyRelayed; } @Nullable @CalledByNative("RTCConfiguration") Integer getIceCheckIntervalStrongConnectivity() { return iceCheckIntervalStrongConnectivityMs; } @Nullable @CalledByNative("RTCConfiguration") Integer getIceCheckIntervalWeakConnectivity() { return iceCheckIntervalWeakConnectivityMs; } @Nullable @CalledByNative("RTCConfiguration") Integer getIceCheckMinInterval() { return iceCheckMinInterval; } @Nullable @CalledByNative("RTCConfiguration") Integer getIceUnwritableTimeout() { return iceUnwritableTimeMs; } @Nullable @CalledByNative("RTCConfiguration") Integer getIceUnwritableMinChecks() { return iceUnwritableMinChecks; } @Nullable @CalledByNative("RTCConfiguration") Integer getStunCandidateKeepaliveInterval() { return stunCandidateKeepaliveIntervalMs; } @CalledByNative("RTCConfiguration") boolean getDisableIPv6OnWifi() { return disableIPv6OnWifi; } @CalledByNative("RTCConfiguration") int getMaxIPv6Networks() { return maxIPv6Networks; } @Nullable @CalledByNative("RTCConfiguration") IntervalRange getIceRegatherIntervalRange() { return iceRegatherIntervalRange; } @Nullable @CalledByNative("RTCConfiguration") TurnCustomizer getTurnCustomizer() { return turnCustomizer; } @CalledByNative("RTCConfiguration") boolean getDisableIpv6() { return disableIpv6; } @CalledByNative("RTCConfiguration") boolean getEnableDscp() { return enableDscp; } @CalledByNative("RTCConfiguration") boolean getEnableCpuOveruseDetection() { return enableCpuOveruseDetection; } @CalledByNative("RTCConfiguration") boolean getEnableRtpDataChannel() { return enableRtpDataChannel; } @CalledByNative("RTCConfiguration") boolean getSuspendBelowMinBitrate() { return suspendBelowMinBitrate; } @Nullable @CalledByNative("RTCConfiguration") Integer getScreencastMinBitrate() { return screencastMinBitrate; } @Nullable @CalledByNative("RTCConfiguration") Boolean getCombinedAudioVideoBwe() { return combinedAudioVideoBwe; } @Nullable @CalledByNative("RTCConfiguration") Boolean getEnableDtlsSrtp() { return enableDtlsSrtp; } @CalledByNative("RTCConfiguration") AdapterType getNetworkPreference() { return networkPreference; } @CalledByNative("RTCConfiguration") SdpSemantics getSdpSemantics() { return sdpSemantics; } @CalledByNative("RTCConfiguration") boolean getActiveResetSrtpParams() { return activeResetSrtpParams; } }; private final List localStreams = new ArrayList<>(); private final long nativePeerConnection; private List senders = new ArrayList<>(); private List receivers = new ArrayList<>(); private List transceivers = new ArrayList<>(); /** * Wraps a PeerConnection created by the factory. Can be used by clients that want to implement * their PeerConnection creation in JNI. */ public PeerConnection(NativePeerConnectionFactory factory) { this(factory.createNativePeerConnection()); } PeerConnection(long nativePeerConnection) { this.nativePeerConnection = nativePeerConnection; } // JsepInterface. public SessionDescription getLocalDescription() { return nativeGetLocalDescription(); } public SessionDescription getRemoteDescription() { return nativeGetRemoteDescription(); } public DataChannel createDataChannel(String label, DataChannel.Init init) { return nativeCreateDataChannel(label, init); } public void createOffer(SdpObserver observer, MediaConstraints constraints) { nativeCreateOffer(observer, constraints); } public void createAnswer(SdpObserver observer, MediaConstraints constraints) { nativeCreateAnswer(observer, constraints); } public void setLocalDescription(SdpObserver observer, SessionDescription sdp) { nativeSetLocalDescription(observer, sdp); } public void setRemoteDescription(SdpObserver observer, SessionDescription sdp) { nativeSetRemoteDescription(observer, sdp); } /** * Enables/disables playout of received audio streams. Enabled by default. * * Note that even if playout is enabled, streams will only be played out if * the appropriate SDP is also applied. The main purpose of this API is to * be able to control the exact time when audio playout starts. */ public void setAudioPlayout(boolean playout) { nativeSetAudioPlayout(playout); } /** * Enables/disables recording of transmitted audio streams. Enabled by default. * * Note that even if recording is enabled, streams will only be recorded if * the appropriate SDP is also applied. The main purpose of this API is to * be able to control the exact time when audio recording starts. */ public void setAudioRecording(boolean recording) { nativeSetAudioRecording(recording); } public boolean setConfiguration(RTCConfiguration config) { return nativeSetConfiguration(config); } public boolean addIceCandidate(IceCandidate candidate) { return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp); } public boolean removeIceCandidates(final IceCandidate[] candidates) { return nativeRemoveIceCandidates(candidates); } /** * Adds a new MediaStream to be sent on this peer connection. * Note: This method is not supported with SdpSemantics.UNIFIED_PLAN. Please * use addTrack instead. */ public boolean addStream(MediaStream stream) { boolean ret = nativeAddLocalStream(stream.nativeStream); if (!ret) { return false; } localStreams.add(stream); return true; } /** * Removes the given media stream from this peer connection. * This method is not supported with SdpSemantics.UNIFIED_PLAN. Please use * removeTrack instead. */ public void removeStream(MediaStream stream) { nativeRemoveLocalStream(stream.nativeStream); localStreams.remove(stream); } /** * Creates an RtpSender without a track. * *

This method allows an application to cause the PeerConnection to negotiate * sending/receiving a specific media type, but without having a track to * send yet. * *

When the application does want to begin sending a track, it can call * RtpSender.setTrack, which doesn't require any additional SDP negotiation. * *

Example use: *

   * {@code
   * audioSender = pc.createSender("audio", "stream1");
   * videoSender = pc.createSender("video", "stream1");
   * // Do normal SDP offer/answer, which will kick off ICE/DTLS and negotiate
   * // media parameters....
   * // Later, when the endpoint is ready to actually begin sending:
   * audioSender.setTrack(audioTrack, false);
   * videoSender.setTrack(videoTrack, false);
   * }
   * 
*

Note: This corresponds most closely to "addTransceiver" in the official * WebRTC API, in that it creates a sender without a track. It was * implemented before addTransceiver because it provides useful * functionality, and properly implementing transceivers would have required * a great deal more work. * *

Note: This is only available with SdpSemantics.PLAN_B specified. Please use * addTransceiver instead. * * @param kind Corresponds to MediaStreamTrack kinds (must be "audio" or * "video"). * @param stream_id The ID of the MediaStream that this sender's track will * be associated with when SDP is applied to the remote * PeerConnection. If createSender is used to create an * audio and video sender that should be synchronized, they * should use the same stream ID. * @return A new RtpSender object if successful, or null otherwise. */ public RtpSender createSender(String kind, String stream_id) { RtpSender newSender = nativeCreateSender(kind, stream_id); if (newSender != null) { senders.add(newSender); } return newSender; } /** * Gets all RtpSenders associated with this peer connection. * Note that calling getSenders will dispose of the senders previously * returned. */ public List getSenders() { for (RtpSender sender : senders) { sender.dispose(); } senders = nativeGetSenders(); return Collections.unmodifiableList(senders); } /** * Gets all RtpReceivers associated with this peer connection. * Note that calling getReceivers will dispose of the receivers previously * returned. */ public List getReceivers() { for (RtpReceiver receiver : receivers) { receiver.dispose(); } receivers = nativeGetReceivers(); return Collections.unmodifiableList(receivers); } /** * Gets all RtpTransceivers associated with this peer connection. * Note that calling getTransceivers will dispose of the transceivers previously * returned. * Note: This is only available with SdpSemantics.UNIFIED_PLAN specified. */ public List getTransceivers() { for (RtpTransceiver transceiver : transceivers) { transceiver.dispose(); } transceivers = nativeGetTransceivers(); return Collections.unmodifiableList(transceivers); } /** * Adds a new media stream track to be sent on this peer connection, and returns * the newly created RtpSender. If streamIds are specified, the RtpSender will * be associated with the streams specified in the streamIds list. * * @throws IllegalStateException if an error accors in C++ addTrack. * An error can occur if: * - A sender already exists for the track. * - The peer connection is closed. */ public RtpSender addTrack(MediaStreamTrack track) { return addTrack(track, Collections.emptyList()); } public RtpSender addTrack(MediaStreamTrack track, List streamIds) { if (track == null || streamIds == null) { throw new NullPointerException("No MediaStreamTrack specified in addTrack."); } RtpSender newSender = nativeAddTrack(track.nativeTrack, streamIds); if (newSender == null) { throw new IllegalStateException("C++ addTrack failed."); } senders.add(newSender); return newSender; } /** * Stops sending media from sender. The sender will still appear in getSenders. Future * calls to createOffer will mark the m section for the corresponding transceiver as * receive only or inactive, as defined in JSEP. Returns true on success. */ public boolean removeTrack(RtpSender sender) { if (sender == null) { throw new NullPointerException("No RtpSender specified for removeTrack."); } return nativeRemoveTrack(sender.nativeRtpSender); } /** * Creates a new RtpTransceiver and adds it to the set of transceivers. Adding a * transceiver will cause future calls to CreateOffer to add a media description * for the corresponding transceiver. * *

The initial value of |mid| in the returned transceiver is null. Setting a * new session description may change it to a non-null value. * *

https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addtransceiver * *

If a MediaStreamTrack is specified then a transceiver will be added with a * sender set to transmit the given track. The kind * of the transceiver (and sender/receiver) will be derived from the kind of * the track. * *

If MediaType is specified then a transceiver will be added based upon that type. * This can be either MEDIA_TYPE_AUDIO or MEDIA_TYPE_VIDEO. * *

Optionally, an RtpTransceiverInit structure can be specified to configure * the transceiver from construction. If not specified, the transceiver will * default to having a direction of kSendRecv and not be part of any streams. * *

Note: These methods are only available with SdpSemantics.UNIFIED_PLAN specified. * @throws IllegalStateException if an error accors in C++ addTransceiver */ public RtpTransceiver addTransceiver(MediaStreamTrack track) { return addTransceiver(track, new RtpTransceiver.RtpTransceiverInit()); } public RtpTransceiver addTransceiver( MediaStreamTrack track, @Nullable RtpTransceiver.RtpTransceiverInit init) { if (track == null) { throw new NullPointerException("No MediaStreamTrack specified for addTransceiver."); } if (init == null) { init = new RtpTransceiver.RtpTransceiverInit(); } RtpTransceiver newTransceiver = nativeAddTransceiverWithTrack(track.nativeTrack, init); if (newTransceiver == null) { throw new IllegalStateException("C++ addTransceiver failed."); } transceivers.add(newTransceiver); return newTransceiver; } public RtpTransceiver addTransceiver(MediaStreamTrack.MediaType mediaType) { return addTransceiver(mediaType, new RtpTransceiver.RtpTransceiverInit()); } public RtpTransceiver addTransceiver( MediaStreamTrack.MediaType mediaType, @Nullable RtpTransceiver.RtpTransceiverInit init) { if (mediaType == null) { throw new NullPointerException("No MediaType specified for addTransceiver."); } if (init == null) { init = new RtpTransceiver.RtpTransceiverInit(); } RtpTransceiver newTransceiver = nativeAddTransceiverOfType(mediaType, init); if (newTransceiver == null) { throw new IllegalStateException("C++ addTransceiver failed."); } transceivers.add(newTransceiver); return newTransceiver; } // Older, non-standard implementation of getStats. @Deprecated public boolean getStats(StatsObserver observer, @Nullable MediaStreamTrack track) { return nativeOldGetStats(observer, (track == null) ? 0 : track.nativeTrack); } /** * Gets stats using the new stats collection API, see webrtc/api/stats/. These * will replace old stats collection API when the new API has matured enough. */ public void getStats(RTCStatsCollectorCallback callback) { nativeNewGetStats(callback); } /** * Limits the bandwidth allocated for all RTP streams sent by this * PeerConnection. Pass null to leave a value unchanged. */ public boolean setBitrate(Integer min, Integer current, Integer max) { return nativeSetBitrate(min, current, max); } /** * Starts recording an RTC event log. * * Ownership of the file is transfered to the native code. If an RTC event * log is already being recorded, it will be stopped and a new one will start * using the provided file. Logging will continue until the stopRtcEventLog * function is called. The max_size_bytes argument is ignored, it is added * for future use. */ public boolean startRtcEventLog(int file_descriptor, int max_size_bytes) { return nativeStartRtcEventLog(file_descriptor, max_size_bytes); } /** * Stops recording an RTC event log. If no RTC event log is currently being * recorded, this call will have no effect. */ public void stopRtcEventLog() { nativeStopRtcEventLog(); } // TODO(fischman): add support for DTMF-related methods once that API // stabilizes. public SignalingState signalingState() { return nativeSignalingState(); } public IceConnectionState iceConnectionState() { return nativeIceConnectionState(); } public IceGatheringState iceGatheringState() { return nativeIceGatheringState(); } public void close() { nativeClose(); } /** * Free native resources associated with this PeerConnection instance. * * This method removes a reference count from the C++ PeerConnection object, * which should result in it being destroyed. It also calls equivalent * "dispose" methods on the Java objects attached to this PeerConnection * (streams, senders, receivers), such that their associated C++ objects * will also be destroyed. * *

Note that this method cannot be safely called from an observer callback * (PeerConnection.Observer, DataChannel.Observer, etc.). If you want to, for * example, destroy the PeerConnection after an "ICE failed" callback, you * must do this asynchronously (in other words, unwind the stack first). See * bug * 3721 for more details. */ public void dispose() { close(); for (MediaStream stream : localStreams) { nativeRemoveLocalStream(stream.nativeStream); stream.dispose(); } localStreams.clear(); for (RtpSender sender : senders) { sender.dispose(); } senders.clear(); for (RtpReceiver receiver : receivers) { receiver.dispose(); } for (RtpTransceiver transceiver : transceivers) { transceiver.dispose(); } transceivers.clear(); receivers.clear(); nativeFreeOwnedPeerConnection(nativePeerConnection); } /** Returns a pointer to the native webrtc::PeerConnectionInterface. */ public long getNativePeerConnection() { return nativeGetNativePeerConnection(); } @CalledByNative long getNativeOwnedPeerConnection() { return nativePeerConnection; } public static long createNativePeerConnectionObserver(Observer observer) { return nativeCreatePeerConnectionObserver(observer); } private native long nativeGetNativePeerConnection(); private native SessionDescription nativeGetLocalDescription(); private native SessionDescription nativeGetRemoteDescription(); private native DataChannel nativeCreateDataChannel(String label, DataChannel.Init init); private native void nativeCreateOffer(SdpObserver observer, MediaConstraints constraints); private native void nativeCreateAnswer(SdpObserver observer, MediaConstraints constraints); private native void nativeSetLocalDescription(SdpObserver observer, SessionDescription sdp); private native void nativeSetRemoteDescription(SdpObserver observer, SessionDescription sdp); private native void nativeSetAudioPlayout(boolean playout); private native void nativeSetAudioRecording(boolean recording); private native boolean nativeSetBitrate(Integer min, Integer current, Integer max); private native SignalingState nativeSignalingState(); private native IceConnectionState nativeIceConnectionState(); private native IceGatheringState nativeIceGatheringState(); private native void nativeClose(); private static native long nativeCreatePeerConnectionObserver(Observer observer); private static native void nativeFreeOwnedPeerConnection(long ownedPeerConnection); private native boolean nativeSetConfiguration(RTCConfiguration config); private native boolean nativeAddIceCandidate( String sdpMid, int sdpMLineIndex, String iceCandidateSdp); private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates); private native boolean nativeAddLocalStream(long stream); private native void nativeRemoveLocalStream(long stream); private native boolean nativeOldGetStats(StatsObserver observer, long nativeTrack); private native void nativeNewGetStats(RTCStatsCollectorCallback callback); private native RtpSender nativeCreateSender(String kind, String stream_id); private native List nativeGetSenders(); private native List nativeGetReceivers(); private native List nativeGetTransceivers(); private native RtpSender nativeAddTrack(long track, List streamIds); private native boolean nativeRemoveTrack(long sender); private native RtpTransceiver nativeAddTransceiverWithTrack( long track, RtpTransceiver.RtpTransceiverInit init); private native RtpTransceiver nativeAddTransceiverOfType( MediaStreamTrack.MediaType mediaType, RtpTransceiver.RtpTransceiverInit init); private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes); private native void nativeStopRtcEventLog(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy