精华内容
下载资源
问答
  • webrtc教程

    热门讨论 2013-12-08 10:29:31
    webrtc教程。初步讲解。还在继续完善中。有兴趣的同学可以一起来完善。下载后评论,可以返还积分。 http://blog.csdn.net/kl222/article/details/17198873
  • WebRTC教程

    2019-06-02 07:50:53
    Learning WebRTC Getting Started with WebRTC Real-Time Communication with WebRTC WebRTC Cookbook
  • 中文版WebRTC教程

    2019-02-27 15:36:30
    这是一份 webrtc的开发文档,内容比较全,而且是中文版本
  • webrtc教程(v0.3)

    千次下载 热门讨论 2014-02-25 22:01:23
    webrtc教程(v0.3)。初步讲解。还在继续完善中。有兴趣的同学可以一起来完善。下载后评论,可以返还积分。可在下面地址留言讨论。 http://blog.csdn.net/kl222/article/details/17198873
  • webrtc教程(v3.0)

    2018-07-03 10:52:37
    webrtc详细教程,细化了windows下编译过程。 增加IDE工具用法。 重新排版整个文档。
  • WebRtc教程 相关信息可以在以下链接中找到。
  • webrtc教程V3.0.pdf

    2016-09-29 10:32:05
    pdf版本的webrtc入门教程
  • 使用Meteor.js和PeerJS的基本WebRTC教程 请参阅博客文章: 。
  • 本入门教程将分为三篇内容,分别讲述信令服务器的搭建、媒体服务器的搭建、Android 端的 WebRTC 应用实现,全文采用开源框架来搭建,适用于大多数入门的开发者。转载请注明出处。如遇到 WebRTC 开发问题,可以点击...

    作者:李超,音视频技术专家。本入门教程将分为三篇内容,分别讲述信令服务器的搭建、媒体服务器的搭建、Android 端的 WebRTC 应用实现,全文采用开源框架来搭建,适用于大多数入门的开发者。转载请注明出处。如遇到 WebRTC 开发问题,可以点击这里,关注作者与他交流。

    前言

    我们在学习 WebRTC 时,首先要把实验环境搭建好,这样我们就可以在上面做各种实验了。

    对于 WebRTC 来说,它有一整套规范,如怎样使用它的接口、使用SDP进行媒体协商、通过ICE收集地址并进行连通性检测等等。除此之外,WebRTC还需要房间服务器将多端聚集到一起管理,以及信令服务器进行信令数据交换(如媒体描述信息SDP的交换,连接地址的交抽换等),但在WebRTC的规范中没有对这部分内容进行规定,所以需要由用户自己处理。

    你可以根据自己的喜好选择服务器(如 Apache,Nginx 或 Nodejs),我今天将介绍如何使用 Nodejs 来搭建信令服务器。

    为什么选择 Nodejs

    Apache、Nginx和Nodejs都是非常成熟的Web服务器,Nginx 可以说是的性能是最好的Web服务器了。但从未来的发展来说,Nodejs可能会更有优势。

    现在以Chrome为代表的浏览器的功能越来越强大,以前认为通过浏览器不可能完成的事儿,现在它都可以轻松实现。H5、 WebSocket的出现以及现在WebRTC的加入,让大家越来越觉得以后的浏览器可以说是“无所不能”。因此,推动 JavaScript 语言的发展越来越迅速。这可以从现在 JavaScript 技术的火爆,以及各种层叠不穷JS FrameWork的出现得以印证。

    而 Nodejs 的最大优点即是可以使用 JS 语言开发服务器程序。这样使得大量的前端同学可以无缝的转到服务器开发,甚至有可能前后端使用同一套代码实现。对于这一点我想无论是对个人还是对于企业都是具大的诱惑。

    一方面 JS 语言的简单性可以方便开发出各种各样功能的服务端程序。

    更可贵的是 Nodejs 的生态链非常的完整,有各种各样的功能库。你可以根据自己的需要通过安装工具 NPM 快速的安装,这也使它也得到了广大开发者的喜欢。

    Nodejs 现在是非常流行的 Web 服务器,它在服务器端使用 V8(JavaScript)引擎,通过它解析 JS 脚本来控制服务器的行为。这对于广大的 JS 同学来说真是太幸福了,在10年前还很难想像可以通过 JS 脚本语言来写服务器程序。

    当然,如果你想对Nodejs作能力拓展的话,还是要写C/C++库,然后加载到 Nodejs 中去。

    Nodejs的基本原理

    bVbp6pb

    Nodejs的工作原理如上图所示, 其核心是 V8 引擎。通过该引擎,可以让 js 调用 C/C++方法 或 对象。相反,通过它也可能让 C/C++ 访问 javascript 方法和变量。

    Nodejs 首先将 JavaScript 写好的应用程序交给 V8 引擎进行解析,V8理解应用程序的语义后,再调用 Nodejs 底层的 C/C++ API将服务启动起来。 所以 Nodejs 的强大就在于 js 可以直接调用 C/C++ 的方法,使其能力可以无限扩展。

    以开发一个 HTTP 服务为例,Nodejs 打开侦听的服务端口后,底层会调用 libuv 处理该端口的所有 http 请求。其网络事件处理如下图所示:

    bVbp6pm

    当有网络请求过来时,首先会被插入到一个事件处理队列中。libuv会监控该事件队列,当发现有事件时,先对请求做判断,如果是简单的请求,就直接返回响应了;如果是复杂请求,则从线程池中取一个线程进行异步处理;

    线程处理完后,有两种可能:一种是已经处理完成,则向用户发送响应;另一种情况是还需要进一步处理,则再生成一个事件插入到事件队列中等待处理;事件处理就这样循环往复下去,永不停歇。

    两个 V8 引擎

    bVbp6pV

    如上图所示,在我们使用 Nodejs之后实际存在了两个 V8 引擎。一个V8用于解析服务端的 JS 应用程序,它将服务启动起来。另一个 V8 是浏览器中的 V8 引擎,用于控制浏览器的行为。

    对于使用 Nodejs 的新手来说,很容易出现思维混乱,因为在服务端至少要放两个 JS 脚本。其中一个是服务端程序,控制 Nodejs 的行为,它由 Nodejs 的V8引擎解析处理;另一个是客户端程序,它是要由浏览器请求后,下发到浏览器,由浏览器中的 V8 引擎进行解析处理。如果分不清这个,那麻烦就大了。

    安装 Nodejs

    下面我们就来看看具体如何安装 Nodejs。

    安装 Nodejs 非常的简单:

    在Ubuntu系统下执行:

    apt install nodejs

    或在Mac 系统下执行:

    brew install nodejs

    通过上面的步骤我们就将 Nodejs 安装好了。我这里安装的 Nodejs版本为:v8.10.0。

    安装NPM

    除了安装 Nodejs 之外,我们还要安装NPM(Node Package Manager),也就是 Nodejs 的包管理器。它就像Ubuntu下的 apt 或Mac 系统下的brew 命令类似,是专门用来管理各种依赖库的。

    在它们没有出现之前,我们要安装个包特别麻烦。以Linux为例,假设要安装一个工具,其基本步骤是:

    先将这个工具的源码下载下来。

    执行./configure 生成Makefile 文件。

    执行 make 命令对其进行编译。

    最后,执行 make install 将其安装到指定目录下。

    如果编译过程中发现有依赖的库,则要对依赖库执行前面的4步,也就是先将依赖库安装好,然后再来安装该工具。

    大家可以看到,以前在Linux下安装个程序或工具是多么的麻烦。

    Linux 有了apt 之后,一切都变得简单了。我们只要执行 apt install xxx 一条命令就好了,它会帮你完成上面的一堆操作。

    对于 Nodejs的安装包也是如此,NPM 就是相当于 Linux 下的 apt,它的出现大大提高了人们的工作效率。

    NPM 的安装像安装 Nodejs 一样简单:

    在Ubuntu下执行:

    apt install npm

    或在Mac下执行:

    brew install npm

    socket.io

    此次,我们使用 Nodejs 下的 socket.io 库来实现 WebRTC 信令服务器。socket.io特别适合用来开发WebRTC的信令服务器,通过它来构建信令服务器特别的简单,这主要是因为它内置了房间 的概念。

    bVbp6p7

    上图是 socket.io 与 Nodejs配合使用的逻辑关系图, 其逻辑非常简单。socket.io 分为服务端和客户端两部分。服务端由 Nodejs加载后侦听某个服务端口,客户端要想与服务端相连,首先要加载 socket.io 的客户端库,然后调用 io.connect();就与服务端连上了。

    需要特别强调的是 socket.io 消息的发送与接收。socket.io 有很多种发送消息的方式,其中最常见的有下面几种,是我们必须要撑握的:

    给本次连接发消息

    socket.emit()

    给某个房间内所有人发消息

    io.in(room).emit()

    除本连接外,给某个房间内所有人发消息

    socket.to(room).emit()

    除本连接外,给所以人发消息

    socket.broadcast.emit()

    消息又该如何接收呢?

    发送 command 命令

    S: socket.emit('cmd’);

    C: socket.on('cmd',function(){...});

    送了一个 command 命令,带 data 数据

    S: socket.emit('action', data);

    C: socket.on('action',function(data){...});

    发送了command命令,还有两个数据

    S: socket.emit(action,arg1,arg2);

    C: socket.on('action',function(arg1,arg2){...});

    有了以上这些知识,我们就可以实现信令数据通讯了。

    搭建信令服务器

    接下来我们来看一下,如何通过 Nodejs下的 socket.io 来构建的一个服务器:

    这是客户端代码,也就是在浏览器里执行的代码。index.html:

    WebRTC client

    该代码十分简单,就是在body里引入了两段 JS 代码。其中,socket.io.js 是用来与服务端建立 socket 连接的。client.js 的作用是做一些业务逻辑,并最终通过 socket 与服务端通讯。

    首先,在server.js目录下创建 js 子目录,然后在 js目录下生成 client.js。

    下面是client.js的代码:

    var isInitiator;

    room = prompt('Enter room name:'); //弹出一个输入窗口

    const socket = io.connect(); //与服务端建立socket连接

    if (room !== '') { //如果房间不空,则发送 "create or join" 消息

    console.log('Joining room ' + room);

    socket.emit('create or join', room);

    }

    socket.on('full', (room) => { //如果从服务端收到 "full" 消息

    console.log('Room ' + room + ' is full');

    });

    socket.on('empty', (room) => { //如果从服务端收到 "empty" 消息

    isInitiator = true;

    console.log('Room ' + room + ' is empty');

    });

    socket.on('join', (room) => { //如果从服务端收到 “join" 消息

    console.log('Making request to join room ' + room);

    console.log('You are the initiator!');

    });

    socket.on('log', (array) => {

    console.log.apply(console, array);

    });

    在该代码中:

    首先弹出一个输入框,要求用户写入要加入的房间。

    然后,通过 io.connect() 建立与服务端的连接,

    根据socket返回的消息做不同的处理:

    当收到房间满"full"时的情况;

    当收到房间空“empty"时的情况;

    当收到加入“join"时的情况;

    以上是客户端(也就是在浏览器)中执行的代码。下面我们来看一下服务端的处理逻辑:

    服务器端代码,server.js:

    const static = require('node-static');

    const http = require('http');

    const file = new(static.Server)();

    const app = http.createServer(function (req, res) {

    file.serve(req, res);

    }).listen(2013);

    const io = require('socket.io').listen(app); //侦听 2013

    io.sockets.on('connection', (socket) => {

    // convenience function to log server messages to the client

    function log(){

    const array = ['>>> Message from server: '];

    for (var i = 0; i < arguments.length; i++) {

    array.push(arguments[i]);

    }

    socket.emit('log', array);

    }

    socket.on('message', (message) => { //收到message时,进行广播

    log('Got message:', message);

    // for a real app, would be room only (not broadcast)

    socket.broadcast.emit('message', message); //在真实的应用中,应该只在房间内广播

    });

    socket.on('create or join', (room) => { //收到 “create or join” 消息

    var clientsInRoom = io.sockets.adapter.rooms[room];

    var numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0; //房间里的人数

    log('Room ' + room + ' has ' + numClients + ' client(s)');

    log('Request to create or join room ' + room);

    if (numClients === 0){ //如果房间里没人

    socket.join(room);

    socket.emit('created', room); //发送 "created" 消息

    } else if (numClients === 1) { //如果房间里有一个人

    io.sockets.in(room).emit('join', room);

    socket.join(room);

    socket.emit('joined', room); //发送 “joined”消息

    } else { // max two clients

    socket.emit('full', room); //发送 "full" 消息

    }

    socket.emit('emit(): client ' + socket.id +

    ' joined room ' + room);

    socket.broadcast.emit('broadcast(): client ' + socket.id +

    ' joined room ' + room);

    });

    });

    在服务端引入了 node-static 库,使服务器具有发布静态文件的功能。服务器具有此功能后,当客户端(浏览器)向服务端发起请求时,服务器通过该模块获得客户端(浏览器)运行的代码,也就是上我面我们讲到的 index.html 和 client.js 并下发给客户端(浏览器)。

    服务端侦听 2013 这个端口,对不同的消息做相应的处理:

    服务器收到 message 消息时,它会直接进行广播,所有连接到该服务器的客户端都会收收广播的消息。

    服务端收到 “create or join”消息时,它会对房间里有人数进行统计,如果房间里没有人,则发送"created" 消息;如果房间里有一个人,发送"join"消息和“joined"消息;如果超过两个人,发送"full"消息。

    要运行该程序,需要使用 NPM 安装 socket.io 和 node-static,安装方法如下:

    进入到 server.js 所在的目录,然后执行下面的命令。

    npm install socket.io

    npm install node-static

    启动服务器并测试

    通过上面的步骤我们就使用 socket.io 构建好一个服务器,现在可以通过下面的命令将服务启动起来了:

    node server.js

    如果你是在本机上搭建的服务,则可以在浏览器中输入 localhost:2013 ,然后新建一个tab 在里边再次输入localhost:2013 。此时,打开控制台看看发生了什么?

    在Chrome下你可以使用快捷键 Command-Option-J或Ctrl-Shift-J的DevTools访问控制台。

    小结

    以上我向大家介绍了 Nodejs 的工作原理、Nodejs的安装与布署,以及如何使用 要sokcet.io 构建 WebRTC 信令消息服务器。socket.io 由于有房间的概念所以与WebRTC非常匹配,用它开发WebRTC信令服务器非常方便。

    另外,在本文中的例子只是一个简单例子并没有太多的实际价值。在后面的文章中我会以这个例子为基础,在其上面不断增加一些功能,最终你会看到一个完整的Demo程序。

    展开全文
  • vue-webRTC vue-webRTC演示 构建设置 # install dependencies npm install # serve with hot reload at localhost:8080 npm run dev # build for production with minification npm run build # build for ...
  • WebRTC视频教程分享

    2020-12-03 12:02:28
    在youtube上搬运了一些webrtc的相关教程,放到了b站如下。 https://www.bilibili.com/video/BV1Tt4y1Y7Uy https://www.bilibili.com/video/BV1nZ4y1G7cm https://www.bilibili.com/video/BV1K54y167Lt
    展开全文
  • 本文件可以直接下载在android studio上面运行,flutter的sdk请使用flutter_windows_1.24.0-10.2.pre-dev这个版本。
  • WebRTC是基于浏览器的Web技术,而移动智 能终端的最大共同点是都具备浏览器,因此WebRTC 几乎可以同时覆盖所有的移动智能终端,用户无需安 装软件就可以进行视频通信。而WebRTC又是基于 HTML5标准的开源技术,因此在...
  • 本文中提供下载的《WebRTC 零基础开发者教程》将以一个初学者的角度,从0开始逐步引导你掌握WebRTC开发的方方面面(当然,教程中更多的是操作性的内容,具体到技术原理和实现,显然不是本教程的讨论范畴)。...
  • 在学习 WebRTC 的过程中,学习的一个基本步骤是先通过 JS 学习 WebRTC的整体流程,在熟悉了整体流程之后,再学习其它端如何使用 WebRTC 进行互联互通。 我们已经在前面分享了信令服务器的搭建和 STUN/TURN服务器的...

    作者:李超,如遇到相关问题,可以点击这里与作者直接交流。

    前言

    在学习 WebRTC 的过程中,学习的一个基本步骤是先通过 JS 学习 WebRTC的整体流程,在熟悉了整体流程之后,再学习其它端如何使用 WebRTC 进行互联互通。

    我们已经在前面分享了信令服务器的搭建和 STUN/TURN服务器的搭建:

    rtcdeveloper.com/t/topic/133…

    rtcdeveloper.com/t/topic/137…

    本文将讲解 Android 端是如何使用WebRTC的,至于 P2P 穿越、STUN/TURN/ICE、RTP/RTCP协议、DTLS等内容不做讲解。

    对这方面有兴趣的同学可以单独再联系我。

    申请权限

    我们要使用 WebRTC 进行音视频互动时需要申请访问硬件的权限,至少要申请以下三种权限:

    • Camera 权限
    • Record Audio 权限
    • Intenet 权限

    在Android中,申请权限分为静态权限申请和动态权限申请,这对于做 Android 开发的同学来说已经是习以为常的事情了。下面我们就看一下具体如何申请权限:

    静态权限申请

    在 Android 项目中的 AndroidManifest.xml 中增加以下代码:

    
    ...
    
    <uses-feature android:name="android.hardware.camera" />
    <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.INTENET" />
    
    ...
    
    复制代码

    动态权限申请

    随着 Android 的发展,对安全性要求越来越高。除了申请静态权限之外,还需要动态申请权限。代码如下:

    void requestPermissions(String[] permissions, intrequestCode);
    复制代码

    实际上,对于权限这块的处理真正做细了要写不少代码,好在 Android 官方给我们又提供了一个非常好用的库 EasyPermissions , 有了这个库我们可以少写不少代码。使用 EasyPermissions 非常简单,在MainActivity中添加代码如下:

    ...
    
    protected void onCreate ( Bundle savedInstanceState ) {
    	...
    	
    	String[] perms = {
    				Manifest.permission.CAMERA,
    				Manifest.permission.RECORD_AUDIO
    	};
    	
    	if (!EasyPermissions.hasPermissions(this, perms)) {
    	    EasyPermissions.requestPermissions(this, 
    	    								   "Need permissions for camera & microphone", 
    	    									0, 
    	    									perms);
    	}
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode,
    									   String[] permissions, 
    									   int[] grantResults) {
    									   
        super.onRequestPermissionsResult(requestCode, 
    							         permissions, 
    							         grantResults);
    							         
        EasyPermissions.onRequestPermissionsResult(requestCode,
         										   permissions, 
         										   grantResults, 
         										   this);
    }
    
    ...
    
    复制代码

    通过添加以上代码,就将权限申请好了,是不是非常简单?权限申请好了,我们开始做第二步,看在 Android 下如何引入 WebRTC 库。

    引入库

    在我们这个例子中要引入两个比较重要的库,第一个当然就是 WebRTC 库了,第二个是 socket.io 库,用它来与信令服务器互联。

    首先我们看一下如何引入 WebRTC 库(我这里使用的是最新 Android Studio 3.3.2)。在 Module 级别的 build.gradle 文件中增加以下代码:

    ...
    dependencies {
        ...
        implementation 'org.webrtc:google-webrtc:1.0.+'
        ...
    }
    复制代码

    是不是非常简单?

    接下来要引入 socket.io 库,用它来与我们之前用 Nodejs 搭建的信令服务器进行对接。再加上前面用到的EasyPermissions库,所以真正的代码应写成下面的样子:

    ...
    dependencies {
        ...
        implementation 'io.socket:socket.io-client:1.0.0'
        implementation 'org.webrtc:google-webrtc:1.0.+'
        implementation 'pub.devrel:easypermissions:1.1.3'
    }
    复制代码

    通过上面的方式我们就将需要引入的库全部引入进来了。下面就可以开始真的 WebRTC 之旅了。

    万物的开始

    我们都知道万物有个起源,我们在开发 WebRTC 程序时也不例外,WebRTC程序的起源就是PeerConnectionFactory。这也是与使用 JS 开发 WebRTC 程序最大的不同点之一,因为在 JS 中不需要使用 PeerConnectionFactory 来创建 PeerConnection 对象。

    而在 Android/iOS 开发中,我们使用的 WebRTC 中的大部分对象基本上都是通过 PeerConnectionFactory 创建出来的。下面这张图就清楚的表达了 PeerConnectionFactory 在 WebRTC 中的地位。

    通过该图我们可以知道,WebRTC中的核心对象 PeerConnection、LocalMediaStream、LocalVideoTrack、LocalAudioTrack都是通过 WebRTC 创建出来的。

    PeerConnectionFactory的初始化与构造

    在 WebRTC 中使用了大量的设计模式,对于 PeerConnectionFactory 也是如此。它本身就是工厂模式,而这个构造 PeerConnection 等核心对象的工厂又是通过 builder 模式构建出来的。

    下面我们就来看看如何构造 PeerConectionFactory。在我们构造 PeerConnectionFactory 之前,首先要对其进行初始化,其代码如下:

    PeerConnectionFactory.initialize(...);
    复制代码

    初始化之后,就可以通过 builder 模式来构造 PeerConnecitonFactory 对象了。

    ...
    
    PeerConnectionFactory.Builder builder = 		
    				PeerConnectionFactory.builder()
                    	.setVideoEncoderFactory(encoderFactory)
                    	.setVideoDecoderFactory(decoderFactory);
                    
     ...
    
     return builder.createPeerConnectionFactory();
    
    复制代码

    通过上面的代码,大家也就能够理解为什么 WebRTC 要使用 buider 模式来构造 PeerConnectionFactory 了吧?主要是方便调整建造 PeerConnectionFactory的组件,如编码器、解码器等。

    从另外一个角度我们也可以了解到,要更换WebRTC引警的编解码器该从哪里设置了哈!

    音视频数据源

    有了PeerConnectionFactory对象,我们就可以创建数据源了。实际上,数据源是 WebRTC 对音视频数据的一种抽象,表式数据可以从这里获取。

    使用过 JS WebRTC API的同学都非常清楚,在 JS中 VideoTrack 和 AudioTrack 就是数据源。而在 Android 开发中我们可以知道 Video/AudioTrack 就是 Video/AudioSouce的封装,可以认为他们是等同的。

    创建数据源的方式如下:

    ...
    VideoSource videoSource = 
    					mPeerConnectionFactory.createVideoSource(false);
    mVideoTrack = mPeerConnectionFactory.createVideoTrack(
    													VIDEO_TRACK_ID, 
    													videoSource);
    													
    ...
    
    AudioSource audioSource = 
    					mPeerConnectionFactory.createAudioSource(new MediaConstraints());
    mAudioTrack = mPeerConnectionFactory.createAudioTrack(
    													AUDIO_TRACK_ID, 
    													audioSource);
            
    ...													
            
    复制代码

    数据源只是对数据的一种抽象,它是从哪里获取的数据呢?对于音频来说,在创建 AudioSource时,就开始从音频设备捕获数据了。对于视频来说我们可以指定采集视频数据的设备,然后使用观察者模式从指定设备中获取数据。

    接下来我们就来看一下如何指定视频设备。

    视频采集

    在 Android 系统下有两种 Camera,一种称为 Camera1, 是一种比较老的采集视频数据的方式,别一种称为 Camera2, 是一种新的采集视频的方法。它们之间的最大区别是 Camera1使用同步方式调用API,Camera2使用异步方式,所以Camera2更高效。

    我们看一下 WebRTC 是如何指定具体的 Camera 的:

    private VideoCapturer createVideoCapturer() {
            if (Camera2Enumerator.isSupported(this)) {
                return createCameraCapturer(new Camera2Enumerator(this));
            } else {
                return createCameraCapturer(new Camera1Enumerator(true));
            }
    }
    
    
    private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
            final String[] deviceNames = enumerator.getDeviceNames();
    
            // First, try to find front facing camera
            Log.d(TAG, "Looking for front facing cameras.");
            for (String deviceName : deviceNames) {
                if (enumerator.isFrontFacing(deviceName)) {
                    Logging.d(TAG, "Creating front facing camera capturer.");
                    VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
                    if (videoCapturer != null) {
                        return videoCapturer;
                    }
                }
            }
    
            // Front facing camera not found, try something else
            Log.d(TAG, "Looking for other cameras.");
            for (String deviceName : deviceNames) {
                if (!enumerator.isFrontFacing(deviceName)) {
                    Logging.d(TAG, "Creating other camera capturer.");
                    VideoCapturer videoCapturer = enumerator.createCapturer(deviceName, null);
                    if (videoCapturer != null) {
                        return videoCapturer;
                    }
                }
            }
            
            return null;
    }
        
    复制代码

    上面代码的逻辑也比较简单:

    • 首先看 Android 设备是否支持 Camera2.
    • 如果支持就使用 Camera2, 如果不支持就使用 Camera1.
    • 在获到到具体的设备后,再看其是否有前置摄像头,如果有就使用
    • 如果没有有效的前置摄像头,则选一个非前置摄像头。

    通过上面的方法就可以拿到使用的摄像头了,然后将摄像头与视频源连接起来,这样从摄像头获取的数据就源源不断的送到 VideoTrack 里了。

    下面我们来看看 VideoCapture 是如何与 VideoSource 关联到一起的:

    ...
    
    mSurfaceTextureHelper = 
    			SurfaceTextureHelper.create("CaptureThread",
    										mRootEglBase.getEglBaseContext());
    
    mVideoCapturer.initialize(mSurfaceTextureHelper,
     						  getApplicationContext(), 
     						  videoSource.getCapturerObserver());
    
    ...
    
    mVideoTrack.setEnabled(true);
    ...
    
    复制代码

    上面的代码中,在初始化 VideoCaptuer 的时候,可以过观察者模式将 VideoCapture 与 VideoSource 联接到了一起。因为 VideoTrack 是 VideoSouce 的一层封装,所以此时我们开启 VideoTrack 后就可以拿到视频数据了。

    当然,最后还要调用一下 VideoCaptuer 对象的 startCapture 方法真正的打开摄像头,这样 Camera 才会真正的开始工作哈,代码如下:

    @Override
    protected void onResume() {
        super.onResume();
        mVideoCapturer.startCapture(VIDEO_RESOLUTION_WIDTH, 
        							VIDEO_RESOLUTION_HEIGHT, 
        							VIDEO_FPS);
    }
    复制代码

    拿到了视频数据后,我们如何将它展示出来呢?

    渲染视频

    在 Android 下 WebRTC 使用OpenGL ES 进行视频渲染,用于展示视频的控件是 WebRTC 对 Android 系统控件 SurfaceView 的封装。

    WebRTC 封装后的 SurfaceView 类为 org.webrtc.SurfaceViewRenderer。在界面定义中应该定义两个SurfaceViewRenderer,一个用于显示本地视频,另一个用于显示远端视频。

    其定义如下:

    ...
    
    <org.webrtc.SurfaceViewRenderer
            android:id="@+id/LocalSurfaceView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center" />
    
    <org.webrtc.SurfaceViewRenderer
        android:id="@+id/RemoteSurfaceView"
        android:layout_width="120dp"
        android:layout_height="160dp"
        android:layout_gravity="top|end"
        android:layout_margin="16dp"/>
    
    ...
    
    复制代码

    通过上面的代码我们就将显示视频的 View 定义好了。光定义好这两个View 还不够,还要对它做进一步的设置:

    ...
    
    mLocalSurfaceView.init(mRootEglBase.getEglBaseContext(), null);
    mLocalSurfaceView.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
    mLocalSurfaceView.setMirror(true);
    mLocalSurfaceView.setEnableHardwareScaler(false /* enabled */);
    
    ...
    复制代码

    其含义是:

    • 使用 OpenGL ES 的上下文初始化 View。
    • 设置图像的拉伸比例。
    • 设置图像显示时反转,不然视频显示的内容与实际内容正好相反。
    • 是否打开便件进行拉伸。

    通过上面的设置,我们的 view 就设置好了,对于远端的 Veiw 与本地 View 的设置是一样的,我这里就不再赘述了。

    接下来将从摄像头采集的数据设置到该view里就可以显示了。设置非常的简单,代码如下:

    ...
    mVideoTrack.addSink(mLocalSurfaceView);
    ...
    复制代码

    对于远端来说与本地视频的渲染显示是类似的,只不过数据源是从网络获取的。

    通过以上讲解,大家应该对 WebRTC 如何采集数据、如何渲染数据有了基本的认识。下面我们再看来下远端的数据是如何来的。

    创建 PeerConnection

    要想从远端获取数据,我们就必须创建 PeerConnection 对象。该对象的用处就是与远端建立联接,并最终为双方通讯提供网络通道。

    我们来看下如何创建 PeerConnecion 对象。

    ...
    PeerConnection.RTCConfiguration rtcConfig = 
    				new PeerConnection.RTCConfiguration(iceServers);
    ...
    PeerConnection connection =
                    mPeerConnectionFactory.createPeerConnection(rtcConfig,
                                                                mPeerConnectionObserver);
            
    ...
    connection.addTrack(mVideoTrack, mediaStreamLabels);
    connection.addTrack(mAudioTrack, mediaStreamLabels);
    ...
    复制代码

    PeerConnection 对象的创建还是要使我们之前讲过的 PeerConnectionFactory 来创建。WebRTC 在建立连接时使用 ICE 架构,一些参数需要在创建 PeerConnection 时设置进去。

    另外,当 PeerConnection 对象创建好后,我们应该将本地的音视频轨添加进去,这样 WebRTC 才能帮我们生成包含相应媒体信息的 SDP,以便于后面做媒体能力协商使用。

    通过上面的方式,我们就将 PeerConnection 对象创建好了。与 JS 中的 PeerConnection 对象一样,当其创建好之后,可以监听一些我们感兴趣有事件了,如收到 Candidate 事件时,我们要与对方进行交换。

    PeerConnection 事件的监听与 JS 还是有一点差别的。在 JS 中,监听 PeerConnection的相关事件非常直接,直接实现peerconnection.onXXX就好了。而 Android 中的方式与 JS 略有区别,它是通过观察者模式来监听事件的。大家这点一定要注意!

    双方都创建好 PeerConnecton 对象后,就会进行媒体协商,协商完成后,数据在底层就开始传输了。

    信令驱动

    在整个 WebRTC 双方交互的过程中,其业务逻辑的核心是信令, 所有的模块都是通过信令串联起来的。

    以 PeerConnection 对象的创建为例,该在什么时候创建 PeerConnection 对象呢?最好的时机当然是在用户加入房间之后了 。

    下面我们就来看一下,对于两人通讯的情况,信令该如何设计。在我们这个例子中,可以将信令分成两大类。第一类为客户端命令;第二类为服务端命令;

    客户端命令有:

    • join: 用户加入房间
    • leave: 用户离开房间
    • message: 端到端命令(offer、answer、candidate)

    服务端命令:

    • joined: 用户已加入
    • leaved: 用户已离开
    • other_joined:其它用户已加入
    • bye: 其它用户已离开
    • full: 房间已满

    通过以上几条信令就可以实现一对一实时互动的要求,是不是非常的简单?

    在本例子中我们仍然是通过socket.io与之前搭建的信令服备器互联的。由于 socket.io 是跨平台的,所以无论是在 js 中,还是在 Android 中,我们都可以使用其客户端与服务器相联,非常的方便。

    下面再来看一下,收到不同信令后,客户端的状态变化:

    客户端一开始的时候处于 Init/Leave 状态。当发送 join 消息,并收到服务端的 joined 后,其状态变为 joined。

    此时,如果第二个用户加入到房间,则客户端的状态变为了 joined_conn, 也就是说此时双方可以进行实时互动了。

    如果此时,该用户离开,则其状态就变成了 初始化状态。其它 case 大家可以根据上面的图自行理解了。

    小结

    本文首先介绍了在 Android 中使用 WebRTC 要需申请的权限,以及如何引入 WebRTC 库。然后从如何采集音视频数据、如何渲染、如何与对方建立连接等几个方面向大家详细介绍了如何在 Android 系统下开发一套 1对1的直播系统。

    本文介绍的知识与我之前所写的通过 《Nodejs 搭建 WebRTC 信令服务器》完整的构成了一套 1对1直播系统。希望通过本文的学习,同学们可以快速的撑握 WebRTC 的使用,并根据自己的需要构建自己的直播系统。

    谢谢!

    转载于:https://juejin.im/post/5ce5156ae51d45772a49ac8a

    展开全文
  • webrtc入门与实战视频教程 从事于音视频技术研发,ffmpeg,webr...

    扫码下载「CSDN程序员学院APP」,1000+技术好课免费看

    APP订阅课程,领取优惠,最少立减5元 ↓↓↓

    订阅后:请点击此处观看视频课程

     

    视频教程-webrtc入门与实战视频教程-C/C++

    学习有效期:永久观看

    学习时长:192分钟

    学习计划:4天

    难度:

     

    口碑讲师带队学习,让你的问题不过夜」

    讲师姓名:杨鑫

    研究员/技术专家/教授

    讲师介绍:从事于音视频技术研发,ffmpeg,webrtc等有比较深入的研究。

    ☛点击立即跟老师学习☚

     

    「你将学到什么?」

    webrtc入门与实战视频培训课程是通过作者多年经验总结出的一套webrtc入门教程,学完此课程,你能搭建出一套android互通或者web互通或者android对web互通的webrtc服务器,此课程由浅入深讲解了从编译到完整搭建一套webrtc demo,包括apprtc房间服务、collider信令服务、coturn穿透服务,即便你没有linux基础也能搭建,让你轻轻松松入门。

     

    「课程学习目录」

    第1章:webrtc入门到深入了解
    1.webrtc学习路线(必看)
    2.webrtc demo分析与说明
    3.webrtc房间服务搭建
    4.webrtc信令服务搭建
    5.webrtc turn服务搭建
    6.webrtc之c++ vs2015编译指导
    7.webrtc之把ninja工程转换成vs工程
    8.peerconnect_client之整体讲解

     

    7项超值权益,保障学习质量」

    • 大咖讲解

    技术专家系统讲解传授编程思路与实战。

    • 答疑服务

    专属社群随时沟通与讲师答疑,扫清学习障碍,自学编程不再难。

    • 课程资料+课件

    超实用资料,覆盖核心知识,关键编程技能,方便练习巩固。(部分讲师考虑到版权问题,暂未上传附件,敬请谅解)

    • 常用开发实战

    企业常见开发实战案例,带你掌握Python在工作中的不同运用场景。

    • 大牛技术大会视频

    2019Python开发者大会视频免费观看,送你一个近距离感受互联网大佬的机会。

    • APP+PC随时随地学习

    满足不同场景,开发编程语言系统学习需求,不受空间、地域限制。

     

    「什么样的技术人适合学习?」

    • 想进入互联网技术行业,但是面对多门编程语言不知如何选择,0基础的你
    • 掌握开发、编程技术单一、冷门,迫切希望能够转型的你
    • 想进入大厂,但是编程经验不够丰富,没有竞争力,程序员找工作难。

     

    「悉心打造精品好课,4天学到大牛3年项目经验」

    【完善的技术体系】

    技术成长循序渐进,帮助用户轻松掌握

    掌握C/C++知识,扎实编码能力

    【清晰的课程脉络】

    浓缩大牛多年经验,全方位构建出系统化的技术知识脉络,同时注重实战操作。

    【仿佛在大厂实习般的课程设计】

    课程内容全面提升技术能力,系统学习大厂技术方法论,可复用在日后工作中。

     

    「你可以收获什么?」

    帮助学员快速入门webrtc,能快速编译出android或者搭建web 版webrtc demo,熟悉coturn如何正确配置,实现不同局域网和4G互通。

     

    展开全文
  • 最新webrtc视频全套教程

    万次阅读 热门讨论 2018-01-03 10:14:00
    为了满足广大朋友需要,特地制作了webrtc视频教程,此课程是作者多年经验总结出的所制作的一套webrtc快速入门教程,学完此课程,你能搭建出一套android互通或者web互通或者android对web互通的webrtc demo,此课程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,212
精华内容 884
关键字:

webrtc教程