ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

相册视频转码MP4格式 iOS

2021-09-06 18:03:42  阅读:190  来源: 互联网

标签:nil 转码 NSLog iOS callBack MP4 asset && path


本地已转码时,直接上传;本地无转码时,先转码再上传

/// 视频处理通过本地沙盒文件路径判断此视频文件是否已经转码
/// @param asset 视频资源
/// @param callBack 回调
- (void)dealWithVidioAsset:(PHAsset *)asset
                  callBack:(void (^)(NSString *))callBack
{
    /// 转码操作
    PHImageManager *manager = [PHImageManager defaultManager];
    [manager requestAVAssetForVideo:asset
                          
                            options:nil
                      resultHandler:^(AVAsset * _Nullable aVsset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
        
        ///判断此视频是否已经转码
         NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingFormat:@"/VideoCacheData/%@.mp4",[((AVURLAsset*)aVsset).URL.path MD5String]];
        
         NSFileManager *fileManager = [NSFileManager defaultManager];
         BOOL isDirExist = [fileManager fileExistsAtPath:path];
        if (isDirExist) {
            // 已经转码成功 直接上传
            [self uploadMpa4WithUrl:[NSURL URLWithString:path] callBack:^(NSString *str) {
                if (callBack) {
                    callBack(str);
                }
            }];
            return;
        }
        [self convertMovToMp4FromAVURLAsset:(AVURLAsset*)aVsset andCompeleteHandler:^(NSURL *fileUrl) {
            if (!fileUrl) {
                [HUDManager hideHUDView];
                [self.view showMessageWithText:@"上传错误请重试!"];
                self.navigationItem.rightBarButtonItem.enabled = YES;

            }else
            {
                [self uploadMpa4WithUrl:fileUrl callBack:^(NSString *str) {
                    if (callBack) {
                        callBack(str);
                    }
                }];
            }
        }];
    }];
}

转码MP4

- (void)convertMovToMp4FromAVURLAsset:(AVURLAsset*)urlAsset andCompeleteHandler:(void(^)(NSURL *fileUrl))fileUrlHandler{

    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:urlAsset.URL options:nil];
    
    NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:avAsset];
    
    if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) {
       
        //  在Documents目录下创建一个名为FileData的文件夹
        NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:@"VideoCacheData"];
       
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL isDir = FALSE;
        BOOL isDirExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
        if(!(isDirExist && isDir)) {
            BOOL bCreateDir = [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
            if(!bCreateDir){
                NSLog(@"创建文件夹失败!%@",path);
            }
            NSLog(@"创建文件夹成功,文件路径%@",path);
        }
        /// 文件名为本地相册路径的Md5
        NSString *resultPath = [path stringByAppendingFormat:@"/%@.mp4",[urlAsset.URL.path MD5String]];
        NSLog(@"file path:%@",resultPath);
        
        NSLog(@"resultPath = %@",resultPath);
        
        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:avAsset
                                                                               presetName:AVAssetExportPresetMediumQuality];
        exportSession.outputURL = [NSURL fileURLWithPath:resultPath];
        exportSession.outputFileType = AVFileTypeMPEG4;
        exportSession.shouldOptimizeForNetworkUse = YES;
        exportSession.videoComposition = [self getVideoComposition:avAsset];  //修正某些播放器不识别视频Rotation的问题

        [exportSession exportAsynchronouslyWithCompletionHandler:^(void)
         {
            dispatch_async(dispatch_get_main_queue(), ^{
                switch (exportSession.status) {
                    case AVAssetExportSessionStatusUnknown:
                        NSLog(@"AVAssetExportSessionStatusUnknown");
                        fileUrlHandler(nil);
                        break;
                    case AVAssetExportSessionStatusWaiting:
                        NSLog(@"AVAssetExportSessionStatusWaiting");
                        fileUrlHandler(nil);
                        break;
                    case AVAssetExportSessionStatusExporting:
                        NSLog(@"AVAssetExportSessionStatusExporting");
                        fileUrlHandler(nil);
                        break;
                    case AVAssetExportSessionStatusCompleted:
                        NSLog(@"AVAssetExportSessionStatusCompleted");
                        fileUrlHandler(exportSession.outputURL);
                        break;
                    case AVAssetExportSessionStatusFailed:
                        NSLog(@"AVAssetExportSessionStatusFailed");
                        fileUrlHandler(nil);
                        break;
                        
                    case AVAssetExportSessionStatusCancelled:
                        NSLog(@"AVAssetExportSessionStatusCancelled");
                        fileUrlHandler(nil);
                        break;
                }
            });
         }];
    }
}

 

修正视频位置

/// 修正位置信息
- (AVMutableVideoComposition *)getVideoComposition:(AVAsset *)asset
{
    AVAssetTrack *videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    AVMutableComposition *composition = [AVMutableComposition composition];
    AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
    CGSize videoSize = videoTrack.naturalSize;
    BOOL isPortrait_ = [self isVideoPortrait:asset];
    if(isPortrait_) {
        videoSize = CGSizeMake(videoSize.height, videoSize.width);
    }
    composition.naturalSize     = videoSize;
    videoComposition.renderSize = videoSize;
    
    videoComposition.frameDuration = CMTimeMakeWithSeconds( 1 / videoTrack.nominalFrameRate, 600);
    AVMutableCompositionTrack *compositionVideoTrack;
    compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    [compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, asset.duration) ofTrack:videoTrack atTime:kCMTimeZero error:nil];
    AVMutableVideoCompositionLayerInstruction *layerInst;
    layerInst = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
    [layerInst setTransform:videoTrack.preferredTransform atTime:kCMTimeZero];
    AVMutableVideoCompositionInstruction *inst = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    inst.timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
    inst.layerInstructions = [NSArray arrayWithObject:layerInst];
    videoComposition.instructions = [NSArray arrayWithObject:inst];
    return videoComposition;
}

- (BOOL) isVideoPortrait:(AVAsset *)asset
{
    BOOL isPortrait = NO;
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    if([tracks    count] > 0) {
        AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
        
        CGAffineTransform t = videoTrack.preferredTransform;
        // Portrait
        if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0)
        {
            isPortrait = YES;
        }
        // PortraitUpsideDown
        if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0)  {
            
            isPortrait = YES;
        }
        // LandscapeRight
        if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0)
        {
            isPortrait = NO;
        }
        // LandscapeLeft
        if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0)
        {
            isPortrait = NO;
        }
    }
    return isPortrait;
}

 

标签:nil,转码,NSLog,iOS,callBack,MP4,asset,&&,path
来源: https://www.cnblogs.com/huangzs/p/15234902.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有