2017-11-27 4 views
0

Ich versuche, mich selbst mit der Codierung von Ziel c zu verbessern und ich bin nicht gut genug, um dieses Problem zu lösen. Ich verwende den folgenden Code, um Video mit Audio zu verbinden und das letzte Video als Kamera zu speichern. Der Code funktioniert perfekt, aber ich muss das Video in temporäre Dokumente speichern, damit ich das Video ändern oder ändern kann, ohne es bei jeder kleinen Änderung zu speichern.Video in DocumentsDirectory speichern

Hier ist mein Code:

- (IBAction)addBackgroundMusicAction:(UIButton *)sender { 
    if (self.asset == nil) { 
     return; 
    } 


    NSString *outPutPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"mergeVideo-%d.mov",arc4random() % 1000]]; 

    NSURL *outPutUrl = [NSURL fileURLWithPath:outPutPath]; 
    if ([[NSFileManager defaultManager] fileExistsAtPath:outPutPath]) 
    { 
     [[NSFileManager defaultManager] removeItemAtPath:outPutPath error:nil]; 
    } 
    AVMutableComposition *composition = [AVMutableComposition composition]; 
    CMTimeRange videoTimeRange = CMTimeRangeMake(kCMTimeZero, self.asset.duration); 
    AVMutableCompositionTrack *videoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid]; 

    AVAssetTrack *videoAssetTrack = [[self.asset tracksWithMediaType:AVMediaTypeVideo] firstObject]; 
    [videoTrack insertTimeRange:videoTimeRange ofTrack:videoAssetTrack atTime:kCMTimeZero error:nil]; 

    AVURLAsset *audioAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"myAudio" ofType:@"mp3"]] options:nil]; 
    AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid]; 
    AVAssetTrack *audioAssetTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject]; 
    [audioTrack insertTimeRange:videoTimeRange ofTrack:audioAssetTrack atTime:kCMTimeZero error:nil]; 


    // 3.1 - Create AVMutableVideoCompositionInstruction 
    AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, self.asset.duration); 
    // 3.2 - Create an AVMutableVideoCompositionLayerInstruction for the video track and fix the orientation. 
    AVMutableVideoCompositionLayerInstruction *videolayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack]; 
    UIImageOrientation videoAssetOrientation_ = UIImageOrientationUp; 
    BOOL isVideoAssetPortrait_ = NO; 
    CGAffineTransform videoTransform = videoAssetTrack.preferredTransform; 
    if (videoTransform.a == 0 && videoTransform.b == 1.0 && videoTransform.c == -1.0 && videoTransform.d == 0) { 
     videoAssetOrientation_ = UIImageOrientationRight; 
     isVideoAssetPortrait_ = YES; 
    } 
    if (videoTransform.a == 0 && videoTransform.b == -1.0 && videoTransform.c == 1.0 && videoTransform.d == 0) { 
     videoAssetOrientation_ = UIImageOrientationLeft; 
     isVideoAssetPortrait_ = YES; 
    } 
    if (videoTransform.a == 1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == 1.0) { 
     videoAssetOrientation_ = UIImageOrientationUp; 
    } 
    if (videoTransform.a == -1.0 && videoTransform.b == 0 && videoTransform.c == 0 && videoTransform.d == -1.0) { 
     videoAssetOrientation_ = UIImageOrientationDown; 
    } 
    [videolayerInstruction setTransform:videoAssetTrack.preferredTransform atTime:kCMTimeZero]; 
    [videolayerInstruction setOpacity:0.0 atTime:self.asset.duration]; 

    // 3.3 - Add instructions 
    mainInstruction.layerInstructions = [NSArray arrayWithObjects:videolayerInstruction,nil]; 

    AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition]; 

    CGSize naturalSize; 
    if(isVideoAssetPortrait_){ 
     naturalSize = CGSizeMake(videoAssetTrack.naturalSize.height, videoAssetTrack.naturalSize.width); 
    } else { 
     naturalSize = videoAssetTrack.naturalSize; 
    } 

    float renderWidth, renderHeight; 
    renderWidth = naturalSize.width; 
    renderHeight = naturalSize.height; 
    mainCompositionInst.renderSize = CGSizeMake(renderWidth, renderHeight); 
    mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction]; 
    mainCompositionInst.frameDuration = CMTimeMake(1, 30); 


    AVAssetExportSession * assetExport = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetMediumQuality]; 
    assetExport.outputURL = outPutUrl; 
    assetExport.outputFileType = AVFileTypeQuickTimeMovie; 
    assetExport.shouldOptimizeForNetworkUse = YES; 
    assetExport.videoComposition = mainCompositionInst; 
    [assetExport exportAsynchronouslyWithCompletionHandler:^{ 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      [self exportDidFinish:assetExport]; 
     }); 
    }]; 
} 

Und sie ist, wo ich das Video auf die Rolle Kamera exportieren:

- (void)exportDidFinish:(AVAssetExportSession*)session { 
    if (session.status == AVAssetExportSessionStatusCompleted) { 
     NSURL *outputURL = session.outputURL; 
     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
     if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputURL]) { 
      [library writeVideoAtPathToSavedPhotosAlbum:outputURL completionBlock:^(NSURL *assetURL, NSError *error){ 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        if (error) { 
         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Saving Failed" 
                     delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
         [alert show]; 
        } else { 
         AVPlayerItem * playeritem = [AVPlayerItem playerItemWithURL:outputURL]; 
         [_player replaceCurrentItemWithPlayerItem:playeritem]; 
         [_player play]; 

        } 
       }); 
      }]; 
     } 
    } 
} 

Wie gesagt, ich brauche, um das Video zu der nicht zu speichern Kamerarolle, ich muss es nur vorübergehend speichern. Außerdem muss ich dieses Video laden, wenn ich eine andere Taste drücke. Speichern Sie das Video und laden Sie es erneut.

Dank

Antwort

1

Verwendung Code Folgende:

NSData *videoData = [NSData dataWithContentsOfURL:outputURL]; 
    if (videoData) { 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"MyFolder"]; 
     // Create folder if needed 
     [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:YES attributes:nil error:nil]; 

     NSString *filePath = [dataPath stringByAppendingPathComponent:@"test.mp4"]; 
     if ([videoData writeToFile:filePath atomically:YES]) { 
      // yeah - file written 
     } else { 
      // oops - file not written 
     } 
    } else { 
     // oops - couldn't get data 
    } 
Verwandte Themen