3

我正在完成一个将电影保存到相册的 iPhone 应用程序。电影源是​​一组图像。我用它来制作电影,它可以很好地把它们放在相册中,但一开始它总是有一个额外的绿框。

有任何想法吗?

我重新阅读了 Apple 的文档,调整了电线并使用编号图像进行了一些测试,以确认它没有掉帧或类似的东西。仍然没有得到正确的方法。

    //build save path with time
NSMutableString *buildPath = [[NSMutableString alloc] init];
[buildPath setString:@"Documents/"];
[buildPath appendString:@"temporary.mp4"];
    NSString *fullPath = [NSHomeDirectory() stringByAppendingPathComponent:buildPath];
[buildPath release];


    //if the file already exists, deleate it
NSFileManager *fileMgr = [NSFileManager defaultManager];
if([fileMgr fileExistsAtPath:fullPath]){
    if([fileMgr removeItemAtPath:fullPath error:&error] != YES){
        //error
    }
}

//prepare to write the movie
    AVAssetWriter *videoWriter =
    [[AVAssetWriter alloc] initWithURL
    :[NSURL fileURLWithPath:fullPath]
    fileType:AVFileTypeMPEG4
        error:&error];

   NSParameterAssert(videoWriter); 

   NSDictionary *videoSettings =
    [NSDictionary dictionaryWithObjectsAndKeys:
    AVVideoCodecH264,AVVideoCodecKey,
    [NSNumber numberWithInt:width],AVVideoWidthKey,
    [NSNumber numberWithInt:height],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]; 

//start writing
[videoWriter startWriting]; 
[videoWriter startSessionAtSourceTime:kCMTimeZero]; 

CVPixelBufferRef buffer = NULL; 
buffer = [self pixelBufferFromCGImage
    :[[imageArray objectAtIndex:0] CGImage]
    :CGSizeMake(width,height)];

CVPixelBufferPoolCreatePixelBuffer(NULL,adaptor.pixelBufferPool,&buffer);
[adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];

//loop through image array
int y = [imageArray count];
int x = 0;
while(x < y)
{
    if(writerInput.readyForMoreMediaData == YES){
        CMTime frameTime = CMTimeMake(1,24);
        CMTime lastTime = CMTimeMake(x,24);
        CMTime presentTime = CMTimeAdd(lastTime,frameTime);

        buffer = [self pixelBufferFromCGImage
            :[[imageArray objectAtIndex:x] CGImage]
            :CGSizeMake(width,height)];

        [adaptor appendPixelBuffer:buffer
            withPresentationTime:presentTime];
        x++;
    }
}

//finish writing 
[writerInput markAsFinished]; 
[videoWriter finishWriting];  

//clean up
CVPixelBufferPoolRelease(adaptor.pixelBufferPool); 
[videoWriter release]; 
[writerInput release];

//handle after save, save is asynchronous
void(^completionBlock)(NSURL *, NSError *) =
    ^(NSURL *assetURL, NSError *error)
{
    if(error != nil){
        //error
    }
    //remove temp movie file
    if([fileMgr removeItemAtPath:fullPath error:&error] != YES){
        //error
    }
};

//write the movie to photo album
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *filePathURL = [NSURL fileURLWithPath:fullPath isDirectory:NO];
if([library videoAtPathIsCompatibleWithSavedPhotosAlbum:filePathURL]){
    [library 
        writeVideoAtPathToSavedPhotosAlbum:filePathURL 
        completionBlock:completionBlock];
}
//clean up
[library release];
4

1 回答 1

2

你的第一个 PTS 应该是 0/24s 而不是 1/24s

糟糕,对不起,我的错误,你的第一个 PTS零 - 我没有注意到CVPixelBufferPoolCreatePixelBufferappendPixelBuffer:withPresentationTime:所以我改变了我的答案。

That very first pixel buffer that you append has nothing to do with your array of images. Is it undefined? I guess it's green. I'm not sure what you're doing with the pixel buffer pool - deleting those two lines and rebasing your loop at zero should get rid of the green frame.

于 2012-01-08T17:33:08.697 回答