PeerConnection是一個(gè)Java層面的API婆硬,它的內(nèi)層包裹著c++的代碼,它需要調(diào)用c++層面的代碼。
它同時(shí)也是rtc-Android-sdk中尤為重要的幾個(gè)類,推薦新入門的同學(xué)迎变,可以從這里面入手。
//需要在類剛開始初始化的時(shí)候飘言,便引入so包氏豌,這個(gè)so包就是我們用c++縮寫
static {
System.loadLibrary("jingle_peerconnection_so");
}
//Ice:Input Checking Equipment 輸入校驗(yàn)設(shè)備, 輸入校正裝置
//檢驗(yàn)設(shè)備的一些信息的收集狀態(tài),開始热凹,收集中泵喘,完成
public enum IceGatheringState { NEW, GATHERING, COMPLETE }
//鏈接的狀態(tài)
public enum IceConnectionState {
NEW,
CHECKING,
CONNECTED,
COMPLETED,
FAILED,
DISCONNECTED,
CLOSED
}
//信號(hào)聲明
public enum SignalingState {
STABLE, //穩(wěn)定的
HAVE_LOCAL_OFFER, //有本地offer
HAVE_LOCAL_PRANSWER, //有遠(yuǎn)程answer
HAVE_REMOTE_OFFER, //有遠(yuǎn)程offer
HAVE_REMOTE_PRANSWER, //有遠(yuǎn)程answer
CLOSED //關(guān)閉
}
//用來回調(diào)的接口,用來監(jiān)聽流發(fā)生的改變
public static interface Observer {
/** Triggered when the SignalingState changes. */
public void onSignalingChange(SignalingState newState);
/** Triggered when the IceConnectionState changes. */
public void onIceConnectionChange(IceConnectionState newState);
/** Triggered when the ICE connection receiving status changes. */
public void onIceConnectionReceivingChange(boolean receiving);
/** Triggered when the IceGatheringState changes. */
public void onIceGatheringChange(IceGatheringState newState);
/** Triggered when a new ICE candidate has been found. */
public void onIceCandidate(IceCandidate candidate);
/** Triggered when some ICE candidates have been removed. */
public void onIceCandidatesRemoved(IceCandidate[] candidates);
/** Triggered when media is received on a new stream from remote peer. */
public void onAddStream(MediaStream stream);
/** Triggered when a remote peer close a stream. */
public void onRemoveStream(MediaStream stream);
/** Triggered when a remote peer opens a DataChannel. */
public void onDataChannel(DataChannel dataChannel);
/** Triggered when renegotiation is necessary. */
public void onRenegotiationNeeded();
}
//一個(gè)對(duì)象IceServer里面包含的是三個(gè)屬性般妙,這個(gè)對(duì)象通常是在加入房間時(shí)被調(diào)用的纪铺,我們也就是通過這個(gè)加入的聊天服務(wù)器里面的房間
public static class IceServer {
public final String uri;
public final String username;
public final String password;
/** Convenience constructor for STUN servers. */
public IceServer(String uri) {
this(uri, "", "");
}
public IceServer(String uri, String username, String password) {
this.uri = uri;
this.username = username;
this.password = password;
}
public String toString() {
return uri + "[" + username + ":" + password + "]";
}
}
//ice的運(yùn)送的方式
public enum IceTransportsType { NONE, RELAY, NOHOST, ALL }
//捆綁的策略,平衡碟渺,最大程序捆綁鲜锚,最大程度兼容
public enum BundlePolicy { BALANCED, MAXBUNDLE, MAXCOMPAT }
//談判、無資格的
public enum RtcpMuxPolicy { NEGOTIATE, REQUIRE }
//tcp候選人的策略,激活苫拍,有缺陷的
public enum TcpCandidatePolicy { ENABLED, DISABLED }
//候選人網(wǎng)絡(luò)策略芜繁,全部,最低的成本
public enum CandidateNetworkPolicy { ALL, LOW_COST }
秘鑰加密的類型
public enum KeyType { RSA, ECDSA }
不斷的收集策略绒极,收集一次骏令,不間斷的收集
public enum ContinualGatheringPolicy { GATHER_ONCE, GATHER_CONTINUALLY }
/**
*這個(gè)一個(gè)類,里面有很多屬性垄提,這些屬性榔袋,大多都是上面剛剛定義過的屬性,當(dāng)我們創(chuàng)建PeerConnection的時(shí)候铡俐,
*這些都是要被設(shè)置的凰兑,它的構(gòu)造方法里面需要接受iceSercers,這個(gè)里面就包含了許多和我們配置相關(guān)的信息
public static class RTCConfiguration {
public IceTransportsType iceTransportsType;
public List<IceServer> 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;
public RTCConfiguration(List<IceServer> iceServers) {
iceTransportsType = IceTransportsType.ALL;
bundlePolicy = BundlePolicy.BALANCED;
rtcpMuxPolicy = RtcpMuxPolicy.NEGOTIATE;
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;
}
};
//記錄媒體流审丘,發(fā)送者吏够,和接受者,還有就是jni層的鏈接和觀察者
private final List<MediaStream> localStreams;
private final long nativePeerConnection;
private final long nativeObserver;
private List<RtpSender> senders;
private List<RtpReceiver> receivers;
//構(gòu)造方法滩报,需要傳入一個(gè)Connection锅知,還有就是一個(gè)回調(diào)的接口
PeerConnection(long nativePeerConnection, long nativeObserver) {
this.nativePeerConnection = nativePeerConnection;
this.nativeObserver = nativeObserver;
localStreams = new LinkedList<MediaStream>();
senders = new LinkedList<RtpSender>();
receivers = new LinkedList<RtpReceiver>();
}
//JSEP(JavaScript Session Establishment Protocol,JavaScript 會(huì)話建立協(xié)議)
//以下便都是和底層C代碼的交互部分了露泊,這里面的方法尤為重要
//這里的方法都是喉镰,我們調(diào)用,然后傳入callback等待結(jié)果
//createOffer,createAnswer,setLocalDescription,setRemoteDescription都是rtc最基本的函數(shù)之一
public native SessionDescription getLocalDescription();
public native SessionDescription getRemoteDescription();
public native DataChannel createDataChannel(String label, DataChannel.Init init);
public native void createOffer(SdpObserver observer, MediaConstraints constraints);
public native void createAnswer(SdpObserver observer, MediaConstraints constraints);
public native void setLocalDescription(SdpObserver observer, SessionDescription sdp);
public native void setRemoteDescription(SdpObserver observer, SessionDescription sdp);
public native boolean setConfiguration(RTCConfiguration config);
//添加和刪除對(duì)端的描述
public boolean addIceCandidate(IceCandidate candidate) {
return nativeAddIceCandidate(candidate.sdpMid, candidate.sdpMLineIndex, candidate.sdp);
}
public boolean removeIceCandidates(final IceCandidate[] candidates) {
return nativeRemoveIceCandidates(candidates);
}
//添加和刪除本地的流
public boolean addStream(MediaStream stream) {
boolean ret = nativeAddLocalStream(stream.nativeStream);
if (!ret) {
return false;
}
localStreams.add(stream);
return true;
}
public void removeStream(MediaStream stream) {
nativeRemoveLocalStream(stream.nativeStream);
localStreams.remove(stream);
}
//添加和獲取發(fā)送者的信息惭笑,例如音量信息侣姆,網(wǎng)速的信息都可以從中獲得
public RtpSender createSender(String kind, String stream_id) {
RtpSender new_sender = nativeCreateSender(kind, stream_id);
if (new_sender != null) {
senders.add(new_sender);
}
return new_sender;
}
// Note that calling getSenders will dispose of the senders previously
// returned (and same goes for getReceivers).
public List<RtpSender> getSenders() {
for (RtpSender sender : senders) {
sender.dispose();
}
senders = nativeGetSenders();
return Collections.unmodifiableList(senders);
}
//獲取狀態(tài),在這里面可以獲取到trak的狀態(tài)
public boolean getStats(StatsObserver observer, MediaStreamTrack track) {
return nativeGetStats(observer, (track == null) ? 0 : track.nativeTrack);
}
// 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();
}
//這里面都是jni層面的代碼沉噩,這些方法可以獲取一些狀態(tài)
public native SignalingState signalingState();
public native IceConnectionState iceConnectionState();
public native IceGatheringState iceGatheringState();
public native void close();
//dispose掉當(dāng)前的這些流捺宗,實(shí)現(xiàn)清空當(dāng)前PeerConnection的作用
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();
}
receivers.clear();
freePeerConnection(nativePeerConnection);
freeObserver(nativeObserver);
}
//JNI層面的代碼,供sdk內(nèi)部調(diào)用的川蒙,我們調(diào)用的很多sdk層面的代碼蚜厉,然后它們調(diào)用這些代碼
private static native void freePeerConnection(long nativePeerConnection);
private static native void freeObserver(long nativeObserver);
private native boolean nativeAddIceCandidate(
String sdpMid, int sdpMLineIndex, String iceCandidateSdp);
private native boolean nativeRemoveIceCandidates(final IceCandidate[] candidates);
private native boolean nativeAddLocalStream(long nativeStream);
private native void nativeRemoveLocalStream(long nativeStream);
private native boolean nativeGetStats(StatsObserver observer, long nativeTrack);
private native RtpSender nativeCreateSender(String kind, String stream_id);
private native List<RtpSender> nativeGetSenders();
private native List<RtpReceiver> nativeGetReceivers();
private native boolean nativeStartRtcEventLog(int file_descriptor, int max_size_bytes);
private native void nativeStopRtcEventLog();
以上便是,我對(duì)PeerConnection源碼的解析畜眨,轉(zhuǎn)載請(qǐng)注明出處:linsir.top昼牛,我的gitHub地址术瓮,歡迎star,follow~