Android上WebRTC介绍

译者说明

由于译者水平有限,翻译尽量遵从原意,一些地方有错误敬请指教。

发布在

这里

原文

https://tech.appear.in/2015/05/25/Introduction-to-WebRTC-on-Android/

翻译

WebRTC被称为开源网络发展的又一大里程碑,被看作为近些年对Web标准的最重要的创新。WebRTC允许开发者在网页应用中添加音视频,并且折不需要复杂的代码和昂贵的其他的基础设备。现在有Chrome、Firfox和Opera都已经支持了WebRTC,并将有更多的浏览器也将会支持,数十亿的设备已经支持了。

然而,WebRTC也被称为城市神话(很多人都相信但实际上并不真实的故事):WebRTC仅仅可以应用在浏览器上。事实上,WebRTC最重要的一个特征是它允许nativ和web app之间的互操作(跨平台)的。很少有人利用这一个特征优势。

这篇Blog将介绍给你如何在你的Android应用中集成WebRTC,使用了WebRTC提供的本地库,提供者:WebRTC Initiative。我们不会强调通过signalling建立连接,而是强调Android和浏览器间的相似和差异。正如你将看到的,将包含一些连接到Web的APIs,如果你想看到更多的基本的关于WebRTC的介绍,请看:Sam Dutton’s Getting started with WebRTC

在你的项目中添加WebRTC的库

以下内容使用WebRTC库中的9127版本。

第一件事是添加WebRTC库到你的项目中。你可以自己编译这个库,但是相信我,如果可以的话,避免自己编译。相反,使用中央厂库中已经编译好的文件。

为了在你的项目中添加这个文件,需要这样写依赖:

compile 'io.pristine:libjingle:9127@aar'

同步你的项目,你已经拥有了可以使用的库文件了!

权限

就像所有的Android一样,使用这个API你需要声明一些权限。WebRTC也不例外。根据你现在使用的或者是将来会使用的权限,例如音频和视频,你需要设置不同的权限。确保你只请求一次。一个可用的视频聊天应用的权限设置:

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:glEsVersion="0x00020000" android:required="true" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

灯光,相机……

当在浏览器中使用WebRTC时,你可以使用一些很好用的API和文档可以参考:navigator.getUserMediaRTCPeerConnection包含了大部分你需要的东西。结合video标签,本地和远程数据流一起使用。

幸运的虽然他们有不同的名字,但是在Android这些API也不是很难。在Android中,我们讨论VideoCapturerAndroidVideoRendererMediaStreamPeerConnectionPeerConnectionFactory。我们深入每一个探讨一下。

然而,在你开始做任何这些事情前,需要创建PeerConnectionFactory,Android的WebRTC的核心。

PeerConnectionFactory

WebRTC在Android上所有事情的核心。理解这个类并且知道它如何工作对彻底了解Android上的WebRTC至关重要。它也和你期望的有点不同,因此让我们讨论一下它吧,

首先,初始化PeerConnectionFactory

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

为了理解它如何工作,让我们看看每个参数:

context

简单的ApplicationContext,或者任何其他Context相关的上下文对象,跟你以前使用的一致。ing around.

initializeAudio

boolean值,初始化音频部分。

initializeVideo

boolean值,初始化视频部分。跳过这两个中的任何一个,允许你跳过询问API权限。例如DataChannel应用。

videoCodecHwAcceleration

boolean值,是否启用硬件加速。

renderEGLContext

可以提供这个值创建进程支持HW视频编码。可以被设置为null,这样的话就编码视频使用yuv420而不是texture帧。

initializeAndroidGlobals也将返回一个boolean值,正常初始化返回OK,有未初始化成功情况返回false。如果返回false时,是最好的练习的机会。查看源代码获取更多信息。

假设一切正常,你可以使用PeerConnectionFactory的构造函数创建对象,与其他类一样。

PeerConnectionFactory peerConnectionFactory = new PeerConnectionFactory();

接下来获取媒体对象进行渲染

一旦有了peerConnectionFactory实例,就应该从你的设备上获取音频和视频了,最终渲染到屏幕上。在网页上,你有getUserMedia和video可以用。在Android上也很类似,但是需要一点属相在Android上我们讨论:
VideoCapturerAndroid,VideoSource,VideoTrack和VideoRenderer,都是以VideoCapturerAndroid开始。

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,你可以给对方发送数据。在这之前,让我们看看我们怎样在应用中显示我们自己的视频。

VideoSource/VideoTrack

为了从VideoCapture实例中获取有用的东西,获取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);

AudioSource/AudioTrack

除了不需要AudioCapturer获取麦克风数据,AudioSource/AudioTrack和VideoSource/VideoTrack很类似。audioConstraints是MediaContraints的实例。

// 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);

VideoRenderer

对于浏览器上的WebRTC,你可能很熟悉使用video显示通过getUserMeida获取到的MediaStream到的数据。然而在Android上,没有video标签。跟踪VideoRenderer,WebRTC库允许你实现你自己的方法。然而,也提供了一个很好的默认的方法VideoRendererGui,简单来说,VideoRendererGui是一个GLSurfaceView,在这之上,可以显示视频流。让我们看看如何设置,包括增加我们的renderer到VideoTrack上。

// 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);

一个需要注意的是createGui需要四个参数。可以使用一个GLSurfaceView渲染所有的视频。正如看到的,我们使用多个GLSurfaceViews,这意味着x/y将从0到合适的范围内变化。这是有意义的。

MediaConstraints

这个MediaConstraints是WebRTC支持将视频和音频放入MediaStream的方式。看这个支持的规范,大多数方法都需要MediaContraints的实例。

MediaConstraints audioConstraints = new MediaConstraints();

为了定制更多的限制,可以定义键值对,并将他们放到约束列表中。

MediaStream

现在是时候讨论其他部分的功能了。在网页上,我们可能很熟悉MediaStream的概念了,getUserMedia直接返回一个MediaStream,你可以直接将其添加到RTCPeerConnection中发送给对端。对于Android也是一样,除了我们必须创建我们自己的MediaStream。让我们看看我们怎样可以添加VideoTrack和AudioTrack到一个恰当的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实体中有了音视频流,除了显示在屏幕上,也应该传递给对方了。尽管本文不包括如何创建数据流管道的方法,我们将浏览一遍每个API的方法并解释与Web如何相关。AppRTC使用autobahn使WebRTC连接到信令服务器。我建议你检出项目,详细了解一下Android如何设置信令服务器。

PeerConnection

现在我们有了MediaStream,我们可以连接到对方了,幸运的是这一部分与Web很类似,因此如果你熟悉浏览器上的WebRTC,这部分和直接。在PeerConnectionFactory的帮助下创建一个PeerConnection是容易的。

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

参数如下:

iceServers
向连接到外网这个是必要的,添加STUN和TURN服务器可以帮助你连接。
constraints
一个MediaConstrains的实例。应该包含offerToRecieveAudio和offerToRecieveVideo。
observer
一个PeerConnectionObserver的实例。

这个PeerConnection API与web很相似,包括像addStream、addIceCandidate、createOffer、createAnswer、getLocalDescription、setRemoteDescription一类的函数。通过Getting started with WebRTC查看两端怎样一起工作,或者看AppRTC看WebRTC应用怎样工作的。让我们快速的看一下每个函数怎么工作的。

addStream

用来将MediaStream添加到PeerConnection中。如果你想让别人看到你听到你,就需要这个函数。

addCandidate

TODO IceCandidates仅创建一次,允许其他人与你连接。

createOffer/createAnswer

TODO 这两个用来初始化通话设置。

setLocalDescription/setRemoteDescription

TODO 设置SDP。

PeerConnectionObserver

TODO 提供这个PeerConnection事件的观察者。

最后

正如你看到的,当你对Web很熟悉时,这个Android的API是很简单直接的。使用上面的工具,你可以开发一个WebRTC的APP,数百万的设备可以直接使用。

WebRTC开放给我我们所有人,对于开发者免费,对用户免费。它的使用不仅仅在视频聊天,我们也看到在医疗,文件传输甚至在游戏中都有使用。

为了查看WebRTC的例子,检出appear.in在AndroidiOS上。它在浏览器上和应用上都完美的工作着,一起八个人在一个房间中都是免费的,不需要安装和登陆。

去吧,创建一些新的不一样的东西吧!

推荐阅读更多精彩内容