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了,(很麻烦的)。