视频压缩
最近遇到一个头疼的问题,录制高清视频,上传服务器,但是太大,上传缓慢,经过几天的周折,最后实现了6:1的压缩率,如果您有更好的办法请联系我。
#import "ViewController.h"
#import<AssetsLibrary/AssetsLibrary.h>
#import<AVKit/AVKit.h>
#import<AVFoundation/Foundation.h>
@interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>
@end
@implementation ViewController{
UIImagePickerController *imagePickerController;
}
- (void)viewDidLoad { [super viewDidLoad];}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event{
[self showImagePickerForSourceType:UIImagePickerControllerSourceTypeCamera andCameraCaptureMode:UIImagePickerControllerCameraCaptureModeVideo];
}
- (void)showImagePickerForSourceType:(UIImagePickerControllerSourceType)sourceType andCameraCaptureMode:(UIImagePickerControllerCameraCaptureMode)mode{ imagePickerController = [[UIImagePickerController alloc] init]; //这是 VC 的各种 modal 形式 imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen; imagePickerController.sourceType = sourceType; //支持的摄制类型,拍照或摄影,此处将本设备支持的所有类型全部获取,并且同时赋值给imagePickerController的话,则可左右切换摄制模式 imagePickerController.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera]; imagePickerController.delegate = self; imagePickerController.videoQuality = UIImagePickerControllerQualityTypeIFrame960x540; //允许拍照后编辑 imagePickerController.allowsEditing = YES;
if (sourceType == UIImagePickerControllerSourceTypeCamera) { //设置模式-->拍照/摄像 imagePickerController.cameraCaptureMode = mode; //开启默认摄像头-->前置/后置 imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear; //设置默认的闪光灯模式-->开/关/自动 imagePickerController.cameraFlashMode = UIImagePickerControllerCameraFlashModeAuto;
}
[self presentViewController:imagePickerController animated:YES completion:NULL];
}
#pragma mark delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary*)info{
NSString *mediaType = info[UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:@"public.image"]) {
NSLog(@"image...");
/*
//获取照片的原图
UIImage* original = [info objectForKey:UIImagePickerControllerOriginalImage];
//获取图片裁剪后,剩下的图
UIImage* crop = [info objectForKey:UIImagePickerControllerCropRect];
//获取图片的url
NSURL* url = [info objectForKey:UIImagePickerControllerMediaURL];
//获取图片的metadata数据信息
NSDictionary* metadata = [info objectForKey:UIImagePickerControllerMediaMetadata];
*/
//获取图片裁剪的图
UIImage* edit = [info objectForKey:UIImagePickerControllerEditedImage];
[self saveImage:edit];
}else{ // public.movie
NSLog(@"video...");
NSURL *url=[info objectForKey:UIImagePickerControllerMediaURL];//视频路径
// NSString *urlStr=[url path];
//
NSLog(@"开始压缩,压缩前大小 %f MB",[self fileSize:url]);
AVURLAsset *avAsset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
if ([compatiblePresets containsObject:AVAssetExportPresetHighestQuality]) {
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset presetName:AVAssetExportPresetHighestQuality];
exportSession.outputURL = [self compressedURL];
//优化网络
exportSession.shouldOptimizeForNetworkUse = true;
//转换后的格式
exportSession.outputFileType = AVFileTypeMPEG4;
//异步导出
[exportSession exportAsynchronouslyWithCompletionHandler:^{
// 如果导出的状态为完成
NSLog(@"%@",exportSession);
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSLog(@"压缩完毕,压缩后大小 %f MB",[self fileSize:[self compressedURL]]);
[self saveVideo:[self compressedURL]];
}else{
NSLog(@"当前压缩进度:%f",exportSession.progress);
}
}];
}
// [self saveVideo:url];
}
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
NSLog(@"取消");
[picker dismissViewControllerAnimated:YES completion:nil];
}
//取消屏幕旋转
- (BOOL)shouldAutorotate {
return YES;
}
#pragma mark save
- (void)saveImage:(UIImage *)img
{
// //如果是拍照的照片,则需要手动保存到本地,系统不会自动保存拍照成功后的照片
// UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
[[[ALAssetsLibrary alloc]init] writeImageToSavedPhotosAlbum:[img CGImage] orientation:(ALAssetOrientation)img.imageOrientation completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"Save image fail:%@",error);
}else{
NSLog(@"Save image succeed.");
}
}];
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
if (error) {
NSLog(@"保存照片过程中发生错误,错误信息:%@",error.localizedDescription);
}else{
NSLog(@"照片保存成功.");
}
}
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
NSLog(@"----%@",contextInfo);
if (error) {
NSLog(@"保存视频过程中发生错误,错误信息:%@",error.localizedDescription);
}else{
NSLog(@"视频保存成功.");
}
}
#pragma mark 保存压缩
- (NSURL *)compressedURL
{
return [NSURL fileURLWithPath:[[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true) lastObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"cgq.mp4"]]];
}
- (CGFloat)fileSize:(NSURL *)path
{
return [[NSData dataWithContentsOfURL:path] length]/1024.00 /1024.00;
}
- (void)saveVideo:(NSURL *)outputFileURL
{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL
completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"保存视频失败:%@",error);
} else {
NSLog(@"保存视频到相册成功");
}
}];
}
@end