H5+錄制視頻太大的壓縮方案:
一.項目使用h5+api開發的,錄制視頻的時候采用的是h5+api錄制,但是這不是重點,重點在於以下幾點
1.ios默認錄制的為mov格式,采用1280*720錄制十秒大概六十兆左右,這個大小是無法滿足上傳需求的。
2.Android錄制格式默認MP4,所以這就要求我們ios工程師要完成兩個工作,轉碼MP4,壓縮。
二.ios提供的有api用來轉碼和壓縮(也就是有限的幾個參數來調整視頻大小)
三.直接上代碼,因為網上有一些代碼是無法跑通的,或者是滿足不了壓縮需求的。
代碼:
/*生成uuid的一個方法,用來用做轉換后的文件名*/
- (NSString*) stringWithUUID {
CFUUIDRef uuidObj = CFUUIDCreate(nil);//create a new UUID
//get the string representation of the UUID
NSString *uuidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(nil, uuidObj));
return uuidString;
}
/*轉換方法(callBackParm是錄制好的視頻本地路徑)這個路徑大家如果是完全用原生來做就直接用就行了,我這里做了處理是因為,我們在h5+項目里面用到的路徑是相對路徑,交互到原生就會是一個別的路徑*/
-(void)transfer:(NSString *)callBackParm{
NSLog(@"%@",callBackParm);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *loaclPath = [NSString stringWithFormat:@"%@/%@", docDir, callBackParm ];
/*如果錄制是原生來做的就直接拿到路徑傳進來就行了*/
AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:loaclPath] options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality])
{
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
NSString *exportPath = [NSString stringWithFormat:@"%@/camera/%@.mp4",docDir,[self stringWithUUID]];
exportSession.outputURL = [NSURL fileURLWithPath:exportPath];
NSLog(@"%@", exportPath);
exportSession.outputFileType = AVFileTypeMPEG4;
// exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
switch ([exportSession status]) {
case AVAssetExportSessionStatusFailed:
NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"Export canceled");
break;
case AVAssetExportSessionStatusCompleted:
NSLog(@"轉換成功");
float second=[self getFileSize:exportPath];
NSString *stringFloat = [NSString stringWithFormat:@"%f",second];
NSFileManager *fileMgr = [NSFileManager defaultManager];
BOOL bRet = [fileMgr fileExistsAtPath:loaclPath];
if (bRet) {
NSError *err;
[fileMgr removeItemAtPath:loaclPath error:&err];
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"notfiy_of_native" object:exportPath];
break;
}
}];
}
}
/*這個方法用來測試我們壓縮過的視頻有多大*/
- (CGFloat) getFileSize:(NSString *)path
{
NSFileManager *fileManager = [[NSFileManager alloc] init];
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;
}
四.代碼解讀:
1.傳進來的是一個本地路徑,也就是你錄制好的路徑,上面已經有解釋了。
2.AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:avAsset presetName:AVAssetExportPresetMediumQuality];
這一句才是真正的調整視頻的大小,后面這個AVAssetExportPresetMediumQuality參數是最合適的一個大小,如果不符合大家的需要可以跳轉進去看看別的參數。
3.exportSession.outputFileType = AVFileTypeMPEG4;這個是將輸出文件的類型轉換成后綴為.mp4的文件,也就是轉成mp4。
4.錄制完成刪除轉換前的mov視頻(這是要做的,這些東西沒必要一直留着,因為很大,如果 有需要在上傳成功之后轉換后的mp4文件也要刪掉)
BOOL bRet = [fileMgr fileExistsAtPath:loaclPath];
if (bRet) {
NSError *err;
[fileMgr removeItemAtPath:loaclPath error:&err];
}
到這里就完結了這個壓縮和轉碼的過程,其實並沒有想象中那么高級和麻煩,因為是系統提供的api,所以我們可以控制的東西很少,如果大家覺得這個不太好,那就只能用ffmpeg了,(很麻煩的)。