iOS视频拍摄与压缩

来源:互联网 发布:gm预测软件2008下载 编辑:程序博客网 时间:2024/04/29 06:25

最近在学习使用iOS自带的API进行视频压缩,所以就从视频拍摄开始学起,因为曾经想直接对已有视频进行压缩,无奈总是失败,经研究发现不可以直接调用PC中的视频文件进行压缩,否则直接AVAssetExportSessionStatusFailed。所以只可以用真机测试并调用不iPhone中的视频。废话不多说,上代码:

使用UIImagePickerController即可完成视频的拍摄,并存入自定义的目录中

方法如下

- (IBAction)start:(id)sender
{
    UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
    ipc.sourceType = UIImagePickerControllerSourceTypeCamera;//sourcetype有三种分别是camera,photoLibrary和photoAlbum
    NSArray *availableMedia = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];//Camera所支持的Media格式都有哪些,共有两个分别是@"public.image",@"public.movie"
    ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//设置媒体类型为public.movie
    [self presentViewController:ipc animated:YES completion:nil];
    ipc.videoMaximumDuration = 30.0f;//30秒
    ipc.delegate = self;//设置委托
    [ipc release];
}

关于上面提到的ipc.sourceType的三种取值,camera指的是调用相机进行拍摄,而photoLibrary指的是手机中的所有图片,photoAlbum指的是单纯指的是相册中的图片。其余的不做过多解释。

然后在如下委托方法中进行拍摄完毕的一些处理

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    sourceURL = [[info objectForKey:UIImagePickerControllerMediaURL] retain];
    
    fileLenLabel.text = [NSString stringWithFormat:@"%f s", [self getVideoLength:sourceURL]];//这个url为什么可以呢,因为这里必须这样
    fileSizeLabel.text = [NSString stringWithFormat:@"%f kb", [self getFileSize:[[sourceURL absoluteString] substringFromIndex:16]]];//文件并没有存储在sourceURL所指的地方,因为这里自己加上了所以要将这段字符串去掉,这个Label是测试时工程中用到的显示所拍摄文件大小的标签
    NSLog([[sourceURL absoluteString] substringFromIndex:16]);
    [self dismissViewControllerAnimated:YES completion:nil];
}

好了,到这里就已经将拍摄好的视频存储在了sourceURL中。下面进行压缩处理

- (IBAction)convert:(id)sender
{//转换时文件不能已存在,否则出错
    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:sourceURL options:nil];
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    if ([compatiblePresets containsObject:resultQuality]) {
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:resultQuality];
        NSDateFormatter *formater = [[NSDateFormatter alloc] init];//用时间给文件全名,以免重复,在测试的时候其实可以判断文件是否存在若存在,则删除,重新生成文件即可
        [formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
        resultPath = [[NSHomeDirectory() stringByAppendingFormat:@"/Documents/output-%@.mp4", [formater stringFromDate:[NSDate date]]] retain];
        NSLog(resultPath);
        [formater release];
        exportSession.outputURL = [NSURL fileURLWithPath:resultPath];
        exportSession.outputFileType = AVFileTypeMPEG4;
        [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
        {
            switch (exportSession.status) {
                case AVAssetExportSessionStatusUnknown:
                    NSLog(@"AVAssetExportSessionStatusUnknown");
                    break;
                case AVAssetExportSessionStatusWaiting:
                    NSLog(@"AVAssetExportSessionStatusWaiting");
                    break;
                case AVAssetExportSessionStatusExporting:
                    NSLog(@"AVAssetExportSessionStatusExporting");
                    break;
                case AVAssetExportSessionStatusCompleted:
                    NSLog(@"AVAssetExportSessionStatusCompleted");

                    break;
                case AVAssetExportSessionStatusFailed:
                    NSLog(@"AVAssetExportSessionStatusFailed");
                    break;
            }
            [exportSession release];
        }];
    }
}

做几点说明,在视频拍摄的时候有个参数是来设置拍摄质量的,三种取值UIImagePickerControllerQualityTypeHigh,Medium,Low,但是经过测试发现这三个参数对拍摄效果并无多大影响,压缩的时候也有一个参数三个取值(针对iPhone的只有三个,还有针对其它设备的不同分辨率如640*480等,但是他们并不适用于iPhone,还有一些针对PC的)这三个取值分别是AVAssetExportPresetMediumQuality,Highest,Low,其中Highest与Medium自我感觉并多大差异,清晰度相当,压缩后的文件大小也几乎一样,但是Low要小的多,一分中的视频如果用Medium(或Highest)大小是5M多点,如果是Low则为600KB左右,但是Low要相对模糊许多。一般选取Medium即可。

这里再对如何获取文件的大小以及视频的时长做一点小解释

- (CGFloat) getFileSize:(NSString *)path
{
    NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease];
    float filesize = -1.0;
    if ([fileManager fileExistsAtPath:path]) {
        NSDictionary *fileDic = [fileManager attributesOfItemAtPath:path error:nil];//获取文件的属性
        unsigned long long size = [[fileDic objectForKey:NSFileSize] longLongValue];
        filesize = 1.0*size/1024;
    }
    return filesize;
}此方法可以获取文件的大小,返回的是单位是KB。

- (CGFloat) getVideoLength:(NSURL *)URL
{
    NSDictionary *opts = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
                                                     forKey:AVURLAssetPreferPreciseDurationAndTimingKey];
    AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:URL options:opts];
    float second = 0;
    second = urlAsset.duration.value/urlAsset.duration.timescale;
    return second;
}此方法可以获取视频文件的时长。

0 0