How to add animation on image change while create video using images
Asked Answered
B

0

13

I have an array of images from which I want to create a video by playing these images one after the other in a sequence.I want to add a different types of animation when image get change. Suggest me some method or any solution to achieve this functionality in Objective-C with the Cocoa framework.

Here is working code for making video of images, But please suggest that how we animate images while making video:

-(void)createVideoFromImages:(NSString *) path withSize:(CGSize) size
{
    NSError *error = nil;

    AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:
                                  [NSURL fileURLWithPath:path] fileType:AVFileTypeMPEG4
                                                              error:&error];
    NSParameterAssert(videoWriter);

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                   AVVideoCodecH264, AVVideoCodecKey,
                                   [NSNumber numberWithInt:size.width], AVVideoWidthKey,
                                   [NSNumber numberWithInt:size.height], AVVideoHeightKey,
                                   nil];


    AVAssetWriterInput* videoWriterInput = [AVAssetWriterInput
                                            assetWriterInputWithMediaType:AVMediaTypeVideo
                                            outputSettings:videoSettings];

    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
                                                     assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput
                                                     sourcePixelBufferAttributes:nil];

    NSParameterAssert(videoWriterInput);

    NSParameterAssert([videoWriter canAddInput:videoWriterInput]);
    videoWriterInput.expectsMediaDataInRealTime = YES;
    [videoWriter addInput:videoWriterInput];
    //Start a session:
    [videoWriter startWriting];
    [videoWriter startSessionAtSourceTime:kCMTimeZero];

    //Video encoding
    CVPixelBufferRef buffer = NULL;

    //convert uiimage to CGImage.
    int frameCount = 0;

    for(int i = 0; i<[arrPicture count]; i++)
    {
        buffer = [self bufferImageFromCGImage:[[arrPicture objectAtIndex:i] CGImage] size:size];

        __block  BOOL append_ok = NO;
        int j = 0;
        while (!append_ok && j < 30)
        {
            if (adaptor.assetWriterInput.readyForMoreMediaData)
            {
                printf("appending %d attemp %d\n", frameCount, j);

                CMTime frameTime = CMTimeMake(frameCount,(int32_t)1);
                append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];

                // CVPixelBufferPoolRef bufferPool = adaptor.pixelBufferPool;
                // NSParameterAssert(bufferPool != NULL);
                [NSThread sleepForTimeInterval:0.05];

            }
            else
            {
                printf("adaptor not ready %d, %d\n", frameCount, j);
                [NSThread sleepForTimeInterval:0.1];
            }
            j++;
        }
        if (!append_ok)
        {
            printf("error appending image %d times %d\n", frameCount, j);
        }
        frameCount++;
        CVBufferRelease(buffer);
    }

    [videoWriterInput markAsFinished];
    [videoWriter finishWritingWithCompletionHandler:^{
        NSLog(@"Finished writing...checking completion status...");
        if (videoWriter.status != AVAssetWriterStatusFailed && videoWriter.status == AVAssetWriterStatusCompleted)
        {
            NSLog(@"Video writing succeeded.");

            // Move video to camera roll
            // NOTE: You cannot write directly to the camera roll.
            // You must first write to an iOS directory then move it!
            NSURL *videoTempURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@", path]];
        } else
        {
            NSLog(@"Video writing failed: %@", videoWriter.error);
        }
    }];
}


-(CVPixelBufferRef) bufferImageFromCGImage:(CGImageRef)image size:(CGSize)size
{
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                             [NSNumber numberWithBool:YES],     kCVPixelBufferCGImageCompatibilityKey,
                             [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey,
                             nil];
    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width,
                                          size.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options,
                                          &pxbuffer);
    status=status;//Added to make the stupid compiler not show a stupid warning.
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL);

    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
    NSParameterAssert(pxdata != NULL);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, size.width,
                                                 size.height, 8, 4*size.width, rgbColorSpace,
                                                 kCGImageAlphaNoneSkipFirst);
    NSParameterAssert(context);

    //CGContextTranslateCTM(context, 0, CGImageGetHeight(image));
    //CGContextScaleCTM(context, 1.0, -1.0);//Flip vertically to account for different origin
    long width,height;
    if (CGImageGetWidth(image) > self.view.frame.size.width) {
        width = self.view.frame.size.width;
    }else{
        width = self.view.frame.size.width; //  CGImageGetWidth(image);
    }

    if (CGImageGetHeight(image) > self.view.frame.size.height) {
        height = self.view.frame.size.height;
    }else{
        height = self.view.frame.size.height -64 ;//  CGImageGetHeight(image);
    }
    CGContextDrawImage(context, CGRectMake(0, 0, width,
                                           height), image);
    CGColorSpaceRelease(rgbColorSpace);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}
Baisden answered 7/7, 2016 at 9:38 Comment(6)
did you solved this? same issues i faced..Discoid
@Hitesh- Nope, still i don't get any solution for this. Let me know if u will get solution.Baisden
i Think it's possible using FFMPEG.. but i have no more idea about it. #17380533Discoid
See https://mcmap.net/q/909295/-what-39-s-the-best-way-to-composite-frame-based-animated-stickers-over-recorded-video for an example of putting other images over video at runtime.Hoxha
@ZarnaParikh u got any solution to add animation on every image while creating video?plz reply.Marvelous
hi you got solution for your question i have do same things like you so if you get any solution then tell me pls,Conspire

© 2022 - 2024 — McMap. All rights reserved.