【踩坑日记】uni-app相机抽帧,相机被多次初始化问题
缘起:最近频繁接到使用我们
AI运行识别插件
用户的反馈,部分机型在uni
中抽几帧后,就不再帧的了。开始以为又是小程序的API兼容的问题(确有机型出现过抽帧兼容性问题),后面越来越多的反馈在原生下无问题,只有采用uni-app
方案的有问题...
一、先看抽帧简略代码
下面是小程序做AI运动识别的第一步,摄像头帧数据采集的精简代码版段,大致流程是:在摄像头初始化完成后,初始化一个CameraFrameListener
、进行抽帧,并根据抽取的帧图像大小,调整Camera
组件大小与帧图大小同比缩放(宽全为全屏、高自适应)。
为什么要同比缩放的原因,请见我们的系列分享:【一步步开发AI运动小程序】四、小程序如何抽帧
<template>
<view class="container">
<camera id="preview" class="preview" :style="videoStyles" flash="off" :device-position="deviceKey"
resolution="high" frame-size="low" @initdone="onCameraReady">
</camera>
</view>
</template>
<script>
export default {
data() {
return {
deviceKey: "back",
previewWidth: 480,
previewHeight: 640,
previewRate: 1,
frameWidth: 480,
frameHeight: 640
};
},
computed: {
videoStyles() {
const style = `width:${this.previewWidth}px;height:${this.previewHeight}px;`;
return style;
}
},
methods: {
autoFitPreview(width, height) {
const sifno = uni.getSystemInfoSync();
let rate = sifno.windowWidth / width;
this.previewWidth = width * rate;
this.previewHeight = height * rate;
this.previewRate = rate;
this.frameWidth = width;
this.frameHeight = height;
},
initCamera(){
//防止重初始化
if(this.listener)
return;
const that = this;
const context = wx.createCameraContext();
const listener = context.onCameraFrame((frame) => {
//当帧图像大小发生变化时,重新调整摄像头代码
if(that.frameWidth != frame.width)
that.autoFitPreview(frame.width, frame.height);
console.log(frame.data instanceof ArrayBuffer, frame.width, frame.height)
});
listener.start();
},
onCameraReady(e) {
this.autoFitPreview(480, 640);
this.initCamera();
},
onStart(){
this.listener.start();
},
onStop(){
this.listener.stop();
}
}
}
</script>
二、BUG复现
在确认原生小程序抽帧无问题后,我们偿试了问题复现,经过多次测试,发现在uni
下,Camera
组件会多次触发initdone
事件,进一步测试后发现,只要动态改变camera
的style高、宽,便会触发重新初始化。
initCamera(){
//这里的防初始化,便是引发抽帧断流的原因,因为相机重新初始化了,所以listener实际已经无法再监听帧流了,必须重新创建
if(this.listener)
return;
const that = this;
const context = wx.createCameraContext();
const listener = context.onCameraFrame((frame) => {
//当帧图像大小发生变化时,重新调整摄像头代码
//此处的重新适应,便导致了相机的重初始化
if(that.frameWidth != frame.width)
that.autoFitPreview(frame.width, frame.height);
console.log(frame.data instanceof ArrayBuffer, frame.width, frame.height)
});
listener.start();
}
三、问题修复
找出问题原因,修复便很简单了,去除相应的防CameraFrameListener
重新始化锁,只要触发initdone
便重新初始化,并同步初始化其它逻辑。同时也要注意尽量将camera大小一次绑定到位,减少动态绑定的次数。
四、问题总结
虽然uni-app
大部分场景都与原生无异,但是受限于vue的值绑定和节点渲染机制,在实际使用中还是有细微的差别的,特别是原生组件。
另外,针对此问题,我们已经更新了我们的
AI运动识别小程序插件
的uni
版本Demo,请各用户联系我们索取。
【踩坑日记】uni-app相机抽帧,相机被多次初始化问题的更多相关文章
- AI相关 TensorFlow -卷积神经网络 踩坑日记之一
上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是g ...
- 人工智能(AI)库TensorFlow 踩坑日记之一
上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是g ...
- hexo博客谷歌百度收录踩坑日记
title: hexo博客谷歌百度收录踩坑日记 toc: false date: 2018-04-17 00:09:38 百度收录文件验证 无论怎么把渲染关掉或者render_skip都说我的格式错误 ...
- Hexo搭建静态博客踩坑日记(二)
前言 Hexo搭建静态博客踩坑日记(一), 我们说到利用Hexo快速搭建静态博客. 这节我们就来说一下主题的问题与主题的基本修改操作. 起步 chrome github hexo git node.j ...
- Hexo搭建静态博客踩坑日记(一)
前言 博客折腾一次就好, 找一个适合自己的博客平台, 专注于内容进行提升. 方式一: 自己买服务器, 域名, 写前端, 后端(前后分离最折腾, 不分离还好一点)... 方式二: 利用Hexo, Hug ...
- 人工智能(AI)库TensorFlow 踩坑日记之二
上次 踩坑日志之一 遗留的问题终于解决了,所以作者(也就是我)终于有脸出来写第二篇了. 首先还是贴上 卷积算法的示例代码地址 :https://github.com/tensorflow/models ...
- JavaScript 新手的踩坑日记
引语 在1995年5月,Eich 大神在10天内就写出了第一个脚本语言的版本,JavaScript 的第一个代号是 Mocha,Marc Andreesen 起的这个名字.由于商标问题以及很多产品已经 ...
- React Native踩坑日记 —— tailwind-rn
项目背景 在项目的初始阶段,我们需要建立自己的design system,我们spike了一些方案,tailwind-rn就是其中一种,如果有用到或者即将用到tailwind-rn的,可以进来看一看, ...
- React Native Android配置部署踩坑日记
万事开头难 作为一只进入ECMAScript世界不久的菜鸟,已经被React Native的名气惊到了,开源一周数万星勾起了我浓烈的兴趣.新年新气象,来个HellWorld压压惊吧^_^(故意少打个' ...
- 微信小程序开发踩坑日记
2017.12.29 踩坑记录 引用图片名称不要使用中文,尽量使用中文命名,IDE中图片显示无异样,手机上图片可能出现不显示的情况. 2018.1.5 踩坑记录 微信小程序设置元素满屏,横向直接w ...
随机推荐
- Ubuntu 设置远程桌面(RDP)
安装桌面环境 如果你的 Ubuntu 还没有安装桌面环境,可以选择以下之一安装: GNOME GNOME 是 Ubuntu Desktop 原生桌面环境. # 安装基本的 GNOME 桌面环境 sud ...
- Windows SSH 免密登陆远程计算机
上传公钥 如果远程计算机是类 Unix 系统,使用下面这条命令: Get-Content $Env:USERPROFILE\.ssh\id_rsa.pub | ssh USER@HOST " ...
- 将.gradle下的 带hash名称文件夹中的依赖 转换为 .m2上的依赖
背景: android studio 在无法下载依赖的情况下 , 仅 使用 mavenLocal() 本地 .gradle 下有对应依赖 , .m2下没有 故将.gradle下的 带hash名称文件 ...
- 【YashanDB知识库】开源调度框架Quartz写入Boolean值到YashanDB报错
问题现象 Quartz 是一个广泛应用于企业级应用中的开源作业调度框架,它主要用于在Java环境中管理和执行任务. 为了任务调度,Quartz的数据模型中使用了大量的布尔值记录任务.流程的各种状态,如 ...
- 同步多个mysql 到一个
了解大概 Ref: is it possible that canal set with multiple mysql database source 使用 canal https://dev.mys ...
- C++ : 仅添加一个引用& 就直接导致程序崩溃
问题描述 在项目某次开发中,测试过程中出现了coredump问题.经过asan工具检测,报了heap-use-after-free内存错误,最终定位到竟是无意中添加了一个引用&导致的! 开发时 ...
- 超轻量级、支持插件的 .NET 网络通信框架
前言 给大家推荐一个轻量级的.支持插件的综合网络通信库:TouchSocket. TouchSocket 的基础通信功能包括 TCP.UDP.SSL.RPC 和 HTTP.其中,HTTP 服务器支持 ...
- JavaScript中class的静态属性和静态方法
我们可以把一个方法赋值给类的函数本身,而不是赋给它的 "prototype" .这样的方法被称为 静态的(static). 例如这样: class Animal { static ...
- vue单元测试
0.测试钩子函数 describe的钩子函数 在测试块describe中,存在这四个钩子函数,他会在describe执行的不同时期调用: before():在该区块的所有测试用例之前执行 after( ...
- VMware安装CentOS7及远程登录详细教程
写在前面 主要使用软件: VMware Workstation Pro17 Navicat Premium17 Xshell7 Xftp7 1.在虚拟机安装CentOS7 访问阿里云镜像站 ,选择标记 ...