最近在學(xué)習(xí)使用iOS自帶的API進(jìn)行視頻壓縮,所以就從視頻拍攝開始學(xué)起,因?yàn)樵?jīng)想直接對(duì)已有視頻進(jìn)行壓縮,無奈總是失敗,經(jīng)研究發(fā)現(xiàn)不可以直接調(diào)用PC中的視頻文件進(jìn)行壓縮,否則直接AVAssetExportSessionStatusFailed。所以只可以用真機(jī)測試并調(diào)用不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格式都有哪些,共有兩個(gè)分別是@"public.image",@"public.movie"
ipc.mediaTypes = [NSArray arrayWithObject:availableMedia[1]];//設(shè)置媒體類型為public.movie
[self presentViewController:ipc animated:YES completion:nil];
ipc.videoMaximumDuration = 30.0f;//30秒
ipc.delegate = self;//設(shè)置委托
[ipc release];
}
關(guān)于上面提到的ipc.sourceType的三種取值,camera指的是調(diào)用相機(jī)進(jìn)行拍攝,而photoLibrary指的是手機(jī)中的所有圖片,photoAlbum指的是單純指的是相冊(cè)中的圖片。其余的不做過多解釋。
然后在如下委托方法中進(jìn)行拍攝完畢的一些處理
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
sourceURL = [[info objectForKey:UIImagePickerControllerMediaURL] retain];
fileLenLabel.text = [NSString stringWithFormat:@"%f s", [self getVideoLength:sourceURL]];//這個(gè)url為什么可以呢,因?yàn)檫@里必須這樣
fileSizeLabel.text = [NSString stringWithFormat:@"%f kb", [self getFileSize:[[sourceURL absoluteString] substringFromIndex:16]]];//文件并沒有存儲(chǔ)在sourceURL所指的地方,因?yàn)檫@里自己加上了所以要將這段字符串去掉,這個(gè)Label是測試時(shí)工程中用到的顯示所拍攝文件大小的標(biāo)簽
NSLog([[sourceURL absoluteString] substringFromIndex:16]);
[self dismissViewControllerAnimated:YES completion:nil];
}
好了,到這里就已經(jīng)將拍攝好的視頻存儲(chǔ)在了sourceURL中。下面進(jìn)行壓縮處理
- (IBAction)convert:(id)sender
{//轉(zhuǎn)換時(shí)文件不能已存在,否則出錯(cuò)
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];//用時(shí)間給文件全名,以免重復(fù),在測試的時(shí)候其實(shí)可以判斷文件是否存在若存在,則刪除,重新生成文件即可
[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];
}];
}
}
做幾點(diǎn)說明,在視頻拍攝的時(shí)候有個(gè)參數(shù)是來設(shè)置拍攝質(zhì)量的,三種取值UIImagePickerControllerQualityTypeHigh,Medium,Low,但是經(jīng)過測試發(fā)現(xiàn)這三個(gè)參數(shù)對(duì)拍攝效果并無多大影響,壓縮的時(shí)候也有一個(gè)參數(shù)三個(gè)取值(針對(duì)iPhone的只有三個(gè),還有針對(duì)其它設(shè)備的不同分辨率如640*480等,但是他們并不適用于iPhone,還有一些針對(duì)PC的)這三個(gè)取值分別是AVAssetExportPresetMediumQuality,Highest,Low,其中Highest與Medium自我感覺并多大差異,清晰度相當(dāng),壓縮后的文件大小也幾乎一樣,但是Low要小的多,一分中的視頻如果用Medium(或Highest)大小是5M多點(diǎn),如果是Low則為600KB左右,但是Low要相對(duì)模糊許多。一般選取Medium即可。
這里再對(duì)如何獲取文件的大小以及視頻的時(shí)長做一點(diǎn)小解釋
- (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;
}此方法可以獲取視頻文件的時(shí)長。
|