Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WebRTC 如何在安卓系统上采集视频数据

WebRTC 如何在安卓系统上采集视频数据

作者头像
liuzhen007
发布于 2022-02-23 12:08:22
发布于 2022-02-23 12:08:22
2.8K00
代码可运行
举报
文章被收录于专栏:流媒体音视频流媒体音视频
运行总次数:0
代码可运行

目录

前言

正文

  • 摄像头1.0和2.0接口对比
  • Camera1Capturer 接口类
  • Camera2Capturer 接口类

结论

前言

WebRTC 作为一个开源的实时音视频通讯方案,经过多年的发展基本上已经支持了所有的常用终端,比如 windows、mac、AndroidiOS等。我们都知道音视频通讯的前提是采集本地的音频和视频数据信息。今天,我们就来先了解一下 WebRTC 在安卓端是如何采集视频信号的。

正文

安卓设备和苹果iOS设备都属于移动端,在音视频处理的很多地方都是类似的。比如,视频画面的采集和本地预览都会涉及到横屏显示和竖屏显示问题,视频编码时都需要考虑画面角度(0度、90度、180度、270度)问题。

为此,WebRTC 为安卓端和 iOS 端的 SDK 都提供了非常好用的 API 接口类。其中,安卓端的视频采集类是 CameraCapturer,注意,目前安卓端的摄像头采集有两种方案,一种是使用比较传统的 Camera1Capturer 类,另一种是使用比较新的 Camera2Capturer 类。接下来,分别介绍一下。

之所以会出现 Camera1Capturer 类和 Camera2Capturer 类两套不同的API方案,主要是因为谷歌在开发 Android 5.0 时,对摄像头API进行了全新的颠覆性设计,新增了全新的 Camera V2 接口,这些API不仅大幅提高了 Android 系统拍照的功能,还能支持 RAW 照片输出,甚至允许程序调整相机的对焦模式、曝光模式、快门等。

摄像头1.0和2.0接口对比

下面通过一张对比表格来简单了解一下摄像头1.0和2.0接口的不同。

Camera1Capturer 接口类

Camera1Capturer 接口类是如何采集摄像头视频画面的,下面结合代码介绍一下。大致流程如下:

步骤一、打开安卓本地前置摄像头,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final android.hardware.Camera camera;
try {
  camera = android.hardware.Camera.open(CameraInfo.CAMERA_FACING_FRONT);
} catch (RuntimeException e) {
  callback.onFailure(FailureType.ERROR, e.getMessage());
  return;
}

步骤二、设置本地预览画面的显示图层,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {
  camera.setPreviewTexture(surfaceTextureHelper.getSurfaceTexture());
} catch (IOException | RuntimeException e) {
  camera.release();
  callback.onFailure(FailureType.ERROR, e.getMessage());
  return;
}

步骤三、设置摄像头参数信息。根据前置摄像头支持的采集参数和系统设置的采集参数进行匹配,计算出最佳且支持的采集参数,其中采集参数涉及画面宽、画面高、画面帧率等,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
final CaptureFormat captureFormat;
try {
  final android.hardware.Camera.Parameters parameters = camera.getParameters();
  captureFormat = findClosestCaptureFormat(parameters, width, height, framerate);
  final Size pictureSize = findClosestPictureSize(parameters, width, height);
  updateCameraParameters(camera, parameters, captureFormat, pictureSize, captureToTexture);
} catch (RuntimeException e) {
  camera.release();
  callback.onFailure(FailureType.ERROR, e.getMessage());
  return;
}

步骤四、设置摄像头采集角度。这是一个预设参数,一般在实际使用过程中会根据当前手机的旋转角度动态变化,可选数值有0度、90度、180度、270度,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
camera.setDisplayOrientation(0 /* degrees */);

步骤五、设置本地视图,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
eglBase = EglBase.create(null /* sharedContext */, EglBase.CONFIG_PLAIN);
localRenderer = (SurfaceViewRenderer) findViewById(R.id.local_renderer);

localRenderer.init(eglBase.getEglBaseContext(), null /* rendererEvents */, EglBase.CONFIG_PLAIN, new GlRectDrawer());

videoCapturerSurfaceTextureHelper =
    SurfaceTextureHelper.create("VideoCapturerThread", eglBase.getEglBaseContext());

步骤六、设置采集数据回调方法,参考代码如下:

oesTextureId = GlUtil.generateTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); surfaceTexture = new SurfaceTexture(oesTextureId); setOnFrameAvailableListener(surfaceTexture, (SurfaceTexture st) -> { hasPendingTexture = true; tryDeliverTextureFrame(); }, handler); 通过上面的六个简单步骤,我们就可以完成在安卓系统上摄像头采集和本地画面预览的效果。接下来,我们看一下 Camera2Capturer 接口类如何完成相同的功能。

Camera2Capturer 接口类

Camera2Capturer 接口类基于安卓系统的 Camera V2 接口开发封装的,原因是谷歌在 Android 5.0 中对摄像头API进行了全新的颠覆性设计,不仅大幅提高了 Android 系统拍照的功能,还能支持 RAW 照片输出,甚至允许程序调整相机的对焦模式、曝光模式、快门等。

那么,WebRTC 中又是如何利用 Camera2Capturer 接口类采集安卓系统的摄像头画面的呢?下面也结合代码分步骤介绍一下。

步骤一、根据安卓设备的相机ID打开本地摄像头,同时设置 CameraStateCallback 回调方法,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {
  cameraManager.openCamera(cameraId, new CameraStateCallback(), cameraThreadHandler);
} catch (CameraAccessException e) {
  reportError("Failed to open camera: " + e);
  return;
}

步骤二、设置本地预览画面的显示图层,根据步骤一中设置的摄像头回调事件 onOpened 进行设置,从而绑定图层和摄像头的关系,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  surfaceTextureHelper.setTextureSize(captureFormat.width, captureFormat.height);
  surface = new Surface(surfaceTextureHelper.getSurfaceTexture());
  try {
    camera.createCaptureSession(
        Arrays.asList(surface), new CaptureSessionCallback(), cameraThreadHandler);
  } catch (CameraAccessException e) {
    reportError("Failed to create capture session. " + e);
    return;
  }

步骤三、设置摄像头相关的采集参数,同样是根据上一步中设置的回调事件,不过这次是 onConfigured 进行设置,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   try {
    final CaptureRequest.Builder captureRequestBuilder =
        cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
        new Range<Integer>(captureFormat.framerate.min / fpsUnitFactor,
            captureFormat.framerate.max / fpsUnitFactor));
    captureRequestBuilder.set(
        CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
    captureRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
    chooseStabilizationMode(captureRequestBuilder);
    chooseFocusMode(captureRequestBuilder);
    captureRequestBuilder.addTarget(surface);
    session.setRepeatingRequest(
        captureRequestBuilder.build(), new CameraCaptureCallback(), cameraThreadHandler);
  } catch (CameraAccessException e) {
    reportError("Failed to start capture request. " + e);
    return;
  }

步骤四、设置视频采集数据回调方法,通过监听渲染图层中的 startListening 方法回调的视频帧得到视频数据,然后通知其他模块,参考代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
   surfaceTextureHelper.startListening((VideoFrame frame) -> {
    checkIsOnCameraThread();

    if (state != SessionState.RUNNING) {
      Logging.d(TAG, "Texture frame captured but camera is no longer running.");
      return;
    }

    if (!firstFrameReported) {
      firstFrameReported = true;
      final int startTimeMs =
          (int) TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - constructionTimeNs);
      camera2StartTimeMsHistogram.addSample(startTimeMs);
    }
    final VideoFrame modifiedFrame =
        new VideoFrame(CameraSession.createTextureBufferWithModifiedTransformMatrix(
                           (TextureBufferImpl) frame.getBuffer(),
                           /* mirror= */ isCameraFrontFacing,
                           /* rotation= */ -cameraOrientation),
            /* rotation= */ getFrameOrientation(), frame.getTimestampNs());
    events.onFrameCaptured(Camera2Session.this, modifiedFrame);
    modifiedFrame.release();
  });

再后续的流程就和 Camera1Capturer 接口类相同了,这里就不再赘述了。

需要注意的是,安卓系统采集完摄像头的视频画面后,处理逻辑一般会一分为二,一部分数据流用来本地预览显示,一部分数据流送到编码模块,进行数据组包并发送给对端。因此,我们在使用过程中经常会遇到本地预览画面没有问题,但是传输到远端的视频画面出现问题,或者是本地预览画面有问题,但是传输到远端的视频却是正常的,类似的问题有花屏、显示比例、裁剪等。

结论

本文基本上已经介绍了 WebRTC 是如何在安卓系统上采集本地摄像头画面的,但是,这仅仅是众多流程中一个小环节,后续还有预览、编码、组包、传输、解包、解码、渲染等过程。关于别的部分的内容,我们在后续章节再继续介绍。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 玩转音视频 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
视频直播技术--Android视频采集(Camera1)
今天为大家介绍一下使用Camera1进行视频采集。之前我写过一篇文章介绍的是Camera2进行视频采集。那么有人会问,为什么有了Camera2还要介绍Camera1呢?这里最主要的原因是因为Android版本众多,Camera2是Google新推出的视频采集架构,但很多老的机型还不支持,所以为了兼容性的问题,我们还不能放弃使用Camera1进行视频的采集。
音视频_李超
2020/04/02
5.4K1
浅析WebRtc中视频数据的收集和发送流程
本文是基于PineAppRtc开源项目https://github.com/thfhongfeng/PineAppRtc
BennuCTech
2021/12/10
1.1K0
浅析WebRtc中视频数据的收集和发送流程
关于Camera性能优化的一些建议
上一篇文章主要介绍Camera的基本功能,我们在做相机应用的时候,除了相机的基本功能,还有一个非常重要的点,就是性能不能查,有几个方面:预览不能卡顿、拍照速度要快、录制视频不能卡。
马上就说
2022/05/25
2.7K0
关于Camera性能优化的一些建议
Android端实现1对1音视频实时通话
在学习 WebRTC 的过程中,学习的一个基本步骤是先通过 JS 学习 WebRTC的整体流程,在熟悉了整体流程之后,再学习其它端如何使用 WebRTC 进行互联互通。
音视频_李超
2020/04/02
2.7K0
Android Camera2 API 同时使用前后摄像头预览
不久前,我承担了从运行Android的设备的前后摄像头获取同步提要的任务。 像往常一样,我去了Stack Overflow,然后去了GitHub,然后去了其他博客,才意识到我可能独自一人。 难过的感觉吧?
字节流动
2022/09/26
3.4K0
Android Camera2 API 同时使用前后摄像头预览
Android AVDemo(7):视频采集,视频系列来了丨音视频工程示例
iOS/Android 客户端开发同学如果想要开始学习音视频开发,最丝滑的方式是对音视频基础概念知识有一定了解后,再借助 iOS/Android 平台的音视频能力上手去实践音视频的采集 → 编码 → 封装 → 解封装 → 解码 → 渲染过程,并借助音视频工具来分析和理解对应的音视频数据。
关键帧
2022/06/13
1K0
Android AVDemo(7):视频采集,视频系列来了丨音视频工程示例
Android Camera开发序列:Camera2 API 的简单描述和调用(预览、拍照、录像
Android 5.1 以后,添加了Camera2 的API,能够满足更多操纵camera的场景。当然,相对应camera1的调用,也变的复杂一点。
小驰行动派
2021/04/19
2K0
RenderDemo(2):用 OpenGL 渲染视频丨音视频工程示例
渲染是音视频技术栈相关的一个非常重要的方向,视频图像在设备上的展示、各种流行的视频特效都离不开渲染技术的支持。
关键帧
2023/02/14
1.5K0
RenderDemo(2):用 OpenGL 渲染视频丨音视频工程示例
音视频直播技术--Android视频采集(Camera2)
今天为大家介绍一下如何在 Android 上进行视频采集。在 Android 系统下有两套 API 可以进行视频采集,它们是 Camera 和 Camera2 。Camera是以前老的 API ,从 Android 5.0(21)之后就已经放弃了。我今天主要给大家介绍一下如何使用 Camera2 进行视频的采集。原码可以在这里获取
音视频_李超
2020/04/02
2.1K0
TSINGSEE青犀视频开发webrtc项目如何实现Windows视频采集?
视频都是通过平台系统提供的API来实现视频采集,对于TSINGSEE青犀视频正在开发的webrtc项目来说,也有一套标准。
TSINGSEE青犀视频
2021/07/14
3780
Android TRTC 推自定义采集的视频数据
如果开发者想在 TRTC 中集成第三方美颜库来实现美颜、滤镜等功能,第三方库的美颜功能输入数据格式支持有 camera 的原始数据(YUV 数据)、纹理数据(Textureid)。开发者想实现该功能,需要采用自定义采集视频数据接口,然后复用 LiteAVSDK 的编码和推流功能。
腾讯云-chaoli
2019/07/07
1.9K0
Android TRTC 推自定义采集的视频数据
Android摄像头采集选Camera1还是Camera2?
好多开发者纠结,Android平台采集摄像头,到底是用Camera1还是Camera2?实际上,Camera1和Camera2分别对应相机API1和相机API2。Android 5.0开始,已经弃用了Camera API1,新平台重点开发Camera API2,Camera API1 会逐渐被淘汰。Camera API2 框架为应用提供更接近底层的相机控件,包括高效的零复制连拍/视频流以及曝光、增益、白平衡增益、颜色转换、去噪、锐化等方面的每帧控件。
音视频牛哥
2024/08/08
3160
Android摄像头采集选Camera1还是Camera2?
iOS端 TRTC v2 版本自定义采集视频数据实现
实时音视频 SDK 默认会采集摄像头数据,如果开发者想在 TRTC 中集成使用第三方美颜库来实现美颜、滤镜等预处理功能,可以采用自定义采集视频数据接口,然后复用 LiteAVSDK 的编码和推流功能。 目前自定义采集支持的平台包括 iOS 、Android 、Mac OS 、Windows 。接口文档参考:https://cloud.tencent.com/document/product/647/32259#.E8.87.AA.E5.AE.9A.E4.B9.89.E9.87.87.E9.9B.86.E5.92.8C.E6.B8.B2.E6.9F.93
腾讯云-chaoli
2019/07/07
2.1K1
iOS端 TRTC v2 版本自定义采集视频数据实现
[-综合篇-] 相机、OpenGL、视频、Flutter和SurfaceView
认识一个类,相当于结交一位朋友;看一篇源码,相当于一次顶级的会话; 读一个框架,相当于见证一段思想;做一个程序,相当于创造一个生命; 一次Git提交,相当于记录一次成长;生活也许并非那么美好,但一切可以这么崇高。----张风捷特烈
张风捷特烈
2020/04/30
3.2K0
[-综合篇-] 相机、OpenGL、视频、Flutter和SurfaceView
Android Camera2 与 Camera API技术探究和RAW数据采集
Android Camera2 是 Android 系统中用于相机操作的一套高级应用程序接口(API),它取代了之前的 Camera API。以下是关于 Android Camera2 的一些主要信息:
音视频牛哥
2024/10/01
6260
【Android RTMP】Android Camera 视频数据采集预览 ( 视频采集相关概念 | 摄像头预览参数设置 | 摄像头预览数据回调接口 )
1 . 图像采集显示组件 : 布局文件中添加 SurfaceView , 用于在该 SurfaceView 组件中预览 Camera 采集的图像数据 ;
韩曙亮
2023/03/27
1.6K0
Android平台如何采集摄像头数据并实现低延迟RTMP推送
2015年,我们发布了第一版的Android平台RTMP摄像头|屏幕直播推送模块,几经迭代,功能强大、性能优异,在前些年几乎已经是业内延迟体验和口碑最好的RTMP模块了(毫秒级延迟,低延迟模式下100多毫秒)。鉴于我们侧重于传统行业音视频直播方案,我们从以下几个维度,介绍下Android平台RTMP摄像头采集推送模块的使用场景。
音视频牛哥
2024/11/20
2870
WebRTC视频数据流程分析
直播回放:https://www.livevideostack.cn/video/online-piasy/
LiveVideoStack
2020/09/14
3K0
TRTCSDK自定义采集Texture2D视频通话
摄像头通话功能,是TRTCSDK对系统摄像头进行了封装,采集摄像头数据,编码传输通话。
ppchao
2020/12/03
1.3K1
TRTCSDK自定义采集Texture2D视频通话
Android平台实现Camera2数据推送到RTMP服务器
在Google 推出Android 5.0的时候, Android Camera API 版本升级到了API2(android.hardware.camera2), 之前使用的API1(android.hardware.camera)就被标为 Deprecated 了。
音视频牛哥
2021/03/02
1.4K0
推荐阅读
相关推荐
视频直播技术--Android视频采集(Camera1)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验