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];
}
不能隨便記後讓主線程,但你有沒有證實出口完成處理程序正在主線程上發生? – ChrisH
我沒有。我在哪裏以及如何檢查?它是否重要?在完成處理程序中,我正在發佈通知,並在主線程中觀察通知。所以無論它完成了什麼線程,每當完成時我都應該在主線程上知道對嗎? – jgvb