美文网首页
iOS:GPUImage本地视频叠加

iOS:GPUImage本地视频叠加

作者: 豆浆油条cc | 来源:发表于2020-01-11 17:41 被阅读0次

之前看过一些视频APP,可以把多个视频嵌入到一个视频图层中,抽空研究了下,思路是使用GPUImage中的GPUImageTwoInputFilter滤镜,这个滤镜可以添加2个渲染轨道。

问题:使用2个GPUImageMovie作为输入源,但是改变外层图层的位置大小是一个问题,后续抽空研究。

最终的做出的效果图:


Untitled.gif

代码:

- (void)addFilter{
    NSURL *path1 = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp4"]];
    NSURL *path2 = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"2" ofType:@"mp4"]];
    
    AVAsset* inputAsset1 = [AVAsset assetWithURL:path1];
    AVAsset* inputAsset2 = [AVAsset assetWithURL:path2];
    
    NSString *outPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Movie.mp4"];//输出文件
    NSURL* outUrl = [NSURL fileURLWithPath:outPath];
    [[NSFileManager defaultManager] removeItemAtPath:outPath error:nil];
    
    //输入源1
    GPUImageMovie* imageMovie1 = [[GPUImageMovie alloc] initWithURL:path1];
    imageMovie1.shouldRepeat = NO;//循转播放
    imageMovie1.playAtActualSpeed = YES;//预览视频时的速度是否要保持真实的速度
    imageMovie1.runBenchmark = YES;//打印处理的frame
    
    //输入源2
    GPUImageMovie* imageMovie2 = [[GPUImageMovie alloc] initWithURL:path2];
    imageMovie2.shouldRepeat = NO;//循转播放
    imageMovie2.playAtActualSpeed = YES;//预览视频时的速度是否要保持真实的速度
    imageMovie2.runBenchmark = YES;//打印处理的frame
    
    
    //输出源
    self.movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:outUrl size:[self getVideoOutPutNaturalSizeWithAsset:inputAsset1]];
    self.movieWriter.transform = [self getVideoOrientationWithAsset:inputAsset1];
    self.movieWriter.encodingLiveVideo = NO;//视频是否循环播放
    self.movieWriter.shouldPassthroughAudio = YES;//是否使用源音源
    
    // 滤镜
    GPUImageDissolveBlendFilter * filter = [[GPUImageDissolveBlendFilter  alloc] init];
    filter.mix = 0.5;
        
    [filter addTarget:self.movieWriter];
    [imageMovie1 addTarget:filter];
    [imageMovie2 addTarget:filter];
    
    [self.movieWriter startRecording];
    [imageMovie1 startProcessing];
    [imageMovie2 startProcessing];

    __weak typeof(self) weakSelf = self;
    [self.movieWriter setCompletionBlock:^{
        __strong typeof(self) strongSelf = weakSelf;
        NSLog(@"合并完成");
        [filter removeTarget:strongSelf.movieWriter];
        [strongSelf.movieWriter finishRecording];
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            AVPlayerViewController *playerVc = [[AVPlayerViewController alloc]init];
            playerVc.player = [[AVPlayer alloc]initWithURL:outUrl];
            [playerVc.player play];
            [strongSelf presentViewController:playerVc animated:YES completion:nil];
        });
    }];
    
    [self.movieWriter setFailureBlock:^(NSError *error) {
        NSLog(@"合成失败:error = %@",error.description);
    }];
}

//获取视频旋转角度
- (CGAffineTransform)getVideoOrientationWithAsset:(AVAsset*)asset{
    
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
    return videoTrack.preferredTransform;
}
//获取视频分辨率
- (CGSize)getVideoOutPutNaturalSizeWithAsset:(AVAsset*)asset{
    
    NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
    AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
    CGFloat width = videoTrack.naturalSize.width;
    CGFloat height = videoTrack.naturalSize.height;
    
    CGSize size = CGSizeZero;
    CGAffineTransform videoTransform = videoTrack.preferredTransform;//矩阵旋转角度
    
    if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) {
        size = CGSizeMake(width, height);
    }
    if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) {
        size = CGSizeMake(width, height);
    }
    if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) {
        size = CGSizeMake(width, height);
    }
    if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) {
        size = CGSizeMake(height, width);
    }
    
    return size;
}

GitHub:
https://github.com/qw9685/GPUImage-addVideo

相关文章

  • iOS:GPUImage本地视频叠加

    之前看过一些视频APP,可以把多个视频嵌入到一个视频图层中,抽空研究了下,思路是使用GPUImage中的GPUIm...

  • iOS:AVFoundation本地视频叠加(画中画)

    之前使用GPUImage叠加本地视频,有很多坑,所以换了个思路,使用AVMutableVideoCompositi...

  • GPUImage源码分析与使用(一)

    GPUImage简介 GPUImage是链式编程,可以处理图片和视频,支持iOS和Mac。 GPUImage1.0...

  • iOS库之GPUImage

    iOS库之GPUImage GPUImageVideoCamera 相机视频输入源, GPUImageStillC...

  • iOS-GPUImage 本地视频添加滤镜

    本文内容: 1、播放本地视频,实时添加滤镜,修改不同的滤镜效果 2、给本地视频添加滤镜,然后保存有滤镜效果的视频到...

  • 美颜滤镜

    GPUImage GPUImage:是一个基于OpenGL ES 2.0图像和视频处理的开源iOS框架,提供各种各...

  • iOS视频特效资料

    该文档收集了视频特效的参考资料: 美颜滤镜篇 IOS使用GPUImage滤镜初级试水 GPUImage录像的一些备...

  • GPUImage简介

    GPUImage 概述 GPUImage是一个遵循BSD的iOS开源库,通过使用它可以为图片、实时视频和影片添加G...

  • GPUImage与CoreImage

    GPUImage 与 CoreImage 对比 GPUImage 最低支持iOS4.0,iOS5.0之后就支持自定...

  • iOS GPUImage blog收集

    iOS GPUImage blog收集 GPUImage详解(简书博客) GPUImage(五):五种类型输入源(...

网友评论

      本文标题:iOS:GPUImage本地视频叠加

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