Costel 项目评审

//--- theme: github highlight: a11y-dark

项目背景:

该项目场景是方便用户在厨房也能继续经过智能平板观看电视节目。咱们须要开发一个应用用来接收电视传过来的音视频数据,而后将音视频数据传输到平板端进行播放,用户能经过平板来操控电视。git

需求分析:

1.功能性需求分析

  • TV Box开机后,默认的WIFI名称为COSTEL001
  • PAD须要接收TV的APP,当打开须要默认与TV BOX相连
  • 818板卡解TV端发送的音视频信号(后方案变为从摄像头获取mipi信号的数据,经过录音获取音频数据)
  • 经过网络传输,音视频数据在PAD端进行播放
  • PAD在播放网络视频的时候,可将声音经过蓝牙传给TV BOX内置的喇叭播放
  • 须要的遥控菜单,包括音量+/-;频道+/-;关机;确认键等,按键信息最终由RK3128控制

image.png

实际上,开发过程当中,还能挖掘出了下面几个隐藏的需求。github

  • 因为板卡没法发出热点,因此不能经过热点的方式进行配对链接。经沟通,使用同一局域网进行链接。此方案存在的隐患为:其它设备在同一局域网下,也可获取TV数据,并调用TV的喇叭,因此须要 鉴权功能;
  • 当TV进行传输音视频的同时,PAD本地若是也正在播放媒体,就会将声音传给TV喇叭,这很明显是不合理的。

2. 非功能性需求分析

项目中视频方面采用的技术逻辑为: 咱们还须要考虑不少非功能性的需求。具体来说,我总结了如下几个比较重要的方面。算法

  • 易用性

包括产品的易用性和代码的易用性。产品的易用性是指:用户不须要花太多时间思考就能上手应用,老小皆宜。代码的易用性是指:框架是否易集成、易插拔、跟业务代码是否松耦合、提供的接口是否够灵活等等,都是咱们应该花心思去思考和设计的。markdown

  • 性能

咱们但愿应用自己的代码执行效率,对系统没有太多性能上的影响。音视频播放一方面,咱们但愿它是低延迟的,音视频是同步的;另外一方面,咱们但愿应用自己对内存的消耗不能太大。这块后期需认真思考。网络

  • 扩展性

是指在不修改或尽可能少修改代码的状况下添加新的功能,即符合开闭原则。在增长一些新的视频数据的获取方式、音频获取方式、或者编码方式的时候,不需改动原有逻辑。框架

技术选型:

  • 设备配对:818板卡发送NSD携带port,PAD端经过扫描同一ip网段下的该port设备,经过CRCP协议实现配对ide

  • 应用鉴权初步方案:1.818板卡未配对,正常发送带port的NSD服务;2.当有设备配对后,818用配对设备的DeviceId经算法加密后发送加密port的NSD服务,PAD端有重试机制,第一次直接链接该port,失败后使用算法解密后尝试链接。链接成功之后默认配对性能

  • 818视频采集、解码及播放:Camera2 + MediaCodeC + SurfaceTexture,编码格式采用h264ui

  • 818音频采集、解码及播放:AudioRecord + MediaCodec/OpusLib +AudioTrack,编码格式为Opus。 VS AAC:在编码延时方面。首先,Opus是由两个编解码器Silk和Celt融合而成。Celt 仅编码延时方面是优于AAC 的,合并成Opus后有所增加,但仍是低于AAC。 质量方面:Celt 最初的质量不如 AAC。在成为 Opus 的一部分后,牺牲了一部分的延时,增长了一些新技术以后,质量与 AAC 至关,甚至更好一些。在压缩率方面,Opus里共有32种模式用来处理不一样种类的信号,opus在码率和音质上的确是有优点的。(参考 :https://zhuanlan.zhihu.com/p/66719842)this

  • TVBOX喇叭进行播放: 当PAD中止电视回传 且 本地有媒体播放时,经过BlueTooth蓝牙配对

  • PAD遥控器指令发送:PAD 与818间经过CRCP传输遥控码,818与3553之间经过AIDL传遥控码

总体工做流程

image.png

时序图

1.Camera2采集视频数据:

image.png 整个过程使用Camera2来获取数据,获取的数据经过MediaCodec编码,使用H264协议,接收端接收到数据以后解码,而后经过TextureView渲染,大概是这么一个流程,下面记录下实现过程。

1.相机初始化 获取可用的相机列表、相机相关的属性

String[] cameraIdList = mCameraManager.getCameraIdList();
 CameraCharacteristics cameraCharacteristics = mCameraManager.getCameraCharacteristics(cameraId);
复制代码

2.在打开相机以前先,先要去获取相机支持的最接近的预览尺寸,而后要实例化一个ImageReader,用来接收Camera2的可用数据。这些作完以后,须要监测TextureView是否可用,不可用先设置setSurfaceTextureListener监听,可用以后再来打开相机。 添加接收数据回调的Target Surface

mPreviewSize = getBestSupportedSize(new ArrayList<Size>(Arrays.asList(map.getOutputSizes(SurfaceTexture.class))));
mImageReader.setOnImageAvailableListener(this, mBackgroundHandler);
复制代码

3.创建Camera2预览会话,经过RepeatingRequest()进行连续请求

private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(@NonNull CameraDevice cameraDevice) {
        Camera2TextureView.this.mCameraDevice = cameraDevice;
        createCaptureSession();
    }
   
    mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        //添加接收数据回调的Target Surface
        mPreviewRequestBuilder.addTarget(mWorkingSurface);
        mPreviewRequestBuilder.addTarget(mImageReader.getSurface());
        
        mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mBackgroundHandler);

复制代码

4.经过imageReader 读取相机数据。因为Camera2的yuv数据获取到数据须要本身手动拼接,因此这里是和Camera1不一样的,获取到的数据拼接成nv21,须要转化成nv12,由于MediaCodec不支持nv21。采集到数据以后,经过mediaCodec进行编码操做。

public void onImageAvailable(ImageReader reader) {

Image image= reader.acquireNextImage();
复制代码

image.png

  1. 声音录制编码及解码播放

用户登陆成功uml时序图.png MirrorAudioManager是上帝类,持有AudioRecorder 和AudioEncoder的

UML图

1.设备配对时鉴权

相关文章
相关标签/搜索