WebRTC知识分享——WebRTC on Android

原文:https://tech.appear.in/2015/05/25/Introduction-to-WebRTC-on-Android/
前提:
1、在你的工程中导入WebRTC的库
2、应用要有操作摄像头或者麦克风的权限
我们在浏览器上使用WebRTC的时候,可以使用那些已经写好的函数,比如navigator.getUserMedia和RTCPeerConnection包含了几乎我们需要的所有东西,用video标签不仅可以显示本
地网页摄像头的流,也可以显示远程的视频流。
幸运的是,安卓上的API和他们没有太大的不一样,除了名字,在安卓上,我们使用VideoCapturerAndroid, VideoRenderer, MediaStream, PeerConnection,和PeerConnectionFactory,接下来我们一个一个看。
1、PeerConnectionFactory
几乎包含了WebRTC的所有代码。
首先,初始化PeerConnectionFactory

// First, we initiate the PeerConnectionFactory with
// our application context and some options.
PeerConnectionFactory.initializeAndroidGlobals(
context,
initializeAudio,
initializeVideo,
videoCodecHwAcceleration,
renderEGLContext);

每一个参数的含义:
context:应用的上下文或者其他相关的上下文
initializeAudio:一个布尔值,用来初始化音频部分
initializeVideo:布尔值,用来初始化视频部分
videoCodecHwAcceleration:布尔值,允许硬件加速(??)
renderEGLContext:支持硬件视屏的解码

initializeAndroidGlobals返回一个布尔表示执行的结果。
初始化完成后,创建

PeerConnectionFactory peerConnectionFactory = new PeerConnectionFactory();

一旦有了PeerConnectionFactory实例,就可以从用户的设备中会的视频或音频流最后将他>们渲染到屏幕上。在网页上,有getUserMedia和,而安卓上并不那么简单,在安卓上我们讨论VideoCapturerAndroid, VideoSource, VideoTrack和VideoRenderer。
2、VideoCapturerAndroid
VideoCapturerAndroid提供方便的方法获得设备的视频流,也可以让你获得摄像头的数量,
获得前置摄像头或者后置摄像头。

// Returns the number of camera devices
VideoCapturerAndroid.getDeviceCount();

// Returns the front face device name
VideoCapturerAndroid.getNameOfFrontFacingDevice();
// Returns the back facing device name
VideoCapturerAndroid.getNameOfBackFacingDevice();

// Creates a VideoCapturerAndroid instance for the device name
VideoCapturerAndroid.create(name);

有了这个包含视频流的VideoCapturerAndroid实例,你就可以创建一个包含视频流的MediaStream,并将他发送给别人。但是,在这之前,我们需要在自己应用中显示这个视频。

3、VideoSource/VideoTrack
为了从你的VideoCapturer实例中获得有用的东西,或者为PeerConnection获得一个有效的MediaStream,或者只是将视频渲染给用户,你都需要通过VideoSource/VideoTrack类
VideoSource允许开始或结束捕捉你的设备
VideoTrack是一个简单的分装来将VideoSource添加到MediaStream对象中
用法实例,capturer是VideoCapturer实例,videoConstraints是MediaConstraints实例。

// First we create a VideoSource
VideoSource videoSource =
peerConnectionFactory.createVideoSource(capturer, videoConstraints);

// Once we have that, we can create our VideoTrack
// Note that VIDEO_TRACK_ID can be any string that uniquely
// identifies that video track in your application
VideoTrack localVideoTrack =
peerConnectionFactory.createVideoTrack(VIDEO_TRACK_ID, videoSource);

4、AudioSource/AudioTrack
和VideoSource/VideoTrack相似,除了,我们不需要AudioCapturer来捕捉麦克风。audioConstraints是MediaConstraints的实例。

// First we create an AudioSource
AudioSource audioSource =
peerConnectionFactory.createAudioSource(audioConstraints);

// Once we have that, we can create our AudioTrack
// Note that AUDIO_TRACK_ID can be any string that uniquely
// identifies that audio track in your application
AudioTrack localAudioTrack =
peerConnectionFactory.createAudioTrack(AUDIO_TRACK_ID, audioSource);

5、VideoRenderer
在网页中,使用标签来显示从getUserMedia获得的视频流,但是在安卓上,没有标签,用VideoRenderer。然而,他也提供了一个VideoRendererGui.简而言之,VideoRendererGui是一个可以在上面显示你视频的GLSurfaceView。
实例:

// To create our VideoRenderer, we can use the
// included VideoRendererGui for simplicity
// First we need to set the GLSurfaceView that it should render to
GLSurfaceView videoView = (GLSurfaceView) findViewById(R.id.glview_call);

// Then we set that view, and pass a Runnable
// to run once the surface is ready
VideoRendererGui.setView(videoView, runnable);

// Now that VideoRendererGui is ready, we can get our VideoRenderer
VideoRenderer renderer = VideoRendererGui.createGui(x, y, width, height);

// And finally, with our VideoRenderer ready, we
// can add our renderer to the VideoTrack.
localVideoTrack.addRenderer(renderer);

6、MediaConstraints
支持在MediaStream中视频或者音频的不同约束。

MediaConstraints audioConstraints = new MediaConstraints();

7、MediaStream
现在你可以看到自己了。。现在是时候实现其他的功能了。在网页上,你应该对MediaStream的概念比较熟悉,getUserMesia直接返回一个可以添加到
RTCPeerConnection并发动给另一端的媒体流。在安卓上也同样如此,除了我们需要自己构建我们自己的MediaStream。
示例:

// We start out with an empty MediaStream object,
// created with help from our PeerConnectionFactory
// Note that LOCAL_MEDIA_STREAM_ID can be any string
MediaStream mediaStream = peerConnectionFactory.createLocalMediaStream(LOCAL_MEDIA_STREAM_ID);

// Now we can add our tracks.
mediaStream.addTrack(localVideoTrack);
mediaStream.addTrack(localAudioTrack);

最终我们获得了一个包含视频或音频流的MediaStream实例,并且可以在屏幕上显示自己。现在需要将这个发送给另一端。但是WebRTC并没有提供一种方式去建立信令机制,
我们将通过每一个API来阐述怎样将他和网页联系。AppRTC利用autobahn使得websocket连接到信令服务器。

8、PeerConnection
现在我们已经有了我们的MediaStream,我们可以开始和另一端连接。幸运的是,这一部分和网页上很相近。
通过PeerConnectionFactory创建一个PeerConnection。

PeerConnection peerConnection = peerConnectionFactory.createPeerConnection(
iceServers,
constraints,
observer);

参数意义:
iceServers:当你需要连接本地的设备或者网络之外的网络,需要用到这个,STUN或者TURN服务器。
constraints:MediaConstraints的实例,需要包括offerToRecieveAudioofferToRecieveVideo
observer:PeerConnectionObserver的实例。

PeerConnection的API和网页上的及其相似,包括的方法有addStream, addIceCandidate, createOffer, createAnswer, getLocalDescription, setRemoteDescription等等。下面快速的看一下每个方法。

addStream:
将MediaStream添加到PeerConnection。
addIceCandidate:
当互动式ICE框架找到可以让别的peer连接到你的候选,这个就被创建。当你发送你从 PeerConnectionObserver.onIceCandidate处理器得到的给另一端时,无论通过哪种信令机制,你将要获得远程端的有效的IceCandidates。用这个方法将他们加到PeerConnection中。
createOffer/createAnswer
初始化通话时需要用到。在WebRTC中有caller和callee的概念。caller使用createOffer,他用到sdpObserver,允许你将SDP给其他部分或者一个MediaConstraints。
一旦另一端得到这个邀请,他就会创建一个answer并发给caller。SDP是描述另一端所期望格式的元数据(视频,格式,编解码,加密,分辨率,大小等等)。
setLocalDescription/setRemoteDescription
这个用来设置从createOffer/createAnswer产生的SDP,包括从远端获得的。用来配置Connection以便你在转换视频和音频是可以正常工作。
PeerConnectionObserver
这个接口提供一种方式来PeerConnection的事件,例如什么时候接收到MediaStream,什么时候找到了IceCandidates,什么时候需要重新谈判。这个接口需要由你执行,你才可以合理的处理即将到来的事件。

展开阅读全文

没有更多推荐了,返回首页