GPUImage实现摄像头暂停
GPUImage相信很多开发者都用过,其本身也是十分简单易用,因此对于GPUImage的基本用法不再赘述。
最近在使用GPUImage时要实现摄像时暂停和继续的功能,但GPUImage本身并没有提供相关的接口。查看GPUImageVideoCamera 中的相关代码,可以发现
- (void)pauseCameraCapture;方法。但这个方法会令GPUImage显示的摄像头捕捉的画面也暂停,这显然不是一个好的方案。
但- (void)pauseCameraCapture;这个方法却能给我们带来解决问题的思路。查看GPUImage源代码:
- (void)pauseCameraCapture;
{
capturePaused = YES;
}
在这里只是简单地设置了一个暂停的标志。那这个标志在什么地方用到呢。继续看代码:
- (void)processVideoSampleBuffer:(CMSampleBufferRef)sampleBuffer;
{
if (capturePaused)
{
return;
}
.....
}
在处理视频帧的地方,如果暂停了就直接返回,用这种方法来实现暂停。
显然我们可以采用类似的方法来处理,但是首先我们要找到在哪里处理。如果使用过GPUImageVideoCamera,大致都会知道视频帧的流向。
如图,首先是GPUImageVideoCamera获取视频帧,将其传给filter,然后filter再将视频帧传给GPUImageView和
。前者用来显示摄像头捕捉到的图像,后者用来保存视频。

我们要实现暂停(显示的图像不暂停)显然只能在GPUImageMovieWriter这个环节来实现了。
继续看代码,找到GPUImageMovieWriter这个类中处理视频帧的的方法。
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
要怎么改写看个人具体情况了,可以直接修改,继承或者用category。本人采用的是继承的方式。
增加个标志,暂停就直接返回,否则调用父类的方法处理。看起来好像没问题,写个demo测试一下,发现视频暂停后,到继续的那段时间里不是直接跳过,而是
一直显示暂停时的那一帧图像。这是因为视频帧是带有时间戳的,虽然丢弃了暂停时的视频帧,但是时间戳还是原来的值,所以就出现了这种奇怪的情况。
继续修改时间戳:
- (void)configure{
_timeOffset = CMTimeMake(0, 1);
_isDisCount = NO;
_isPause = NO;
_isAudioOn = YES;
_offSet = kCMTimeZero;
}
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex{
if (_isPause) {
return;
}
if (_isDisCount) {
_isDisCount = NO;
_offSet = CMTimeSubtract(frameTime, _last);
if (_offSet.value > 0) {
_timeOffset = CMTimeAdd(_timeOffset, _offSet);
}
}
_last = frameTime;
frameTime = CMTimeSubtract(frameTime, _timeOffset);
[super newFrameReadyAtTime:frameTime atIndex:textureIndex];
}
改完再测试一下,暂停和恢复摄像正常了,没有什么问题。但是,视频末尾出现了有一小段时间播放最后一帧的情况,这是什么问题。
如果你录音声音正常的话就可以听到最后一段视频卡住了,但音频还是正常播放的。这是因为,我们只处理了图像帧,而没有处理音频
的缘故。
找到相关的方法,简单地return一下就好了。
- (void)processAudioBuffer:(CMSampleBufferRef)audioBuffer
{
if (_isPause) {
return;
}
[super processAudioBuffer:audioBuffer];
}
大概是GPUImageMovieWriter中处理了,音频会被按照顺序直接连接在一起,修改时间没用。
所以,如果想实现音频暂停(按照时间播放,中间有一段没声音)的话会比较麻烦。一种是可以记录暂停时间,在录音完之后进行剪辑。
另一种可以插入空的音频帧(没试过)。
GPUImage实现摄像头暂停的更多相关文章
- Vuforia unity开发摄像头问题
Vuforia unity开发摄像头问题 项目一直在赶进度,写博的时间越来越少了~从事Unity开发也快两个月了,AR方向~ 使用的是高通家的SDK Vuforia...从工程融合一直到对unity和 ...
- 基于GPUImage的实时美颜滤镜
1.背景 前段时间由于项目需求,做了一个基于GPUImage的实时美颜滤镜.现在各种各样的直播.视频App层出不穷,美颜滤镜的需求也越来越多.为了回馈开源,现在我把它放到了GitHub https:/ ...
- Android 自带 camera 详解
在本文中 需要考虑的问题 概述 Manifest声明 使用内置的摄像头应用程序 捕获图像的intent 捕获视频的intent 接收摄像头intent的结果 创建摄像头应用程序 检测摄像头硬件 访问摄 ...
- vuforia 中摄像机的开启与关闭
本文主要讲解的是Unity对Vuforia的开发中在原生调用摄像头上遇到的坑~Unity中调用设备摄像头打开或则关闭,或则开关扫描识别问题等等一些情况~ 下面先说说趟过的坑,再说说解决办法,或则目前没 ...
- (17)Python读取摄像头并实现视频播放、暂停、指定目录保存、回放功能
读取摄像头并播放.暂停功能 import sys #import scipy.io as sio from PyQt5 import QtGui, QtCore, QtWidgets #from wy ...
- GPUimage实时滤镜的实现
GPUIMAGE中GPUImageStillCamera可以调用系统相机,并实现实时滤镜,但是我没有找到相机全屏的方法,望知道的说一下 GPUImageStillCamera继承自GPUImageVi ...
- iOS:GPUImage强大的图像处理框架
GPUImage是一个非常棒的图像处理的开源库,里面提供了非常非常多的滤镜效果来加工图像. 不过就是因为太多效果了,而且对于程序员来说,那么多效果并不清楚知道要用那一个.于是我就使用提供的默认值,加上 ...
- TVideoGrabber的使用(一)捕捉摄像头
使用TVideoGrabber捕捉摄像头,相当容易,只需几句代码即可解决问题,首先我们新建一个工程,然后从控件面板上拉取一个 TVideoGrabber控件到窗体中,然后再在窗体上放置四个Button ...
- Android中直播视频技术探究之---采集摄像头Camera视频源数据进行推流(采用金山云SDK)
一.前言 在之前已经详细介绍了Android中的一种视频数据源:Camera,不了解的同学可以点击进入:Android中Camera使用详解 ,在这篇文章中我们介绍了如何采集摄像头的每一帧数据,然后进 ...
随机推荐
- 信号量 semaphore 和 @synchronized 的运用
1. //创建全局队列 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); //创建信号量 dispatch_semaphore_t s ...
- this其实是js的一个对象谁调用它它就指向谁
本人看了一下,感觉对this解释的有点复杂了,因此,本人在此给this一个简单易于理解的定义. 因为上面计算出来的结果不符合我们的习惯,并且负值在计算的时候会影响正确性,现在我们给这个结果加上180 ...
- 时间戳 JavaScript parse() 方法 处理技巧
返回1970/01/01至2012/3/21之间的毫秒数: var d = Date.parse("March 21, 2012"); d 输出结果: 1332259200000 ...
- golang下的grpc
facebook的thrift也是开源rpc库,性能高出grpc一倍以上,grpc发展的较晚,期待以后有长足的进步.简单来说thrift = grpc + protobuf gRPC基于HTTP/2标 ...
- java1234教程系列笔记 S1 Java SE chapter 02 写乘法口诀表
一.水仙花数 1.方式一:这是我的思路,取各个位数的方式.我个人习惯于使用取模运算. public static List<Integer> dealNarcissiticNumberMe ...
- 警告:隐式声明与内建函数'exit'不兼容解决方案
警告:隐式声明与内建函数'exit'不兼容解决方案 #include <stdio.h> int main() { printf("hello world!/n"); ...
- Verilog HDL那些事_建模篇笔记(实验八:键盘解码)
1.PS2接口与协议时序图 对于PS2的接口来说,需要额外关注的是PIN5与PIN1,一个是时钟,一个是数据.PS2协议对数据的移位是“CLOCK下降沿”有效,其CLOCK的频率通常在10KHz左右. ...
- [2015.02.02]文本编码转换专家 v2.6
软件名称:文本编码转换专家最新版本:v2.6操作系统:XP/2003/Win7/Win2008软件介绍:文本编码转换专家,界面简洁易用,功能强大实用.自动识别文件编码,有效转换成目标编码.真正的多线程 ...
- 【java】之3种方式实现Object和Map之间的转换
利用commons.BeanUtils实现Obj和Map之间转换,这种是最简单,也是最经常用的 public static Object mapToObject(Map<String, Obje ...
- 线程优先级抢占实验【RT-Thread学习笔记 3】
同时处于就绪状态的线程,优先级高的先执行. 高优先级就绪时,低优先级任务让出CPU,让高优先级任务先执行. 创建两个任务函数: //线程优先级抢占 void thread1_entry(void *p ...