音视频之进程间传递 YUV 格式视频流,解决不能同时调用 Camera 问题

栏目: IOS · Android · 发布时间: 5年前

内容简介:由于项目需求,需要在执法仪本地录像的时候,执法软件能正常的使用设备本身的 Camera 资源。由于 Android 系统自身不允许多个软件同时使用 Camera 资源,故开发一套

由于项目需求,需要在执法仪本地录像的时候,执法软件能正常的使用设备本身的 Camera 资源。由于 Android 系统自身不允许多个软件同时使用 Camera 资源,故开发一套 内存共享 子码流传输协议,当执法软件需要视频流的时候,向执法仪设备请求往 MemoryFile 中写入 YUV 格式的视频流,执法软件每隔一段时间循环的去指定的内存中 read YUV 视频流。

完整代码入口

流程图

音视频之进程间传递 YUV 格式视频流,解决不能同时调用 Camera 问题

效果图

  • 本地相机未打开

    音视频之进程间传递 YUV 格式视频流,解决不能同时调用 Camera 问题
  • 本地相机打开

    音视频之进程间传递 YUV 格式视频流,解决不能同时调用 Camera 问题

简要流程及示例代码说明

  1. 执法仪服务端收到客户端的开启视频流写入内存的指令

    //处理客服端发送过来的需要子码流的数据
        private void onHandleAction(Context context, Intent intent) {
            switch (intent.getAction()) {
                /**
                 * 需要子码流
                 */
                case Constants.ACTION_CAMERE_CORE_SHOW:
                    //如果正在发送视频流,就不需要执行后面代码了
                    if (!MemoryFileServiceManager.getInsta(context).isSendVideoFrame())
                        MemoryFileServiceManager.getInsta(context).setSendVideoFrame(true, intent);
                    break;
            }
        }
    复制代码
  2. 服务端获取开启视频的条件

    private void sendVideoFrame(Intent intent) {
            if (intent != null && intent.getExtras() != null) {
                Bundle extras = intent.getExtras();
                //获取需要预览的宽
                Constants.PREVIEWHEIGHT = extras.getInt(Constants.Config.PREVIEW_WIDTH, 1280);
                //获取需要预览的高
                Constants.PREVIEWHEIGHT = extras.getInt(Constants.Config.PREVIEW_HEIGHT, 720);
                //需要绑定对方服务的进程
                Constants.BIND_OTHER_SERVICE_PCK = extras.getString(Constants.Config.BIND_OTHER_SERVICE_PCK, "");
                //需要绑定对方服务的全路径
                Constants.BIND_OTHER_SERVICE_CLASS = extras.getString(Constants.Config.BIND_OTHER_SERVICE_CLASS, "");
                //需要开启 Camera ID 的前置还是后置 0:后置 1:前置
                Constants.CAMERA_ID = extras.getInt(Constants.Config.CAMERA_ID, 0);
            }
        }
    复制代码
  3. 服务器是否开启相机,如果已经开启则不需要开启

    //是否摄像头
            if (mCamera == null)
                openCamera();
    复制代码
  4. 服务端初始化一块内存,用于写入 YUV 视频流。

    mMemoryFile = initMemoryFile(Constants.MEMORY_FILE_NAME, Constants.MEMORY_SIZE);
    复制代码
  5. 绑定对方服务,提供文件描述符号

    /**
         * 绑定对方服务,提供 文件描述符
         */
        private void bindOtherService() {
            try {
                if (TextUtils.isEmpty(Constants.BIND_OTHER_SERVICE_PCK) || TextUtils.isEmpty(Constants.BIND_OTHER_SERVICE_CLASS))
                    throw new NullPointerException("PCK or CLSS is null ?");
                Intent intent = new Intent();
                ComponentName cmp = new ComponentName(Constants.BIND_OTHER_SERVICE_PCK, Constants.BIND_OTHER_SERVICE_CLASS);
                intent.setComponent(cmp);
                context.bindService(intent, mCameraServiceConnection, Context.BIND_AUTO_CREATE);
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }
        }
    复制代码
  6. 绑定对方服务成功,交于文件描述符 ParcelFileDescriptor

    mCameraService = ICameraCoreService.Stub.asInterface(binder);
                if (mMemoryFile != null) {
                    try {
                        //反射拿到文件描述符号
                        mParcelFileDescriptor = MemoryFileHelper.getParcelFileDescriptor(mMemoryFile);
                        if (mParcelFileDescriptor != null) {
                            mCameraService.addExportMemoryFile(mParcelFileDescriptor, Constants.PREVIEWWIDTH, Constants.PREVIEWHEIGHT, Constants.MEMORY_SIZE);
    
                        }
    复制代码
  7. 发送数据,当标志位为 byte[0] == 0 代表服务端可将 YUV 写入内存, == 1 ,代表客服端可以读取可用的 YUV 数据。

    /**
         * 读标志位 写入视频流
         *
         * @param memoryFile
         */
        public void writeBytes(MemoryFile memoryFile) {
            try {
                if (mYUVQueue.size() > 0) {
                    BufferBean mBufferBean = new BufferBean(Constants.BUFFER_SIZE);
                    //读取标志符号
                    memoryFile.readBytes(mBufferBean.isCanRead, 0, 0, 1);
                    //当第一位为 0 的时候,代表客服端已经读取了,可以正常将视频流写入内存中
                    if (mBufferBean.isCanRead[0] == 0) {
                        //拿到视频流
                        byte[] video = mYUVQueue.poll();
                        if (video != null)
                            //将视频流写入内存中
                            memoryFile.writeBytes(video, 0, 0, video.length);
                        //标志位复位,等待客服端读取视频流
                        mBufferBean.isCanRead[0] = 1;
                        memoryFile.writeBytes(mBufferBean.isCanRead, 0, 0, 1);
                    } else {
                        Log.d(TAG, "readShareBufferMsg isCanRead:" + mBufferBean.isCanRead[0] + ";length:"
                                + mBufferBean.mBuffer.length);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                sendBroadcast(Constants.ACTION_FEEDBACK, e.getMessage());
            }
        }
    复制代码
  8. 开启成功或者失败等其他错误消息反馈给客服端

    //返回给客服端   
    public void sendBroadcast(String action,String content) {
            Intent intent = new Intent();
            intent.setAction(action);
            ComponentName componentName = new ComponentName("com.t01.sharevideostream",
                    "com.t01.sharevideostream.revices.FeedBackReceiver");
            intent.setComponent(componentName);
            Bundle extras = new Bundle();
            extras.putString(Constants.ACTION_FEEDBACK_CONTENT, content);
            intent.putExtras(extras);
            context.sendBroadcast(intent);
        }
    复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

HTML5与CSS3基础教程(第7版)

HTML5与CSS3基础教程(第7版)

[美] Elizabeth Castro、[美] Bruce Hyslop / 望以文 / 人民邮电出版社 / 2013-1 / 59.00元

代表下一代网页编写技术的HTML5,为网页提供布局和格式的CSS3,这两者构成了Web开发的基石,也是Web程序员和设计师必须熟练掌握的最基本技能。 本书是风靡全球的HTML和CSS最佳入门教程的最新版,上一版单单英文版的销量就超过100万册,被翻译为十多种语言,并长期雄踞亚马逊书店计算机图书排行榜榜首。 最新的第7版秉承前一版直观、透彻、全面、循序渐进的讲授特色,仍然采用独特的双栏图......一起来看看 《HTML5与CSS3基础教程(第7版)》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具