zoukankan      html  css  js  c++  java
  • 相册视频转码MP4格式 iOS

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

    /// 视频处理通过本地沙盒文件路径判断此视频文件是否已经转码
    /// @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;
    }
    在北京的灯中,有一盏是我家的。这个梦何时可以实现?哪怕微微亮。北京就像魔鬼训练营,有能力的留,没能力的走……
  • 相关阅读:
    第三波精品Android源码袭来!免费下载
    推荐!Html5精品效果源码分享
    又来一波!Android精品源码分享
    Android精品资源汇总,10个源码(持续更新)
    Android开发者学习必备:10个优质的源码供大家学习
    专访方立勋:开发者应该保持好奇和热情
    将博客搬至CSDN
    GIT修改commit信息
    使用FormData上传文件
    Spring MVC @PathVariable with dot (.) is getting truncated
  • 原文地址:https://www.cnblogs.com/huangzs/p/15234902.html
Copyright © 2011-2022 走看看