【踩坑日记】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 ...
随机推荐
- CMake构建学习笔记8-OpenSceneGraph库的构建
1. 概论 在连续构建了zlib.libpng.libjpeg.libtiff.giflib以及freetype这几个库之后,接下来我们就要来一个大的,构建OpenSceneGraph这样大型库.Op ...
- tar 解压文件时提示 Ignoring unknown extended header keyword
在 Linux 上使用 tar 解压文件时出现下列提示: tar: Ignoring unknown extended header keyword 'LIBARCHIVE.xattr.com.app ...
- devops-3:Jenkins增加静态节点
Jenkins管理静态节点 Jenkins搭建完成后一般只有一个master节点,此节点主要用于管理Jenkins配置,如果再在master节点上跑一系列的Job,未免有点太勉强,并且如果出现资源紧缺 ...
- Instant exceeds minimum or maximum instant
使用 Instant.now().plusSeconds("xxxxx")报错 Instant exceeds minimum or maximum instant原因是取值范围 ...
- OpenFeign深入学习笔记
OpenFeign 是一个声明式的 Web 服务客户端,它使得编写 Web 服务客户端变得更加容易.OpenFeign 是在 Spring Cloud 生态系统中的一个组件,它整合了 Ribbon(客 ...
- python 或者 pyspark 和 java 交互, pyspark 里怎么调用自定义的 jar 包
1. python 直接访问 jar 里面的类 先定义java文件,然后要访问java class, 需要有gateway server 和 entrypoint, 到时候python就可以连接上ga ...
- JavaScript Library – PhotoSwipe
效果 前言 以前用过 lightbox2 和 fancyapps. lightbox2 已经没有维护了. fancyapps 改版好多次了. v2, v3 现在 v4 已经开始收费了. PhotoSw ...
- 火山引擎数智平台:高性能ChatBI的技术解读和落地实践
导读:大模型能力的发展和成熟,催生出新一代智能化 BI-- ChatBI,即通过自然语言处理(NLP)与大型语言模型(LLMs)的结合,极大简化数据分析过程,提高效率并降低分析门槛.火山引擎数智平台旗 ...
- MyBatis——案例——查询-查询所有
查询-查询所有数据 1.创建相应Mapper接口文件 以及Mapper配置信息文件 修改配置文件中 namespace : 2.编写接 ...
- codeforces 1931E
题目链接 简介:对一些数字,余念安可以反转一个数字,齐夏将两个数字首尾相连变为一个数字.每个人都采取最优策略. 名单上只剩下一个号码.如果该整数不小于 10的m次方 ,则齐夏获胜.否则余念安就赢了. ...