PeerConnectionFactory一個(gè)用來生成PeerConnection的工廠類值骇,WebRTC中最重要的類之一,用來創(chuàng)建peerConnection的類鞭呕,同時(shí)負(fù)責(zé)初始化全局和底層交互。
加載so庫
static {
try {
System.loadLibrary("jingle_peerconnection_so");
nativeLibLoaded = true;
} catch (UnsatisfiedLinkError var1) {
nativeLibLoaded = false;
}
}
網(wǎng)絡(luò)接口相關(guān)參數(shù)
public static class Options {
//未知
static final int ADAPTER_TYPE_UNKNOWN = 0;
//以太網(wǎng)
static final int ADAPTER_TYPE_ETHERNET = 1;
//WIFI
static final int ADAPTER_TYPE_WIFI = 2;
//移動(dòng)網(wǎng)絡(luò)
static final int ADAPTER_TYPE_CELLULAR = 4;
//vpn
static final int ADAPTER_TYPE_VPN = 8;
//回環(huán)
static final int ADAPTER_TYPE_LOOPBACK = 16;
//網(wǎng)絡(luò)忽略宛官,與PeerConnectionParameters.loopback有關(guān)
public int networkIgnoreMask;
//解碼器
public boolean disableEncryption;
//網(wǎng)絡(luò)監(jiān)控
public boolean disableNetworkMonitor;
public Options() {
}
}
初始化PeerConnectionFactory
//native層初始化全局葫松,如果初始化成功會(huì)返回TRUE,否則返回FALSE
/*
*Context:簡(jiǎn)單的ApplicationContext瓦糕,或者其他Context相關(guān)的上下文
*videoHwAcceleration:是否啟用硬件加速
*/
public static void initializeAndroidGlobals(Context context, boolean videoHwAcceleration) {
ContextUtils.initialize(context);
nativeInitializeAndroidGlobals(context, videoHwAcceleration);
}
//一個(gè)初始化工作,應(yīng)該在創(chuàng)建Factory創(chuàng)建之前进宝,用來初始化音視頻軌
//fieldTrialsInitString:音視頻軌的描述
public static native void initializeFieldTrials(String fieldTrialsInitString);
//初始化內(nèi)部描述
public static native void initializeInternalTracer();
//關(guān)閉內(nèi)部描述
public static native void shutdownInternalTracer();
//打開或關(guān)閉內(nèi)部追蹤刻坊,創(chuàng)建一個(gè)log文件,與PeerConnectionParameters.tracing有關(guān)
public static native boolean startInternalTracingCapture(String var0);
public static native void stopInternalTracingCapture();
工廠構(gòu)造方法
/** @deprecated 看來已經(jīng)不建議使用*/
@Deprecated
public PeerConnectionFactory() {
this((PeerConnectionFactory.Options)null);
}
//很明顯党晋,調(diào)用了下面的構(gòu)造方法
public PeerConnectionFactory(PeerConnectionFactory.Options options) {
this(options, (VideoEncoderFactory)null, (VideoDecoderFactory)null);
}
//調(diào)用native層傳進(jìn)去一組參數(shù)
/**
*
* @param options 網(wǎng)絡(luò)接口相關(guān)參數(shù)
* @param encoderFactory 視頻編碼器接口谭胚,創(chuàng)建視頻編碼器及格式
* @param decoderFactory 視頻解碼器接口,創(chuàng)建視頻解碼器
*/
public PeerConnectionFactory(PeerConnectionFactory.Options options, VideoEncoderFactory encoderFactory, VideoDecoderFactory decoderFactory) {
this.nativeFactory = nativeCreatePeerConnectionFactory(options, encoderFactory, decoderFactory);
if (this.nativeFactory == 0L) {
throw new RuntimeException("Failed to initialize PeerConnectionFactory!");
}
}
創(chuàng)建PeerConnection
/**
*
* @param rtcConfig WebRTC通信最主要的配置未玻,主要是配置IceServer信息
* @param constraints 媒體約束類
* @param observer ICE和音視頻流變化時(shí)的回調(diào)接口
*/
public PeerConnection createPeerConnection(PeerConnection.RTCConfiguration rtcConfig,
MediaConstraints constraints, PeerConnection.Observer observer) {
long nativeObserver = nativeCreateObserver(observer);
if (nativeObserver == 0L) {
return null;
} else {
long nativePeerConnection = nativeCreatePeerConnection(this.nativeFactory, rtcConfig, constraints, nativeObserver);
return nativePeerConnection == 0L ? null : new PeerConnection(nativePeerConnection, nativeObserver);
}
}
/**
*
* @param rtcConfig IceServer信息
* @param constraints 媒體約束類
* @param observer ICE和音視頻流變化時(shí)的回調(diào)接口
*/
public PeerConnection createPeerConnection(List<PeerConnection.IceServer> iceServers,
MediaConstraints constraints, PeerConnection.Observer observer) {
RTCConfiguration rtcConfig = new RTCConfiguration(iceServers);
return this.createPeerConnection(rtcConfig, constraints, observer);
}
創(chuàng)建本地媒體流
public MediaStream createLocalMediaStream(String label) {
return new MediaStream(nativeCreateLocalMediaStream(this.nativeFactory, label));
}
創(chuàng)建本地視頻源灾而,調(diào)用的都是native層的代碼
public VideoSource createVideoSource(VideoCapturer capturer) {
org.webrtc.EglBase.Context eglContext = this.localEglbase == null ? null : this.localEglbase.getEglBaseContext();
SurfaceTextureHelper surfaceTextureHelper = SurfaceTextureHelper.create("VideoCapturerThread", eglContext);
long nativeAndroidVideoTrackSource = nativeCreateVideoSource(this.nativeFactory, surfaceTextureHelper, capturer.isScreencast());
CapturerObserver capturerObserver = new AndroidVideoTrackSourceObserver(nativeAndroidVideoTrackSource);
capturer.initialize(surfaceTextureHelper, ContextUtils.getApplicationContext(), capturerObserver);
return new VideoSource(nativeAndroidVideoTrackSource);
}
創(chuàng)建視頻軌
public VideoTrack createVideoTrack(String id, VideoSource source) {
return new VideoTrack(nativeCreateVideoTrack(this.nativeFactory, id, source.nativeSource));
}
創(chuàng)建本地音頻流
public AudioSource createAudioSource(MediaConstraints constraints) {
return new AudioSource(nativeCreateAudioSource(this.nativeFactory, constraints));
}
創(chuàng)建音頻軌
public AudioTrack createAudioTrack(String id, AudioSource source) {
return new AudioTrack(nativeCreateAudioTrack(this.nativeFactory, id, source.nativeSource));
}
Aec轉(zhuǎn)碼
// Starts recording an AEC dump. Ownership of the file is transfered to the
// native code. If an AEC dump is already in progress, it will be stopped and
// a new one will start using the provided file.
//使用一定文件空間轉(zhuǎn)碼
public boolean startAecDump(int file_descriptor, int filesize_limit_bytes) {
return nativeStartAecDump(nativeFactory, file_descriptor, filesize_limit_bytes);
}
// Stops recording an AEC dump. If no AEC dump is currently being recorded,
// this call will have no effect.
//停止轉(zhuǎn)碼
public void stopAecDump() {
nativeStopAecDump(nativeFactory);
}
設(shè)置網(wǎng)絡(luò)狀態(tài),
/** @deprecated對(duì)應(yīng)無參數(shù)的構(gòu)造方法扳剿,同樣不建議被使用 */
@Deprecated
public void setOptions(PeerConnectionFactory.Options options) {
this.nativeSetOptions(this.nativeFactory, options);
}
設(shè)置視頻硬件加速參數(shù)
public void setVideoHwAccelerationOptions(org.webrtc.EglBase.Context localEglContext, org.webrtc.EglBase.Context remoteEglContext) {
if (this.localEglbase != null) {
Logging.w("PeerConnectionFactory", "Egl context already set.");
this.localEglbase.release();
}
if (this.remoteEglbase != null) {
Logging.w("PeerConnectionFactory", "Egl context already set.");
this.remoteEglbase.release();
}
this.localEglbase = EglBase.create(localEglContext);
this.remoteEglbase = EglBase.create(remoteEglContext);
nativeSetVideoHwAccelerationOptions(this.nativeFactory, this.localEglbase.getEglBaseContext(), this.remoteEglbase.getEglBaseContext());
}
釋放資源旁趟,回收PeerConnectionFactory
public void dispose() {
nativeFreeFactory(this.nativeFactory);
networkThread = null;
workerThread = null;
signalingThread = null;
if (this.localEglbase != null) {
this.localEglbase.release();
}
if (this.remoteEglbase != null) {
this.remoteEglbase.release();
}
}
回調(diào)線程
public void threadsCallbacks() {
nativeThreadsCallbacks(this.nativeFactory);
}
輸出現(xiàn)在的調(diào)用幀
private static void printStackTrace(Thread thread, String threadName) {
if (thread != null) {
StackTraceElement[] stackTraces = thread.getStackTrace();
if (stackTraces.length > 0) {
Logging.d("PeerConnectionFactory", threadName + " stacks trace:");
StackTraceElement[] var3 = stackTraces;
int var4 = stackTraces.length;
for(int var5 = 0; var5 < var4; ++var5) {
StackTraceElement stackTrace = var3[var5];
Logging.d("PeerConnectionFactory", stackTrace.toString());
}
}
}
}
public static void printStackTraces() {
printStackTrace(networkThread, "Network thread");
printStackTrace(workerThread, "Worker thread");
printStackTrace(signalingThread, "Signaling thread");
}
當(dāng)線程準(zhǔn)備完畢
private static void onNetworkThreadReady() {
networkThread = Thread.currentThread();
Logging.d("PeerConnectionFactory", "onNetworkThreadReady");
}
private static void onWorkerThreadReady() {
workerThread = Thread.currentThread();
Logging.d("PeerConnectionFactory", "onWorkerThreadReady");
}
private static void onSignalingThreadReady() {
signalingThread = Thread.currentThread();
Logging.d("PeerConnectionFactory", "onSignalingThreadReady");
}
native層代碼
//創(chuàng)建peerConnectionFactory
private static native long nativeCreatePeerConnectionFactory(Options options);
//創(chuàng)建回調(diào)的listener
private static native long nativeCreateObserver(PeerConnection.Observer observer);
//創(chuàng)建peerConnection
private static native long nativeCreatePeerConnection(long nativeFactory,
PeerConnection.RTCConfiguration rtcConfig, MediaConstraints constraints, long nativeObserver);
//創(chuàng)建本地的媒體流
private static native long nativeCreateLocalMediaStream(long nativeFactory, String label);
//創(chuàng)建音頻資源
private static native long nativeCreateVideoSource(
long nativeFactory, EglBase.Context eglContext, boolean is_screencast);
//初始化視頻的資源
private static native void nativeInitializeVideoCapturer(long native_factory,
VideoCapturer j_video_capturer, long native_source,
VideoCapturer.CapturerObserver j_frame_observer);
//創(chuàng)建視頻足記
private static native long nativeCreateVideoTrack(
long nativeFactory, String id, long nativeVideoSource);
//創(chuàng)建音頻資源
private static native long nativeCreateAudioSource(
long nativeFactory, MediaConstraints constraints);
//創(chuàng)建音頻足記
private static native long nativeCreateAudioTrack(
long nativeFactory, String id, long nativeSource);
//開啟ace轉(zhuǎn)碼
private static native boolean nativeStartAecDump(
long nativeFactory, int file_descriptor, int filesize_limit_bytes);
//關(guān)閉ace轉(zhuǎn)碼
private static native void nativeStopAecDump(long nativeFactory);
//設(shè)置配置
@Deprecated public native void nativeSetOptions(long nativeFactory, Options options);
//設(shè)置怎么樣的轉(zhuǎn)碼方式,加速的方式
private static native void nativeSetVideoHwAccelerationOptions(
long nativeFactory, Object localEGLContext, Object remoteEGLContext);
//不同線程的回調(diào)
private static native void nativeThreadsCallbacks(long nativeFactory);
//釋放factory的控件
private static native void nativeFreeFactory(long nativeFactory);