最近,在做有关视频操作的功能。需要从相册选择视频,处理之后再保存到相册。
选择视频:
方式一:用系统的UIImagePickerController
贴代码:
-
- (void)selectAction{
-
-
NSLog(@"从相册选择");
-
UIImagePickerController *picker=[[UIImagePickerController alloc] init];
-
-
picker.delegate=self;
-
picker.allowsEditing=NO;
-
picker.videoMaximumDuration = 1.0;//视频最长长度
-
picker.videoQuality = UIImagePickerControllerQualityTypeMedium;//视频质量
-
-
//媒体类型:@"public.movie" 为视频 @"public.image" 为图片
-
//这里只选择展示视频
-
picker.mediaTypes = [NSArray arrayWithObjects:@"public.movie", nil];
-
-
picker.sourceType= UIImagePickerControllerSourceTypeSavedPhotosAlbum;
-
-
[kCurNavController presentViewController:picker animated:YES completion:^{
-
-
}];
-
-
}
-
-
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
-
-
NSString *mediaType=[info objectForKey:UIImagePickerControllerMediaType];
-
-
if ([mediaType isEqualToString:@"public.movie"]){
-
//如果是视频
-
NSURL *url = info[UIImagePickerControllerMediaURL];//获得视频的URL
-
NSLog(@"url %@",url);
-
self.videoUrl = url;
-
}
-
-
[self dismissViewControllerAnimated:YES completion:nil];
-
}
选择视频:
方式二:利用三方库TZImagePickerController
贴代码:
-
- (void)selectThreeKuAction{
-
-
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 columnNumber:4 delegate:nil pushPhotoPickerVc:YES];
-
-
//展示相册中的视频
-
imagePickerVc.allowPickingVideo = YES;
-
//不展示图片
-
imagePickerVc.allowPickingImage = NO;
-
//不显示原图选项
-
imagePickerVc.allowPickingOriginalPhoto = NO;
-
//按时间排序
-
imagePickerVc.sortAscendingByModificationDate = YES;
-
-
//选择完视频之后的回调
-
[imagePickerVc setDidFinishPickingVideoHandle:^(UIImage *coverImage,id asset){
-
-
//iOS8以后返回PHAsset
-
PHAsset *phAsset = asset;
-
-
if (phAsset.mediaType == PHAssetMediaTypeVideo) {
-
//从PHAsset获取相册中视频的url
-
PHVideoRequestOptions *options = [[PHVideoRequestOptions alloc] init];
-
options.version = PHImageRequestOptionsVersionCurrent;
-
options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
-
PHImageManager *manager = [PHImageManager defaultManager];
-
[manager requestAVAssetForVideo:phAsset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
-
AVURLAsset *urlAsset = (AVURLAsset *)asset;
-
-
NSURL *url = urlAsset.URL;
-
self.videoUrl = url;
-
NSLog(@"%@",url);
-
}];
-
}
-
}];
-
[kCurNavController presentViewController:imagePickerVc animated:YES completion:nil];
-
}
以上都得到了视频的URL,之后再操作就方便了。
裁剪视频:
-
//视频裁剪
-
- (void)cropWithVideoUrlStr:(NSURL *)videoUrl start:(CGFloat)startTime end:(CGFloat)endTime completion:(void (^)(NSURL *outputURL, Float64 videoDuration, BOOL isSuccess))completionHandle
-
{
-
AVURLAsset *asset =[[AVURLAsset alloc] initWithURL:videoUrl options:nil];
-
-
//获取视频总时长
-
Float64 duration = CMTimeGetSeconds(asset.duration);
-
-
NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dafei.mp4"];
-
NSURL *outputURL = [NSURL fileURLWithPath:outputPath];
-
-
//如果文件已经存在,先移除,否则会报无法存储的错误
-
NSFileManager *manager = [NSFileManager defaultManager];
-
[manager removeItemAtPath:outputPath error:nil];
-
-
NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset];
-
if ([compatiblePresets containsObject:AVAssetExportPresetMediumQuality])
-
{
-
-
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
-
initWithAsset:asset presetName:AVAssetExportPresetPassthrough];
-
-
exportSession.outputURL = outputURL;
-
//视频文件的类型
-
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
-
//输出文件是否网络优化
-
exportSession.shouldOptimizeForNetworkUse = YES;
-
-
//要截取的开始时间
-
CMTime start = CMTimeMakeWithSeconds(startTime, asset.duration.timescale);
-
//要截取的总时长
-
CMTime duration = CMTimeMakeWithSeconds(endTime - startTime,asset.duration.timescale);
-
CMTimeRange range = CMTimeRangeMake(start, duration);
-
exportSession.timeRange = range;
-
-
[exportSession exportAsynchronouslyWithCompletionHandler:^{
-
switch ([exportSession status]) {
-
case AVAssetExportSessionStatusFailed:
-
{
-
NSLog(@"合成失败:%@", [[exportSession error] description]);
-
completionHandle(outputURL, endTime, NO);
-
}
-
break;
-
case AVAssetExportSessionStatusCancelled:
-
{
-
completionHandle(outputURL, endTime, NO);
-
}
-
break;
-
case AVAssetExportSessionStatusCompleted:
-
{
-
//成功
-
completionHandle(outputURL, endTime, YES);
-
-
}
-
break;
-
default:
-
{
-
completionHandle(outputURL, endTime, NO);
-
} break;
-
}
-
}];
-
}
-
}
处理完视频之后,把视频保存到相册:
方式一:
-
//保存视频到相册
-
- (void)writeVideoToPhotoLibrary:(NSURL *)url
-
{
-
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
-
-
[library writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error){
-
if (error == nil) {
-
-
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存成功" preferredStyle:UIAlertControllerStyleAlert];
-
-
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
-
-
}]];
-
[self presentViewController:alert animated:true completion:nil];
-
-
}else{
-
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存失败" preferredStyle:UIAlertControllerStyleAlert];
-
-
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
-
-
}]];
-
[self presentViewController:alert animated:true completion:nil];
-
}
-
}];
-
}
UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
-
// 视频保存回调
-
- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo: (void *)contextInfo {
-
-
if (error == nil) {
-
-
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存成功" preferredStyle:UIAlertControllerStyleAlert];
-
-
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
-
-
}]];
-
[self presentViewController:alert animated:true completion:nil];
-
-
}else{
-
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"视频保存失败" preferredStyle:UIAlertControllerStyleAlert];
-
-
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
-
-
}]];
-
[self presentViewController:alert animated:true completion:nil];
-
}
-