2012-10-03 12 views
11

Attualmente sto lavorando a un'applicazione che si occupa dei video. Nella mia applicazione l'utente può tagliare il video, ho un controllo personalizzato per selezionare l'ora di inizio e l'ora di fine. Ho bisogno di tagliare il video con questi due valori. Ho provato con UIVideoEditorController come segue.Taglia video senza visualizzare UIVideoEditorController?

UIVideoEditorController* videoEditor = [[[UIVideoEditorController alloc] init] autorelease]; 
    videoEditor.delegate = self; 
    NSString* videoPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"MOV"]; 
    if ([UIVideoEditorController canEditVideoAtPath:videoPath]) 
    { 
     videoEditor.videoPath = videoPath; 
     [self presentModalViewController:videoEditor animated:YES]; 
    } 
    else 
    { 
     NSLog(@"can't edit video at %@", videoPath); 
    } 

Ma il problema è il codice di cui sopra verrà visualizzato il controllo editor video di Apple e l'utente può fare alcune operazioni su quel punto di vista. Non voglio visualizzare questa visualizzazione perché ho già visualizzato il video su MPMoviePlayer e ricevuto l'input dell'utente (ora di inizio e ora di fine) per il ritaglio del video su un controllo personalizzato. Come posso tagliare un video senza visualizzare UIVideoEditorController?

+1

mi può fornire ur codice per la rifilatura video, dove l'utente può scegliere ora di inizio e fine? –

risposta

17

Finalmente ho trovato la soluzione.

Possiamo usare AVAssetExportSession per tagliare i video senza visualizzare UIVideoEditorController.

Il mio codice è simile:

- (void)splitVideo:(NSString *)outputURL 
{ 

    @try 
    { 
     NSString *videoBundleURL = [[NSBundle mainBundle] pathForResource:@"Video_Album" ofType:@"mp4"]; 

     AVAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:videoBundleURL] options:nil]; 

     NSArray *compatiblePresets = [AVAssetExportSession exportPresetsCompatibleWithAsset:asset]; 

     if ([compatiblePresets containsObject:AVAssetExportPresetLowQuality]) 
     { 

      [self trimVideo:outputURL assetObject:asset]; 

     } 
     videoBundleURL = nil; 

     [asset release]; 
     asset = nil; 

     compatiblePresets = nil; 
    } 
    @catch (NSException * e) 
    { 
     NSLog(@"Exception Name:%@ Reason:%@",[e name],[e reason]); 
    } 
} 

Questo metodo Consente di tagliare il video di

- (void)trimVideo:(NSString *)outputURL assetObject:(AVAsset *)asset 
    { 

    @try 
    { 

     AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]initWithAsset:asset presetName:AVAssetExportPresetLowQuality]; 

     exportSession.outputURL = [NSURL fileURLWithPath:outputURL]; 

     exportSession.outputFileType = AVFileTypeQuickTimeMovie; 

     CMTime start = CMTimeMakeWithSeconds(splitedDetails.startTime, 1); 

     CMTime duration = CMTimeMakeWithSeconds((splitedDetails.stopTime - splitedDetails.startTime), 1); 

     CMTimeRange range = CMTimeRangeMake(start, duration); 

     exportSession.timeRange = range; 

     exportSession.outputFileType = AVFileTypeQuickTimeMovie; 

     [self checkExportSessionStatus:exportSession]; 

     [exportSession release]; 
     exportSession = nil; 

    } 
    @catch (NSException * e) 
    { 
     NSLog(@"Exception Name:%@ Reason:%@",[e name],[e reason]); 
    } 
} 

Questo metodo controlla lo stato di taglio:

- (void)checkExportSessionStatus:(AVAssetExportSession *)exportSession 
    { 

    [exportSession exportAsynchronouslyWithCompletionHandler:^(void) 
    { 

     switch ([exportSession status]) 
      { 

      case AVAssetExportSessionStatusCompleted: 

       NSLog(@"Export Completed"); 
       break; 

      case AVAssetExportSessionStatusFailed: 

       NSLog(@"Error in exporting"); 
       break; 

      default: 
       break; 

     } 
    }]; 
} 

sto chiamando il metodo splitVideo dal metodo di azione del pulsante di esportazione e passa l'uscita UR L come argomento.

+0

l'URL di output – Warewolf

+1

@Khoool: outputUrl è fornito per la scrittura del video tagliato. È un percorso file nella directory del documento –

+0

Sto usando lo stesso codice ma ricevo errore: Errore durante l'esportazione di NSString * percorso = [NSSearchPathForDirectoriesInDomains (NSDocumentationDirectory, NSUserDomainMask, YES) objectAtIndex: 0]; path = [percorso stringByAppendingPathComponent: @ "new.mov"]; NSLog (@ "percorso per salvare il video è% @", percorso); [self splitVideo: path]; – Warewolf

2

Siamo in grado di importare AVFoundation/AVFoundation.h

-(BOOL)trimVideofile 
{ 

    float videoStartTime;//define start time of video 
    float videoEndTime;//define end time of video 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"]; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); 
    NSString *libraryCachesDirectory = [paths objectAtIndex:0]; 
    libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:@"Caches"]; 
    NSString *OutputFilePath = [libraryCachesDirectory stringByAppendingFormat:@"/output_%@.mov", [dateFormatter stringFromDate:[NSDate date]]]; 
    NSURL *videoFileOutput = [NSURL fileURLWithPath:OutputFilePath]; 
    NSURL *videoFileInput;//<Path of orignal Video file> 

    if (!videoFileInput || !videoFileOutput) 
    { 
     return NO; 
    } 

    [[NSFileManager defaultManager] removeItemAtURL:videoFileOutput error:NULL]; 
    AVAsset *asset = [AVAsset assetWithURL:videoFileInput]; 

    AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset 
                      presetName:AVAssetExportPresetLowQuality]; 
    if (exportSession == nil) 
    { 
     return NO; 
    } 
    CMTime startTime = CMTimeMake((int)(floor(videoStartTime * 100)), 100); 
    CMTime stopTime = CMTimeMake((int)(ceil(videoEndTime * 100)), 100); 
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime); 

    exportSession.outputURL = videoFileOutput; 
    exportSession.timeRange = exportTimeRange; 
    exportSession.outputFileType = AVFileTypeQuickTimeMovie; 

    [exportSession exportAsynchronouslyWithCompletionHandler:^ 
    { 
     if (AVAssetExportSessionStatusCompleted == exportSession.status) 
     { 
      NSLog(@"Export OK"); 
     } 
     else if (AVAssetExportSessionStatusFailed == exportSession.status) 
     { 
      NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]); 
     } 
    }]; 
    return YES; 
} 
+0

Questa risposta è la stessa di sopra, qual è il vantaggio della duplicazione della risposta –

+0

Non è la risposta di duplicazione. In questo caso, stiamo utilizzando un'altra soluzione diversa. –

+0

Anche in questa risposta, sta usando 'AVAssetExportSession'. Anche qui la stessa cosa, allora qual è la differenza? –

Problemi correlati