2012-05-18 70 views
12

Tôi đã thực hiện R & D và nhận được thành công về cách lấy khung hình về hình ảnh từ tệp video được phát trong MPMoviePlayerController.Cách tạo video từ các khung hình của nó iPhone

Có tất cả các khung từ mã này và lưu tất cả hình ảnh trong một Mảng.

for(int i= 1; i <= moviePlayerController.duration; i++) 
{ 
    UIImage *img = [moviePlayerController thumbnailImageAtTime:i timeOption:MPMovieTimeOptionNearestKeyFrame]; 
    [arrImages addObject:img]; 
} 

Bây giờ câu hỏi là, Sau khi thay đổi một số tệp hình ảnh, như thêm cảm xúc vào hình ảnh và thêm bộ lọc, chẳng hạn như; phim thực, đen và trắng, Làm cách nào chúng ta có thể tạo lại video và lưu trữ cùng một video trong thư mục Tài liệu với cùng tốc độ khung hình mà không làm giảm chất lượng video.

Sau khi thay đổi một số hình ảnh tôi đã thực hiện theo mã sau để lưu lại video đó.

- (void) writeImagesAsMovie:(NSString*)path 
{ 
    NSError *error = nil; 
    UIImage *first = [arrImages objectAtIndex:0]; 
    CGSize frameSize = first.size; 
    AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL: 
            [NSURL fileURLWithPath:path] fileType:AVFileTypeQuickTimeMovie 
                   error:&error]; 
    NSParameterAssert(videoWriter); 

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
            AVVideoCodecH264, AVVideoCodecKey, 
            [NSNumber numberWithInt:640], AVVideoWidthKey, 
            [NSNumber numberWithInt:480], AVVideoHeightKey, 
            nil]; 
    AVAssetWriterInput* writerInput = [[AVAssetWriterInput 
             assetWriterInputWithMediaType:AVMediaTypeVideo 
             outputSettings:videoSettings] retain]; 

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

    NSParameterAssert(writerInput); 
    NSParameterAssert([videoWriter canAddInput:writerInput]); 
    [videoWriter addInput:writerInput]; 

    [videoWriter startWriting]; 
    [videoWriter startSessionAtSourceTime:kCMTimeZero]; 

    int frameCount = 0; 
    CVPixelBufferRef buffer = NULL; 
    for(UIImage *img in arrImages) 
    { 
     buffer = [self newPixelBufferFromCGImage:[img CGImage] andFrameSize:frameSize]; 

      if (adaptor.assetWriterInput.readyForMoreMediaData) 
      { 
       CMTime frameTime = CMTimeMake(frameCount,(int32_t) kRecordingFPS); 
       [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime]; 

       if(buffer) 
        CVBufferRelease(buffer); 
      } 
     frameCount++; 
    } 

    [writerInput markAsFinished]; 
    [videoWriter finishWriting]; 
} 


- (CVPixelBufferRef) newPixelBufferFromCGImage: (CGImageRef) image andFrameSize:(CGSize)frameSize 
{ 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, 
          [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, 
          nil]; 
    CVPixelBufferRef pxbuffer = NULL; 
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width, 
              frameSize.height, kCVPixelFormatType_32ARGB, (CFDictionaryRef) options, 
              &pxbuffer); 
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL); 

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

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width, 
               frameSize.height, 8, 4*frameSize.width, rgbColorSpace, 
               kCGImageAlphaNoneSkipFirst); 
    NSParameterAssert(context); 
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0)); 
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
              CGImageGetHeight(image)), image); 
    CGColorSpaceRelease(rgbColorSpace); 
    CGContextRelease(context); 

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0); 

    return pxbuffer; 
} 

Tôi mới trong chủ đề này vì vậy hãy giúp tôi giải quyết câu hỏi này.

liên kết
+0

Bạn có thể sử dụng http://stackoverflow.com/ câu hỏi/7873423/iphone-sdk-create-a-video-từ-uiimage – Jasmit

+0

Bạn đã nhận được giải pháp cho điều này chưa? Bạn có thể vui lòng gửi giải pháp nếu có thể? –

+0

lý do bạn muốn chuyển đổi thành video một lần nữa? chỉ sử dụng hình ảnh ... –

Trả lời

7
+0

Xin chào bạn có điều gì cập nhật cho Swift không? Tất cả các liên kết này dường như cũ. Chúng tôi đang cố gắng hợp nhất hình ảnh và video thành một video chính nơi hình ảnh phải xuất hiện dưới dạng "video" riêng biệt trong video chính. Ví dụ: giả sử 1 hình ảnh và 1 video. Trong video chính, hình ảnh xuất hiện trong 3 giây và sau đó video phát. Bạn có lời khuyên nào về việc này không? Cảm ơn! – Crashalot

1

Bạn cần tải hình ảnh cho mọi khung hình mà màn hình hiển thị. Tôi đã sử dụng UIGetScreenImage() API riêng tư để thực hiện tương tự. và viết những hình ảnh đó dưới dạng Phim bằng cách sử dụng AVAssetWriter.

Tôi đã viết một wrapper để làm cần thiết chỉ với vài dòng mã, hãy thử thành phần mã nguồn mở này để tham khảo:

https://www.cocoacontrols.com/controls/iqprojectvideo

+0

API riêng tư? Không, nhất quyết không. – Raptor

+0

Bạn chắc chắn sẽ không tải dự án của mình lên AppStore bằng thư viện này. Nó chỉ để ghi video từ màn hình. Chỉ cần sử dụng và ném. Vậy tại sao API riêng tư không nên được sử dụng? –

Các vấn đề liên quan