在iOS中的视频上添加GIF水印

时间:2016-01-05 07:27:36

标签: ios video avfoundation calayer gif

我需要完成此功能:视频上有一个GIF叠加,希望将此视频和GIF合成到一个新视频。我使用以下代码,但结果只是没有GIF的视频:

- (void)applyVideoEffectsToComposition:(AVMutableVideoComposition *)composition size:(CGSize)size
{

    // - set up the parent layer
    CALayer *parentLayer = [CALayer layer];
    CALayer *videoLayer = [CALayer layer];
    parentLayer.frame = CGRectMake(0, 0, size.width, size.height);
    videoLayer.frame = CGRectMake(0, 0, size.width, size.height);
    [parentLayer addSublayer:videoLayer];

    size.width = 100;
    size.height = 100;

    // - set up the overlay
    CALayer *overlayLayer = [CALayer layer];
    overlayLayer.frame = CGRectMake(0, 100, size.width, size.height);

    NSURL *fileUrl = [[NSBundle mainBundle] URLForResource:@"jiafei" withExtension:@"gif"];
    [BBGifManager startGifAnimationWithURL:fileUrl inLayer:overlayLayer];

//    UIImage * image = [UIImage imageNamed:@"gifImage.gif"];
//    [overlayLayer setContents:(id)[image CGImage]];
//    [overlayLayer setMasksToBounds:YES];

    [parentLayer addSublayer:overlayLayer];

    // - apply magic
    composition.animationTool = [AVVideoCompositionCoreAnimationTool
                                 videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];

}

添加Gif水印

CALayer

添加+ (void)startGifAnimationWithURL:(NSURL *)url inLayer:(CALayer *)layer { CAKeyframeAnimation * animation = [self animationForGifWithURL:url]; [layer addAnimation:animation forKey:@"contents"]; } 动画

CAKeyFrameAnimation

创建+ (CAKeyframeAnimation *)animationForGifWithURL:(NSURL *)url { CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"]; NSMutableArray * frames = [NSMutableArray new]; NSMutableArray *delayTimes = [NSMutableArray new]; CGFloat totalTime = 0.0; CGFloat gifWidth; CGFloat gifHeight; CGImageSourceRef gifSource = CGImageSourceCreateWithURL((CFURLRef)url, NULL); // get frame count size_t frameCount = CGImageSourceGetCount(gifSource); for (size_t i = 0; i < frameCount; ++i) { // get each frame CGImageRef frame = CGImageSourceCreateImageAtIndex(gifSource, i, NULL); [frames addObject:(__bridge id)frame]; CGImageRelease(frame); // get gif info with each frame NSDictionary *dict = (NSDictionary*)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(gifSource, i, NULL)); NSLog(@"kCGImagePropertyGIFDictionary %@", [dict valueForKey:(NSString*)kCGImagePropertyGIFDictionary]); // get gif size gifWidth = [[dict valueForKey:(NSString*)kCGImagePropertyPixelWidth] floatValue]; gifHeight = [[dict valueForKey:(NSString*)kCGImagePropertyPixelHeight] floatValue]; // kCGImagePropertyGIFDictionary中kCGImagePropertyGIFDelayTime,kCGImagePropertyGIFUnclampedDelayTime值是一样的 NSDictionary *gifDict = [dict valueForKey:(NSString*)kCGImagePropertyGIFDictionary]; [delayTimes addObject:[gifDict valueForKey:(NSString*)kCGImagePropertyGIFDelayTime]]; totalTime = totalTime + [[gifDict valueForKey:(NSString*)kCGImagePropertyGIFDelayTime] floatValue]; CFRelease((__bridge CFTypeRef)(dict)); } if (gifSource) { CFRelease(gifSource); } NSMutableArray *times = [NSMutableArray arrayWithCapacity:3]; CGFloat currentTime = 0; NSInteger count = delayTimes.count; for (int i = 0; i < count; ++i) { [times addObject:[NSNumber numberWithFloat:(currentTime / totalTime)]]; currentTime += [[delayTimes objectAtIndex:i] floatValue]; } NSMutableArray *images = [NSMutableArray arrayWithCapacity:3]; for (int i = 0; i < count; ++i) { [images addObject:[frames objectAtIndex:i]]; } animation.keyTimes = times; animation.values = images; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; animation.duration = totalTime; animation.repeatCount = HUGE_VALF; return animation; }

   //For adding a marker in Google map
        MarkerOptions mp = new MarkerOptions();
        mp.position(new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude)));
        mp.snippet(strAddress);
        map.addMarker(mp);

        try {

            b = new LatLngBounds.Builder();

            if (MapDetailsList.list != null && MapDetailsList.list.size() > 0) {

                for (int i = 0; i < MapDetailsList.list.size(); i++) {

                    b.include(new LatLng(Double.parseDouble(MapDetailsList.list.get(i).getLatitude()),
                            Double.parseDouble(MapDetailsList.list.get(i).getLongitude())));

                }
                LatLngBounds bounds = b.build();

                DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
                int width = displayMetrics.widthPixels;
                int height = displayMetrics.heightPixels;

                // Change the padding as per needed
                CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width-200, height-200, 5);
                // map.setCenter(bounds.getCenter());

                map.animateCamera(cu);

            }

        } catch (Exception e) {

        }

2 个答案:

答案 0 :(得分:2)

您应该调整CoreAnimation的animation设置:

animation.beginTime = AVCoreAnimationBeginTimeAtZero;
animation.removedOnCompletion = NO;

答案 1 :(得分:0)

以防万一the example on swift3如何做同样的事情 - 将动画帧/图像插入到视频中(不完全是gif,而是图像阵列)。它使用AVAssetExportSession和AVMutableVideoComposition以及AVMutableVideoCompositionInstruction和CAKeyframeAnimation来动画帧。