1

它修剪音頻,但視頻是空白的。使用AVAssetExportSession導出電影時,爲什麼不能獲得視頻?

這是啓動微調

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    self.view.backgroundColor = [UIColor blackColor]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(finishedTrimming:) 
              name:@"videoFinishedTrimming" 
              object:nil]; 
    NSURL *furl = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"capture0.mp4"]]; 

    //[self playVideoWithURL:furl]; //Play original video 

    //Play trimmed video 
    CMTime startTrim = CMTimeMake(0, 1); 
    CMTime endTrim = CMTimeMake(2,1); 
    CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTrim, endTrim); 

    [ProcessingHelper trimAssetWithURL:furl andRange:exportTimeRange]; 
} 

功能這是函數,出口和修剪視頻。

+(void)trimAssetWithURL:(NSURL *)urlIn andRange:(CMTimeRange)timeRangeIn 
{ 
    AVAsset *videoAsset = [AVAsset assetWithURL:urlIn]; 

    //Creates the session with the videoasset 
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:videoAsset presetName:AVAssetExportPresetHighestQuality]; 

    //Creates the path to export to - Saving to temporary directory 
    NSString* filename = [NSString stringWithFormat:@"TrimmedCapture%d.mp4", 0]; 
    NSString* path = [NSTemporaryDirectory() stringByAppendingPathComponent:filename]; 

    //Checks if there is already a file at the output URL. session will not overwrite previous data 
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) 
    { 
     NSLog(@"Removing item at path: %@", path); 
     [[NSFileManager defaultManager] removeItemAtPath:path error:nil]; 
    } 

    //Set the output url 
    exportSession.outputURL = [NSURL fileURLWithPath:path]; 

    //Set the output file type 
    exportSession.outputFileType = AVFileTypeMPEG4; //AVFileTypeAC3; // AVFileTypeMPEGLayer3; // AVFileTypeWAVE; // AVFileTypeQuickTimeMovie; 

    exportSession.timeRange = timeRangeIn; 

    exportSession.metadata = nil; 

    //Exports! 
    [exportSession exportAsynchronouslyWithCompletionHandler:^{ 
     switch (exportSession.status) { 
      case AVAssetExportSessionStatusCompleted:{ 
       NSLog(@"Export Complete"); 
       NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:exportSession.outputURL, @"outputURL", nil]; 
       [[NSNotificationCenter defaultCenter] postNotificationName:@"videoFinishedTrimming" object:self userInfo:options]; 
       break; 
      } 
      case AVAssetExportSessionStatusFailed: 
       NSLog(@"Export Error: %@", [exportSession.error description]); 
       break; 
      case AVAssetExportSessionStatusCancelled: 
       NSLog(@"Export Cancelled"); 
       break; 
      default: 
       break; 
     } 
    }]; 
    exportSession = nil; 
} 

這是啓動視頻

-(void)finishedTrimming:(NSNotification *)notification 
{ 
    NSDictionary *userInfo = notification.userInfo; 
    NSURL *outputURL = [userInfo objectForKey:@"outputURL"]; 
    [self playVideoWithURL:outputURL]; 

} 

播放中的功能,這是播放視頻

-(void)playVideoWithURL:(NSURL *)furl 
{ 
    NSData *movieData; 
    NSError *dataReadingError = nil; 
    movieData = [NSData dataWithContentsOfURL: furl options:NSDataReadingMapped error:&dataReadingError]; 
    if(movieData != nil) 
     NSLog(@"Successfully loaded the data."); 
    else 
     NSLog(@"Failed to load the data with error = %@", dataReadingError); 


    //AVPlayer 
    self.avPlayer = [AVPlayer playerWithURL:furl]; 
    AVPlayerLayer *avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer]; 
    avPlayerLayer.frame = self.vPlayBackMovie.bounds; 
    avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    avPlayerLayer.needsDisplayOnBoundsChange = YES; 

    [self.vPlayBackMovie.layer addSublayer:avPlayerLayer]; 
    self.vPlayBackMovie.layer.needsDisplayOnBoundsChange = YES; 
    [self.avPlayer play]; 
} 
+0

不能隨便記後讓主線程,但你有沒有證實出口完成處理程序正在主線程上發生? – ChrisH

+0

我沒有。我在哪裏以及如何檢查?它是否重要?在完成處理程序中,我正在發佈通知,並在主線程中觀察通知。所以無論它完成了什麼線程,每當完成時我都應該在主線程上知道對嗎? – jgvb

回答

1

感謝ChrisH的功能,你說得對!這項出口是發生在另一個線程,以便在處理程序中,我需要讓主隊列...

我需要

​​3210
+0

如果有人正在尋找/感興趣,您還可以通過將dispatch_main()添加到主文件(本例中爲main.swift)的末尾來獲取導出回調。 – Natalia

相關問題