2012-10-31 85 views
0

我是在視頻輸出圖像的陣列和音頻文件創建圖像的視頻並保存到相冊

,但我似乎無法將它保存到相機膠捲

一些時間它可以節省,但有時它不會,並給我一個奇怪的錯誤

outputFile.mp4無法保存到保存的照片相冊:錯誤域= NSOSStatusErrorDomain代碼= -12848「電影無法播放。」的UserInfo = 0x7bd7370 {。NSLocalizedDescription =電影無法播放}

這個函數從圖像陣列創建視頻:

-(void) writeImagesToMovieAtPath:(NSString *) path withSize:(CGSize) size 
{ 
    NSLog(@"Write Started"); 

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


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

    CVPixelBufferRef buffer = NULL; 

    //convert uiimage to CGImage. 

    int frameCount = 16; 
    int kRecordingFPS = 30; 
    UIImage * im = [UIImage imageNamed:@"IMG_0103.JPG"]; 

    NSArray * imageArray = [[NSArray alloc]initWithObjects:im,im,im,im,im,im,im,im,im,im,im,im,im,im,im,im, nil]; 

    for(UIImage * img in imageArray) 
    { 
     buffer = [self pixelBufferFromCGImage:[img CGImage] andSize:size]; 

     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) kRecordingFPS); 
       append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime]; 

       if(buffer) 
        CVBufferRelease(buffer); 
       [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++; 
    } 


    //Finish the session: 
    [videoWriterInput markAsFinished]; 
    [videoWriter finishWriting]; 
    NSLog(@"Write Ended"); 
    [videoWriterInput release]; 
    [videoWriter release]; 
    [imageArray release]; 
} 

該函數添加音頻:

-(void)CompileFilesToMakeMovie{ 
     AVMutableComposition* mixComposition = [AVMutableComposition composition]; 

     NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 

     NSString* audio_inputFileName = @"Rihanna-Take a Bow.mp3"; 

     NSString* audio_inputFilePath = [NSString stringWithFormat:@"%@/%@",documentsDirectoryPath,audio_inputFileName]; 

     NSURL* audio_inputFileUrl = [NSURL fileURLWithPath:audio_inputFilePath]; 

     NSString* video_inputFileName = @"a.mp4"; 
     NSString* video_inputFilePath = [NSString stringWithFormat:@"%@/%@",documentsDirectoryPath,video_inputFileName]; 
     NSURL* video_inputFileUrl = [NSURL fileURLWithPath:video_inputFilePath]; 

     NSString* outputFileName = @"outputFile.mp4"; 
     NSString* outputFilePath = [NSString stringWithFormat:@"%@/%@",documentsDirectoryPath,outputFileName]; 

     NSURL* outputFileUrl = [NSURL fileURLWithPath:outputFilePath]; 

     if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath]) 
      [[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil]; 



     CMTime nextClipStartTime = kCMTimeZero; 

     AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:video_inputFileUrl options:nil]; 
     CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero,videoAsset.duration); 

     AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 
     [a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:nextClipStartTime error:nil]; 

     //nextClipStartTime = CMTimeAdd(nextClipStartTime, a_timeRange.duration); 

     AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil]; 
     CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, videoAsset.duration); 
     AVMutableCompositionTrack *b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
     [b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:nextClipStartTime error:nil]; 



     AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetMediumQuality]; 
     _assetExport.outputFileType = AVFileTypeMPEG4; 
     _assetExport.outputURL = outputFileUrl; 
     [_assetExport setTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)]; 
     [_assetExport exportAsynchronouslyWithCompletionHandler:nil]; 

     [audioAsset release]; 
     [videoAsset release]; 


     [_assetExport release]; 
    } 

的函數調用:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    NSString *documentsDirectoryPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 

    UIImage * i = [UIImage imageNamed:@"IMG_0103.JPG"]; 

    [self writeImagesToMovieAtPath:[NSString stringWithFormat:@"%@/%@",documentsDirectoryPath,@"a.mp4"] withSize:CGSizeMake(i.size.width, i.size.height)]; 

    NSString* exportVideoPath1 = [NSString stringWithFormat:@"%@/%@",documentsDirectoryPath,@"a.mp4"]; 


    NSString* exportVideoPath = [NSString stringWithFormat:@"%@/%@",documentsDirectoryPath,@"outputFile.mp4"]; 

    UISaveVideoAtPathToSavedPhotosAlbum (exportVideoPath,self, @selector(video:didFinishSavingWithError: contextInfo:), nil); 

} 
+0

你可以更清楚一點。您製作了應用程序,將圖片轉換爲視頻,然後保存視頻?有時它並不能拯救他們?你有什麼代碼可以分享你的洞嗎? – nycynik

+0

我添加了代碼 ,主要是我在這篇文章中使用了代碼:http://stackoverflow.com/a/6094407/1708270 –

+0

這就是它正在發生的 它有時會保存,有時它不會 也是錯誤代碼更改爲(代碼= -12893)在自己的 –

回答

0

在我的情況下,原因是AVAssetWriter還沒有完成d寫作。解決它與下面的一段代碼:

__block BOOL _finished = NO; 

[assetWriter finishWritingWithCompletionHandler:^{ 
    _finished = YES; 
}]; 

while (!_finished) { 
    [NSThread sleepForTimeInterval:0.1]; 
} 
相關問題