请教android webserviceservice ANR问题

全部项目分类
iPhone/iPad/iPod
GPUImage是个功能十分强大、又十分易用的图像处理库。提供各种各样的图像处理滤镜,并且支持照相机和摄像机的实时滤镜。GPUImage顾名思义,是基于GPU的图像加速,所以图像处理速度十分快,并且能够自定义图像滤镜。支持ARC。 []
{{ mentTime }}
5个月前发布&&
7个月前发布&&
3年前发布&&
2年前发布&&
0 评 / 368 阅
0 评 / 43 阅
0 评 / 44 阅
0 评 / 27 阅
0 评 / 7 阅
0 评 / 40 阅
发送私信给: 匿名
评论 GPUImage
还可以输入字
评论 GPUImageGPUImage - 简书
<div class="fixed-btn note-fixed-download" data-toggle="popover" data-placement="left" data-html="true" data-trigger="hover" data-content=''>
写了31350字,被149人关注,获得了130个喜欢
GPUImage的导入下载GPUImage,地址:
把GPUImage.xcodeproj 拖到你的Xcode project
在app的target依赖设置里面添加GPUImage.a作为Target Dependency
在build phase的Link Binary With Libraries, 把libGPUImage.a加进来.
添加下面这些系统framework:CoreMediaCoreVideoOpenGLESAVFoundationQuartzCore
头文件搜索路径: project's build settings, 把GPUImage的source和source下的iOS目录加到搜索路径里, 使用相对路径和递归.
包含下面这个头文件:#import "GPUImage.h"
target-build setting里面,other linker flags 里面添加
-fobjc-arc
-ObjC 这两项尊重原创: 我只是实践者!!!再最后一步老是提示找不到GPUImage.h,source加入的搜索路径没有问题,一直编译不了,原来路径后面需要设置recursive。如下图:
下午6.32.51.png
就是递归的方式搜索。
共125个滤镜, 分为四类Color adjustments:
31 filters, 颜色处理相关Image processing:
40 filters, 图像处理相关.Blending modes:
29 filters,
混合模式相关.Visual effects:
25 filters,
视觉效果相关.
开源框架GPUImage 的简单说明:
问题1:退出滤镜,内存居高不下,GPUImage使用的缓存需要自己释放,如调用:[[GPUImageContext sharedImageProcessingContext].framebufferCache purgeAllUnassignedFramebuffers];
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
· 214人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:AVFoundation和GPUImage初探
AVFoundation和GPUImage初探
最近在做视频相关的东西,然后熟悉了一下AVFoundation框架,以及强大的开源库GPUImage。在这里记录这个过程中遇到的一些问题,以及解决的方法。
AVFoundation简介
1.AVFoundation的一些基本概念
根据苹果的官方文档,AVFoundation是用来播放和创建实时的视听媒体数据的框架,同时提供Objective-C接口来操作这些视听数据,比如编辑,旋转,重编码。本文着重讲的是视频的录制和编辑和GPUImage的一些简单使用,其他的都是一笔带过。来看下苹果文档的一个框架图。
AVAsset,AVAssetTrack,AVComposition,AVVideoComposition,AVAudioMix,AVMutableAudioMixInputParameter,AVMutableVideoCompositionInstrution, AVMutableVideoCompositionLayerInstrution
简单的播放可以使用 MPMoviePlayerController 或者 MPMovieViewController 就行,简单的录 制可以直接使用 UIImagePickerController 。同样简单的声音播放直接使用 AVAudioPlayer ,简单的录制直接使用 AVAduioRecorder 。如果你想要有更多的操作,可使用各种复杂的方式来控制播放,比如在同一时刻为同一个 asset 的不同片段使用不同的分辨率渲染, playitem 来管理asset的呈现状态和方式, playitemtrack 管理 asset 中的轨道(track)状态。
在AVFoudation框架中最核心的类就是 AVAsset ,他是由一系列的媒体数据组成的,包括但不限于:时间、大小(size)、标题、字幕等。其中每一个单独的媒体数据称为轨道( track )。同样剪辑操作中, AVMutableComposition 是一个核心类。
这里又一个重要的东西就是CMTime,它是一个结构体,定义如下:
typedef struct
通常时间是等于value/timescale的,所以两个有相同时间的CMTime它们的timescale并不一定相同。关于更多CMTime的内容可以看
2.1视频的录制
这里用的是系统原生录制,关于录制通常用到的几个类就是 AVCaptureDevice 、 AVCaptureSession 、 AVCaptureDeviceInput 、 AVCaptureOutput ,同样,来看一张图。
一般来说,如果你想修改视频的相关信息,如拍摄地点等,可以拿到output的metadata来修改。大致代码如下:
NSMutableArray *array = [output.metadta mutableCopy];
AVMutableMetadataItem *item = [[AVMutableMetadataItem alloc] init];
item.keyspace = ...;
item.key = ...;
item.value = ...;
[array addObject:item];
output.metadata =
如果录制时候想要得到指定的视频size必须先指定分辨率,像这样
if ([session canSetSessionPreset:AVCaptureSessionPreset640x480]){
session.sessionPreset = AVCaptureSessionPreset640x480;
//设置失败
切换摄像头或其他输入源必须在 beginConfiguration 和 commitConfiguration 之间来处理,大致是这样
[session beginConfiguration];
//移除某个输入源
//再添加某个输入源
//再为新添加的输入源进行必要的相关设置
//...其他操作
[session commitConfiguration];
如果想对实时视频帧进行相关的渲染操作,通过 setSampleBufferDelegate:queue: 方法来为output设置代理,同时必须指定 queue ,代理方法将会在这些 queue 上面被调用。可以在自己的类里面实现 AVCaptureVideoDataOutput 的协议方法,通过实现 captureOutput:didOutputSampleBuffer:fromConnection: 来拿到视频的每一帧,默认情况下这些视频帧会被用最有效的格式来输出到output,当然也可以在拍摄之前就为output进行相关设置。
AVCaptureVideoDataOutput *videoDataOutput = [AVCaptureVideoDataOutput new];
NSDictionary *newSettings =@{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
videoDataOutput.videoSettings = newS
说了这么多,感觉很虚,还是直接上代码,将以上部分衔接起来
//自定义方法,小演示只添加了视频,没有添加声音,添加声音类似
- (void)yourCustomMethodName{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
if ([session canSetSessionPreset:AVCaptureSessionPreset640x480]){
session.sessionPreset = AVCaptureSessionPreset640x480;
//设置失败
AVCaptureDevice *device =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error =
AVCaptureDeviceInput *input =
[AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
// Handle the error appropriately.
if(session canAddInput:input){
[session addInput:input];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
if(session canAddOutput:output){
[session addOutput:output];
output.videoSettings =@{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
//设置帧率(FPS),每秒15帧
output.minFrameDuration = CMTimeMake(1, 15);
dispatch_queue_t queue = dispatch_queue_create("CustomQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue)
NSString *mediaType = AVMediaTypeV
//用来显示录制的实时画面
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
[self.view.layer addSublayer:captureVideoPreviewLayer];
//用户是否允许启用摄像头
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
if (granted)
//Granted access to mediaType
[self setDeviceAuthorized:YES];
[session startRunning];
//Not granted access to mediaType
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:@"AVCam!"
message:@"AVCam doesn't have permission to use Camera, please change privacy settings"
delegate:self
cancelButtonTitle:@"OK"
otherButtonTitles:nil] show];
[self setDeviceAuthorized:NO];
//协议方法,获取每一帧,将每一帧转换成图片,你也可以进行其他的渲染操作
- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
fromConnection:(AVCaptureConnection *)connection {
UIImage *image = imageFromSampleBuffer(sampleBuffer);
上面演示了如何取得每一帧实时画面,如果想要直接存成视频可使用 AVCaptureMovieFileOutput ,如下
AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
NSURL *fileURL = ...;
//存放位置
//指定代理
[aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:delete];
//也可以为其指定outputSettings
同样代理必须实现协议方法 captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error: , 当然还有其他各种具体的设置,如对焦、曝光、闪光灯以及白平衡等等均可以通过KVO来设置,每次设置前都加一个判断,是否支持指定模式,在这里不做详细叙述了,这里你可以看到
2.2视频的剪辑
视频的剪辑包括但不限于:裁剪、旋转(改变transform)、添加水印、添加字幕、合并等。关于剪辑,无非就是取出视频中的轨道(视频和音频),然后对轨道进行一系列的操作变可以得到各种想要的效果。首先我们先来看下面一张图
AVMutableComposition 是整个视频剪辑过程中的一个核心,下面着重讲解这个类。 AVMutableComposition 和 AVAsset 一样含有多个视/音频轨道,但是更重要的是,它可以将多个 AVAssetTrack 合并到一起,比如在视频合并时,可以直接将多段视频拼接到一个轨道( AVMutableCompositonTrcak ),音频也一样。通过借助 AVMutableVideoComposition 和 AVMutableAudioMix 来设置每一段的视/音频的属性,从而达到想要的视听效果,比如视频切换处的淡入淡出,声音的渐变,字幕等等。 关于上图的解释:首先通过将 asset 里面的轨道加载到 composition 的各轨道,然后通过 audioMix 和 videoComposition 对某个轨道进行对应操作,设置其相关属性。其中要用到的具体方法可以参见
其中图中1,2,3用到的方法为
[mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]
[AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:mutableCompositionAudioTrack];`
[AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:mutableCompositionVideoTrack]
关于视频的剪辑的代码可以参见苹果给出的官方
以及Raywendrich上的两篇文章
3.GPUImage
什么?!你没听说过GPUImage?!那你赶紧去看看它的
。GPUImage是一个基于OpenGL ES的一个强大的图像/视频处理库,封装好了各种滤镜同时也可以编写自定义的滤镜。至于他到底是如何强大,用了就知道。在这篇文章不是为了介绍它,而是列出一些我在使用过程中遇到的问题和解决方法。
3.1分段录制
在使用 GPUImageVideoCamera 来录制的时候,可能需要分段录制,在GPUImage给出的视频录制Demo中直接只是录制一次,然而有时候需求可能是要录制多次,如果此时按照Demo的方法每次录制都要创建一个movieWriter,这样子的话每次都会在重新创建movieWriter并将它设置为videoCamera的 audioEncodingTarget 时候,界面都会卡顿一下,这是什么原因呢?因为videoCamera默认是不录制声音的,而每次创建movieWriter的时候都用到了 movieWriter.hasAudioTrack = YES; ,吊用这个之后videoCamera会自动去添加声音输入源,准备一些数据,所以这个过程会导致界面卡顿一下?这该怎么办呢?如果你有进到videoCamera的头文件去看的话你会发现这么一个方法和它的注释
Add audio capture to the session. Adding inputs and outputs freezes the capture session momentarily, so you can use this method to add the audio inputs and outputs early, if you’re going to set the audioEncodingTarget later. Returns YES is the audio inputs and outputs were added, or NO if they had already been added.
–(BOOL)addAudioInputsAndO
注释的大意是:录制的时候添加声音,添加输入源和输出源会暂时会使录制暂时卡住,所以在要使用声音的情况下要先调用该方法来防止录制被卡住。这不刚好就解决了上面的这个问题吗?所以问题就迎刃而解了,因为没看到这个,走了不少弯路,浪费了好长时间。
关于分段录制,可能有这么一个需求就是所有片段都是存于一个文件中而不是录制完成后将各段合并到一个视频文件中。这两个东西或许会帮到你
。前者是基于系统的分段录制的实现,后者是 GPUImageMoiveWriter 的一个子类。
3.2所见即所得
在录制的时候,使用 GPUImageView 来显示,因为给 GPUImageView 设置的大小是320*320的,如果不设置它的填充模式( fillMode )它是默认使用 kGPUImageFillModePreserveAspectRatio 即保持长宽比,其余空白处使用背景色填充,如果要设置成方形就得使用 kGPUImageFillModePreserveAspectRatioAndFill ,但是这个时候问题又来了假设你是用的录制分辨率是960x540,显示的画面则只会显示中间的540x540的画面,这个时候如果movieWriter的size设置为540x540,则最后保存的视频是失真的因为960被压到了540,整个画面变扁了。这个时候有两种解决方案
1.使用 GPUImageCropFilter ,通过设置其 cropRegion 来裁出中间540x540部分。关于 cropRegion 要注意它是一个 CGRect ,它对坐标系做了一个归一化处理,所以让所有的取值都在0.0~1.0范围内,比如960x540裁剪至中间540x540部分则 cropRegion 为 (0,((960-540)/2)/960,1,540/960)
2.改变videoComposition的perferTransfom使其只显示中间的540x540。 这样就完成了所见即所得。
关于GPUImage的实时滤镜添加或给已存在的视频添加滤镜,Demo都给出了详细过程,依葫芦画瓢即可。有一点要注意的是,在一些操作完成的时候注意 removeTarget ,还有就是在使用 movieFile 来播放已存在视频并添加滤镜的时候是没有声音的,这是这个库的一个缺陷,Github上有人提了这个
。同时在用 movieFile 处理视频的时候在切换滤镜的时候最好先 cancelProcessing 不然会有黑屏或卡顿现象出现。同样如果你是用老版本的GPUImage的时候,可能会遇到第一帧是红色的现象,有人提出这个issue后,作者修复了这个bug,切换到最新版的时候就不会有这种情况发生。发生这种情况的原因是视频掉帧,导致音频和视频不同步。
AVFoundation还是有很多东西去做深层次的挖掘,GPUImage也是一样,有了这个强大的库,解决一些事情节省了大量时间。这次仅仅是一个小小的尝试,对于很多东西都是浅尝则止,文中难免会有错误,欢迎在评论中指正。如果你在使用GPUImage和AVFoundation有什么好的心得或者对一些问题有相应的解决方案,不妨在评论中分享一下。
发表评论:
TA的最新馆藏}

我要回帖

更多关于 android startservice 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信