繁体   English   中英

将生成的视频移至下一个视图并将其保存到iOS中的“相机胶卷”中

[英]Getting generated video to next view and saving it to Camera roll in iOS

在这里,我需要生成带有多个选择的图像的视频,然后选择音乐。在这种情况下,我可以选择多个图像并将这些图像生成视频,方法是将选定的图像保存在数组中并生成视频。但是我的问题是,生成的视频应该在下一个视图中显示并且也应将其保存在CameraRoll中。但是生成的视频将进入“文档”并保存在那里。有人帮助我。

我正在关注此链接https://github.com/caferrara/img-to-video

我的代码:

 NSError *error = nil;
 NSFileManager *fileMgr = [NSFileManager defaultManager];
 NSString *documentsDirectory = [NSHomeDirectory()
 stringByAppendingPathComponent:@"Documents"];
 NSString *videoOutputPath = [documentsDirectory      stringByAppendingPathComponent:@"test_output.mp4"];
 if ([fileMgr removeItemAtPath:videoOutputPath error:&error] != YES)
    NSLog(@"Unable to delete file: %@", [error localizedDescription]);
   CGSize imageSize = CGSizeMake(400, 200);
   NSUInteger fps = 30;
  NSArray* imagePaths = [[NSBundle mainBundle]   pathsForResourcesOfType:@"jpg" inDirectory:nil];
 self.chosenImages = [[NSMutableArray alloc]   initWithCapacity:imagePaths.count];
 NSLog(@"-->imageArray.count= %i", self.chosenImages.count);
  for (NSString* path in imagePaths)
  {
    [self.chosenImages addObject:[UIImage imageWithContentsOfFile:path]];

 }

 NSLog(@"Start building video from defined frames.");

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

   NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                               AVVideoCodecH264, AVVideoCodecKey,
   [NSNumber numberWithInt:imageSize.width],   AVVideoWidthKey,
   [NSNumber numberWithInt:imageSize.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];
 [videoWriter startWriting];
 [videoWriter startSessionAtSourceTime:kCMTimeZero];

CVPixelBufferRef buffer = NULL;

//convert uiimage to CGImage.
int frameCount = 0;
double numberOfSecondsPerFrame = 6;
double frameDuration = fps * numberOfSecondsPerFrame;

//for(VideoFrame * frm in imageArray)
NSLog(@"**************************************************");
for(UIImage * img in self.chosenImages)
{
    //UIImage * img = frm._imageFrame;
    buffer = [self pixelBufferFromCGImage:[img CGImage]];

    BOOL append_ok = NO;
    int j = 0;
    while (!append_ok && j < 30) {
        if (adaptor.assetWriterInput.readyForMoreMediaData)  {
            //print out status:
            NSLog(@"Processing video frame (%d,%lu)",frameCount,(unsigned long)[self.chosenImages count]);

            CMTime frameTime = CMTimeMake(frameCount*frameDuration,(int32_t) fps);
            append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime];
            if(!append_ok){
                NSError *error = videoWriter.error;
                if(error!=nil) {
                    NSLog(@"Unresolved error %@,%@.", error, [error userInfo]);
                }
            }
        }
        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, with error.", frameCount, j);
    }
    frameCount++;
}
NSLog(@"**************************************************");

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



////////////////////////////////////////////////////////////////////////////
//////////////  OK now add an audio file to move file  /////////////////////
AVMutableComposition* mixComposition = [AVMutableComposition composition];

NSString *bundleDirectory = [[NSBundle mainBundle] bundlePath];
// audio input file...
NSString *audio_inputFilePath = [bundleDirectory stringByAppendingPathComponent:@"30secs.mp3"];
NSURL    *audio_inputFileUrl = [NSURL fileURLWithPath:audio_inputFilePath];

// this is the video file that was just written above, full path to file is in --> videoOutputPath
NSURL    *video_inputFileUrl = [NSURL fileURLWithPath:videoOutputPath];

// create the final video output file as MOV file - may need to be MP4, but this works so far...
NSString *outputFilePath = [documentsDirectory stringByAppendingPathComponent:@"final_video.mp4"];
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, audioAsset.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:AVAssetExportPresetHighestQuality];
   //_assetExport.outputFileType = @"com.apple.quicktime-movie";
   _assetExport.outputFileType = @"public.mpeg-4";
  //NSLog(@"support file types= %@", [_assetExport supportedFileTypes]);
  _assetExport.outputURL = outputFileUrl;

  [_assetExport exportAsynchronouslyWithCompletionHandler:
   ^(void ) {
     //[self saveVideoToAlbum:outputFilePath];
   }
   ];

   NSLog(@"DONE.....outputFilePath--->%@", outputFilePath);

您也可以按文档路径在下一个屏幕中获取视频。

您可以通过执行以下代码将视频从“文档”文件夹存储到PhotoLibrary。

ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary writeVideoAtPathToSavedPhotosAlbum:DocumentPath completionBlock:^(NSURL *assetURL, NSError *error){
  If(error == nil){
   // Saved successfully
  }
}];

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM