AVAssetWriter将绿色帧添加到电影输出

时间:2012-01-08 04:01:52

标签: ios video h.264 avassetwriter

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

有什么想法吗?

我已经重新阅读了苹果公司的文档,摇晃了电线,并对编号图像进行了一些测试,以确认它没有丢帧或类似的东西。仍然没有正确的方式。

    //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];

1 个答案:

答案 0 :(得分:2)

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

糟糕,抱歉我的错误,你的第一个PTS 为零 - 我没有注意到CVPixelBufferPoolCreatePixelBufferappendPixelBuffer:withPresentationTime:,所以我改变了我的回答。

您附加的第一个像素缓冲区与您的图像数组无关。这是不确定的?我猜它是绿色的。我不确定你在使用像素缓冲池做什么 - 删除这两行并将你的循环重新设置为零应该摆脱绿框。