ios 摄像头第一次黑屏

2018-06-16 10:16:00 weixin_30922589 阅读数 346

 

iOS开发调用相机时出现黑屏的解决办法(原因:没有获取到相机权限)

在开发过程中调用系统相机,但是页面出现黑屏,原因是自己只进行了部分的相机权限的判断没有根据系统的版本判断,

 

 

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        
        AVAuthorizationStatus authStatus =  [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        
        if (authStatus == AVAuthorizationStatusDenied || authStatus == AVAuthorizationStatusRestricted)
        {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"打开相机权限" message:nil preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                if([[UIApplication sharedApplication] canOpenURL:url]) {
                    [[UIApplication sharedApplication] openURL:url];
                }
            }];
            UIAlertAction *canleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
            [alert addAction:okAction];
            [alert addAction:canleAction];
            [self presentViewController:alert animated:YES completion:nil];
            return;
           
        }
    }else{
        ALAuthorizationStatus author = [ALAssetsLibrary authorizationStatus];
        if (author == kCLAuthorizationStatusRestricted || author == kCLAuthorizationStatusDenied)
        {
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"打开相机权限" message:nil preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                if([[UIApplication sharedApplication] canOpenURL:url]) {
                    [[UIApplication sharedApplication] openURL:url];
                }
            }];
            UIAlertAction *canleAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
            [alert addAction:okAction];
            [alert addAction:canleAction];
            [self presentViewController:alert animated:YES completion:nil];
            return;
        }
    }

 

 

 

 

转载于:https://www.cnblogs.com/Rong-Shengcom/p/9189940.html

2017-06-21 11:02:16 Enjolras1024 阅读数 2490

最近使用GPUImage做实时视频滤镜, 发现保存下来的视频第一帧会黑屏, 在网上找解决办法, 加入[self.videoCamera addAudioInputsAndOutputs]可以解决录制的时候闪一下黑屏, 但是保存的视频还是会有问题, 最终在这里找到解决办法。

附手动导入GPUImage方法:

1. 把GPUImage.xcodeproj 拖到你的Xcode project
2. 在app的target依赖设置里面添加GPUImage作为Target Dependency
3. 在build phase的Link Binary With Libraries, 把libGPUImage.a加进来.
4. 添加下面这些framework:
CoreMedia
CoreVideo
OpenGLES
AVFoundation
QuartzCore
5. 头文件搜索路径: project's build settings, 把GPUImage的source和source下的iOS目录加到搜索路径里, 使用相对路径和递归.
6. 包含下面这个头文件:
#import "GPUImage.h"
7. target-build setting里面,other linker flags 里面添加   -fobjc-arc   -ObjC 这两项

2017-09-07 14:35:03 wkyseo 阅读数 12264

最近项目中需要使用video来代替有点复杂的动画(video循环自动播放),遇到了使用过程中的两个坑

ios端默认全屏解决办法

查阅资料说在在video标签加如下属性

<video webkit-playsinline="webkit-playsinline"></video>

无奈测试机是ios10,上面这段代码在iOS8,9下生效
因项目是react工匠,不支持除data-*之外的自定义属性,需在compentDidMount加如下代码

this.videoElement.setAttribute('webkit-playsinline', 'webkit-playsinline');// Fix fullscreen problem on IOS 8 and 9
this.videoElement.setAttribute('playsinline', 'playsinline'); // Fix fullscreen problem on IOS 10

如果项目基于cordova构建,还需在config.xml加如下属性

<preference name="AllowInlineMediaPlayback" value="true" />

对了,行内播放之后还解决了一个问题,可以在video视窗使用定位来增加遮罩等功能

video自动播放黑屏

最开始产品需求是视频加载自动播放并且循环,导致快速切换页面再加载视频经常黑屏很长一段时间才能播放

寻求解决思路:
一. 视频加载前使用loading,对video执行onCanPlay监听remove loading

//react 代码
canPlay() {
  this.mask.remove();
}

<div className="video-wrap">
   <div className="mask" ref={(node) =>{this.mask = node;}}>
     <div className="loading"><span></span><span></span><span></span></div>
   </div>
   <video autoPlay muted loop  poster={this.props.poster} ref={(node) =>{this.videoElement = node;}} onCanPlay={this.canPlay}>
     <source src={this.props.src}></source>
     Your browser does not support the video tag.
   </video>
</div>

问题:依然存在黑屏,换成onplay尝试无解

网上说是videoview在加载第二个视频时 默认会释放到第一个视频的资源再加载第二个视频的资源 这个比较耗内存 会出现短暂的黑屏,可通过Web Workers开启多线程操作资源的加载,未尝试,可作为思路

二. 更改需求^ ^
因自动循环播放体验不友好,后期改为手动播放,添加poster,preload='auto'遂可以解决

 playVideo() {
  this.videoElement.play();
  this.img.style.display = 'none';
}

videoEnded() {
  this.img.style.display = 'block';
}

<div className="video-wrap">
   <img className="play" src="./img/icon-video-play.png" alt="" ref={(node) =>{this.img=node;}} {...tapOrClick(this.playVideo)}/>
   <video preload="auto"  poster={this.props.poster} ref={(node) =>{this.videoElement = node;}} onEnded={this.videoEnded}>
     <source src={this.props.src}></source>
     Your browser does not support the video tag.
   </video>
</div>

题外话,查阅相关资料发现,autoplay确实存在不少坑,低版本的chrome for android 也不支持, google developers 建议autoplay和muted一起使用,参考资料:https://developers.google.com/web/updates/2016/07/autoplay

video.play()返回的是个promise,学到了……^_^,文章也解释了为什么移动端不太支持自动循环播放,会导致用户无意识下载很多资源。来源:https://developers.google.com/web/updates/2016/03/play-returns-promise

var playPromise = document.querySelector('video').play();

// In browsers that don’t yet support this functionality,
// playPromise won’t be defined.
if (playPromise !== undefined) {
  playPromise.then(function() {
    // Automatic playback started!
  }).catch(function(error) {
    // Automatic playback failed.
    // Show a UI element to let the user manually start playback.
  });
}

重点:相对于web端,还可以使用库video.js,相对于html5的video,video.js功能更全,兼容性更好,也支持循环播放功能。

2016-02-02 19:04:39 HDFQQ188816190 阅读数 25922

之前写一个相机,发现在有的手机上能够正常启动相机,而有的打开相机是黑屏。多处查询而未果,今天看到友盟微社区的代码,终于知道原因了。其实没有网上说的那么复杂,就是需要看一下在你手机的设置——隐私——相机中,本软件是不是允许访问相机,只要允许就可以正常打开。所以在写代码的时候要判断一下本程序是不是有访问相机的权限。代码如下:

注意:此方法只对ios7以上的系统有用,如果是在ios6的系统的话就直接崩溃了,况且ios6上也没有“设置--隐私--相机” 那一项

 

 

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {

                AVAuthorizationStatus authStatus =  [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
               
                if (authStatus == AVAuthorizationStatusDenied || authStatus == AVAuthorizationStatusRestricted)
                {
                    [[[UIAlertView alloc] initWithTitle:nil message:@"本应用无访问相机的权限,如需访问,可在设置中修改" delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil, nil] show];
                    return;
                }
            }else{
                ALAuthorizationStatus author = [ALAssetsLibrary authorizationStatus];
                if (author == kCLAuthorizationStatusRestricted || author == kCLAuthorizationStatusDenied)
                {
                    [[[UIAlertView alloc] initWithTitle:nil message:@"本应用无访问相机的权限,如需访问,可在设置中修改" delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil, nil] show];
                    return;
                }
            }
            
            if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
                UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
                imagePicker.sourceType =  UIImagePickerControllerSourceTypeCamera;
                imagePicker.delegate = self;
                imagePicker.allowsEditing = YES;
                [self presentViewController:imagePicker animated:YES completion:^{
                    
                }];
            }
 

-- NORMAL --
2020-05-26 00:17:55 qq_24692477 阅读数 77

总结两版人脸识别的心路历程。主要是开发中遇到的问题。

需求:实现pc端、webapp人脸拍照打卡的功能。

第一版,使用flash+JqueryFaceDetection.js 。

因为项目最初是http协议,使用getUserMedia需要 https 协议,所以pc端使用flash调摄像头。也没有要求真正的人脸识别,就用facedetection检测是否为人脸,但并不能保证是否为本人。

方案:使用jquery.webcam.min.js,调取摄像头拍照,使用facedetection检测照片中是否存在人脸。

pc端遇到的问题:

浏览器只能用IE、360浏览器兼容模式,极速模式。拍照的时候对于光线也有限制,经常拍出来识别不到人脸,需要多试几次。

webapp端遇到的问题:

使用input调摄像头拍照识别,图片需要压缩。

小部分安卓机型比如三星、小米会发生图片旋转的问题,ios拍照也会旋转。这里使用插件exifJs,网上有很多demo。

需要注意一个问题,旋转之后的照片,在输出到画布的时候,是按照图片原始尺寸输出的,像在ios上,一张图的尺寸可能到了4000*4000,所以页面会加载异常的慢,转的base64也会异常的大,往后台传输会卡。

这里的解决方案是在旋转方法里,控制img的尺寸不要超过限定的最大尺寸,我这里是400,并且输出到画布的时候注意写全宽高,否则输出图片为剪裁之后的部分。

 

 

第二版,使用trackingJs检测人脸+腾讯云对比。

为了更好的兼容性,网站升级https协议。

1.使用opencvjs做人脸检测+人脸对比。

https://docs.opencv.org/4.3.0/d5/d10/tutorial_js_root.html,指路opencvjs的官网。

https://blog.csdn.net/weixin_38361925/article/details/82528529,借鉴的这篇博客里的例子。

说一下遇到的问题。

  1. java后端套页面的时候,需要jdk版本在1.8以上。
  2. 涉及到的opencv.js 、utils.js 、xml文件需要在同一个目录下,否则会报错xml文件404。
  3. 一个严重的问题就是部分安卓机、ios,页面运行卡顿,我猜是因为xml文件太大了?加载的资源太大?所以卡顿。因为华为手机可以正常运行。但是最后没有去解决,能力有限,方案弃用。

2.使用trackingJs做人脸检测+腾讯云人脸对比。

领导终于看不下去了,要放过我这个小渣渣了,说要采用三方的人脸识别。比较了一下阿里云和腾讯云识别的方案,腾讯云相对省钱,2000+/年/100万次。这里我们只用腾讯云的人脸对比。

https://trackingjs.com/ trackingjs的官网。

网上的例子也有很多,可以多方参考。

引入tracking-min.js,根据需要引入face-min.js、eye-min.js、mouth-min.js。

使用getUserMedia调用摄像头,ios端需要使用mediaDevices.getUserMedia,这里可以多阅读mediaDevices.getUserMedia--MDN的文档,详细介绍了调用手机端前置摄像头,后置摄像头的问题 。

1、video.play() 可以开启摄像头,tracking.track('#video', tracker,{camera:true});也可以调用摄像头,提前加载tracker。去掉camera:true,否则会闪屏。

2、手机端使用canvas把video视频流输出的时候,注意画布的大小,宽高不要超过屏幕的宽高,

 var vm = $(window).width();

3、使用mediaDevices.getUserMedia在ios调用摄像头,需要系统版本11以上,只支持safari浏览器,

ios系统11会显示空白,因为浏览器没有开启摄像头的权限。

ios系统12会显示黑屏,ios系统13可以显示视频流但是一帧一帧的出现。

这些统统都是因为video需要加上playsinline属性 !

最后发一下最终的效果图。

 

手机端浏览器支持情况
型号 自带浏览器 qq浏览器 谷歌浏览器
华为p30/p40 pro
小米9/红米9 ×
三星s9
苹果7p × ×
oppo 未测试
荣耀 未测试

还是有bug的,小米手机有些型号qq浏览器也不能够调起摄像头,还在优化中。