美文网首页
将视频剪切成正方形

将视频剪切成正方形

作者: Scott丶Wang | 来源:发表于2017-08-13 22:02 被阅读244次

由于项目需要,需要将录制好的全屏视频剪切成长宽均为设备宽度的正方形。本来以为很简单只需要改变录制时分辨率即可,可惜发现苹果提供的几种分辨率均不能满足需求,所以必须自己一点点查询资料、尝试完成需求,功夫不负有心,终于解决了问题,这里讲遇到的坑分享给大家。

过程大致分为三步:
首先,先配置好录制视频的基础
其次,在设备输出代理方法中处理视频
最后,保存视频(具体怎么处理看情况定吧!)

第一、三步省略,直接说第二步。
这里用到主要的类以及相关库:AVFoundation

AVAsset:素材库里的素材; 
AVAssetTrack:素材的轨道; 
AVMutableComposition :一个用来合成视频的“合成器”; 
AVMutableCompositionTrack :“合成器”中的对媒体轨道,有音频轨、视频轨等,里面可以插入各种对应的素材; 
AVMutableVideoCompositionLayerInstruction:视频轨道中的一个视频,可以缩放、旋转等; 
AVMutableVideoCompositionInstruction:一个视频轨道,包含了这个轨道上的所有视频素材; 
AVMutableVideoComposition:管理所有视频轨道,可以决定最终视频的尺寸,裁剪需要在这里进行; 
AVAssetExportSession:配置渲染参数并渲染。

AVAsset

根据官方文档中对它的描述大致上可以把它理解成:某定时长视频资源信息数据模型,包括时长、音频轨道、视频轨道、文本、字幕等信息。
注:基于这是一个定时长视频资源本质,即使我们成功初始化AVAsset或其子类实例,我们也不可能立刻拿到我们想要的信息。原因是AVAsset是同步返回信息的,为了用户体验良好避免阻塞,我们可以在子线程获取信息,但是更推荐大家的是在使用过程中注册监听自己感兴趣的属性值变化来获取信息。

AVPlayerItem
管理着视频资源播放状态、以及可以被KVO监测的属性,错误信息等,注意的是一般情况下,监听和接受监听执行的代码在主线程上。

- (void)croppedVideo:(NSURL*)videoUrl{
    // 1 — 源视频地址
    AVAsset *videoAsset = [AVAsset assetWithURL:videoUrl];
    
    // 2 - 创建AVMutableComposition实例.
    AVMutableComposition *mixComposition = [AVMutableComposition composition];
    
    // 3 - 视频、音频通道
    AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
    AVMutableCompositionTrack *audioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
    
    AVAssetTrack *videoAssetTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
    AVAssetTrack *audioAssertTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
    
    // 3.0 这块是裁剪,这里必须插入音频数据,否则没有声音
    [videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [videoAsset duration])
                        ofTrack:videoAssetTrack
                         atTime:kCMTimeZero
                          error:nil];
    [audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, [videoAsset duration])
                        ofTrack:audioAssertTrack
                         atTime:kCMTimeZero
                          error:nil];
    
    // 3.1 AVMutableVideoCompositionInstruction 视频轨道中的一个视频,可以缩放、旋转等
    AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration);
    
    // 3.2 AVMutableVideoCompositionLayerInstruction 一个视频轨道,包含了这个轨道上的所有视频素材
    AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
    BOOL isVideoAssetPortrait_ = NO;
    CGAffineTransform videoTransform = videoAssetTrack.preferredTransform;
    if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) {
        isVideoAssetPortrait_ = YES;
    }
    if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) {
        isVideoAssetPortrait_ = YES;
    }
    [videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero];
    [videolayerInstruction setOpacity:0.0 atTime:videoAsset.duration];
    
    // 3.3 - Add instructions
    mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil];
    // AVMutableVideoComposition:管理所有视频轨道,可以决定最终视频的尺寸,裁剪需要在这里进行
    AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
    CGSize naturalSize;
    if(isVideoAssetPortrait_){
        naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width);
    } else {
        naturalSize = videoAssetTrack.naturalSize;
    }
    float renderWidth, renderHeight;
    renderWidth = naturalSize.width;
    renderHeight = naturalSize.height;
    float value = renderWidth>renderHeight?renderHeight:renderWidth;
    mainCompositionInst.renderSize = CGSizeMake(value, value);
    mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
    mainCompositionInst.frameDuration = CMTimeMake(1, 30);
    
    // 4 - Get path
    AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
    [[NSFileManager defaultManager] removeItemAtPath:JYTempDataPathWithComponent(kCroppedVideoName) error:nil];
    exporter.outputURL = [NSURL fileURLWithPath:JYTempDataPathWithComponent(kCroppedVideoName)];
    exporter.outputFileType = AVFileTypeMPEG4;
    exporter.shouldOptimizeForNetworkUse = YES;
    exporter.videoComposition = mainCompositionInst;
    
    [exporter exportAsynchronouslyWithCompletionHandler:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            if (exporter.status == AVAssetExportSessionStatusCompleted) {
                _outputFileUrl = [exporter.outputURL copy];
                if (self.videoCompletionBlock) {
                    self.videoCompletionBlock();
                    self.videoCompletionBlock = nil;
                }
            }
        });
    }];
}

忽略的第一部在这里附上可供参考的链接
第一步:录制视频 "星谱"的一边文章 链接

相关文章

  • 将视频剪切成正方形

    由于项目需要,需要将录制好的全屏视频剪切成长宽均为设备宽度的正方形。本来以为很简单只需要改变录制时分辨率即可,可惜...

  • 客家猪肉汤,简单好做特好吃!

    瘦猪肉切成一块一块,切成正方形/长方形都行,切成正方形是为了美观! Tip1:最好使用不要太肥的肉。 猪肉切好之后...

  • 【思维训练】认识图形

    题目: 下面的图形剪两剪刀,可以拼成一个正方形。想一想,怎么剪? 题目(1) 题目(2) 解答: 要拼成一个正方形...

  • 剪窗花

    今天晚上我在家里剪窗花,我先拿出一张正方形得纸,然后叠成三角形,又折了一下。然后我就开始剪,先剪了正方形,又剪三角...

  • 应用题

    【必会题】1.把边长是12厘米的正方形蛋糕切成大小相等的9个小正方形。小正方形蛋糕的周长是多少厘米?【不考虑蛋糕的...

  • 剪辑视频学会这五个软件就够了!

    剪视频用哪个软件好?剪视频难不难,学不会怎么办?有没有剪视频的大神,帮我剪一下…… 其实剪视频根本就不难,剪视频要...

  • iOS开发 - 化圆为方(将圆形图片切成正方形)

    需求:将一张圆形的图片切出中间最大的正方形(说白了就是),使用勾股定理得出:高h = image.size.hei...

  • 把正方形图片切成圆形图片

    _TitleimageView.layer.masksToBounds = YES; //设置圆角;当值为正方形图...

  • 路路通耳枕

    闲暇之余找块花布剪出十二片小的正方形在对角向内剪去小圆孤,每片小正方形只对角剪一次噢。在剪中间的小长方形对折两边向...

  • 剪视频

    NSArray *compatiblePresets = [AVAssetExportSession export...

网友评论

      本文标题:将视频剪切成正方形

      本文链接:https://www.haomeiwen.com/subject/ovshrxtx.html