I am really stuck on this, i have merged videos (mp4 kind that are saved in xcode, and mov - from users photo library) and audio (mp3 kind saved in xcode). On the simulator it works fine and shows the video and audio, but on the device it doesn't show the video only plays the sound . here is the code for merging:` AVMutableComposition* mixComposition = [AVMutableComposition composition];
//Audio
//Now first load your audio file using AVURLAsset. Make sure you give the correct path of your videos.
NSURL *audio_url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:_video.musicFileName ofType:@"mp3"]];
AVURLAsset *audioAsset = [[AVURLAsset alloc] initWithURL:audio_url options:nil];
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
//Now we are creating the first AVMutableCompositionTrack containing our audio and add it to our AVMutableComposition object.
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
//Video
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
NSString *fistPartMovieFilename = @"firstpart";
NSString *lastPartMovieFilename = @"lastpart";
//[_video.selectedVideosFileName insertObject:fistPartMovieFilename atIndex:0];
//[_video.selectedVideosFileName addObject:lastPartMovieFilename];
NSMutableArray *timeRanges = [NSMutableArray arrayWithCapacity:_video.selectedVideosFileName.count];
NSMutableArray *tracks = [NSMutableArray arrayWithCapacity:_video.selectedVideosFileName.count];
NSLog(@"_video.selectedVideosFileName %@",_video.selectedVideosFileName);
for (int i=0; i<[_video.selectedVideosFileName count]; i++)
{
AVURLAsset *assetClip;
NSString *fileName = [_video.selectedVideosFileName objectAtIndex:i];
if ([[_video.selectedVideosFileName objectAtIndex:i] isKindOfClass:[NSURL class]])
{
assetClip = [AVAsset assetWithURL:[_video.selectedVideosFileName objectAtIndex:i]];
}
else
{
assetClip = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithString:fileName] ofType:@"mp4"]] options:nil];
}
AVAssetTrack *clipVideoTrack = [[assetClip tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
[timeRanges addObject:[NSValue valueWithCMTimeRange:CMTimeRangeMake(kCMTimeZero, assetClip.duration)]];
[tracks addObject:clipVideoTrack];
NSLog(@"timeRanges %@",timeRanges);
NSLog(@"tracks %@",tracks);
NSLog(@"assetClip %@",assetClip);
NSLog(@"clipVideoTrack %@",clipVideoTrack);
}
NSError *error = nil;
BOOL sucsess = [compositionVideoTrack insertTimeRanges:timeRanges
ofTracks:tracks
atTime:kCMTimeZero
error:&error];
if (!sucsess || error) {
NSLog(@"video error %@", error);
}
the error i get when trying on device is : video error Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x1704707c0 {NSUnderlyingError=0x174247050 "The operation couldn’t be completed. (OSStatus error -12780.)", NSLocalizedFailureReason=An unknown error occurred (-12780), NSLocalizedDescription=The operation could not be completed
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString *outputFilePath = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:@"Zagoori-%d.mov",arc4random() % 1000]];
NSURL *outputFileUrl = [NSURL fileURLWithPath:outputFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputFilePath])
[[NSFileManager defaultManager] removeItemAtPath:outputFilePath error:nil];
//Now create an AVAssetExportSession object that will save your final video at specified path.
AVAssetExportSession *_assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetLowQuality];
NSLog(@"supportedFileTypes %@", [_assetExport supportedFileTypes]);
_assetExport.outputFileType = @"com.apple.quicktime-movie";
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:^
{
dispatch_async(dispatch_get_main_queue(), ^{
switch ([_assetExport status]) {
case AVAssetExportSessionStatusExporting:
NSLog(@"Export in progress ");
case AVAssetExportSessionStatusFailed:
NSLog(@"Export failed (%ld): %@", (long)[[_assetExport error] code], [[_assetExport error] localizedFailureReason]);
[_assetExport cancelExport];
break;
case AVAssetExportSessionStatusCancelled:
NSLog(@"Export canceled");
break;
case AVAssetExportSessionStatusCompleted:
NSLog(@"Export done");
[self exportDidFinish:_assetExport];
// NSLog (@"finished writing %f", [dtStartDate timeIntervalSinceNow]);
break;
case AVAssetExportSessionStatusWaiting:
NSLog (@"AVAssetExportSessionStatusWaiting");
break;
case AVAssetExportSessionStatusUnknown:
NSLog (@"AVAssetExportSessionStatusUnknown");
break;
}
});
}];
-(void)loadMoviePlayer:(NSURL*)moviePath {
_moviePlayerController = [[MPMoviePlayerController alloc]
initWithContentURL:moviePath];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(introMovieFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:_moviePlayerController];
_moviePlayerController.view.hidden = NO;
_moviePlayerController.view.frame = CGRectMake(0, 0, _videoView.frame.size.width,
_videoView.frame.size.height);
_moviePlayerController.view.backgroundColor = [UIColor clearColor];
_moviePlayerController.scalingMode = MPMovieScalingModeAspectFit;
_moviePlayerController.fullscreen = NO;
[_moviePlayerController prepareToPlay];
[_moviePlayerController readyForDisplay];
[_moviePlayerController setControlStyle:MPMovieControlStyleDefault];
_moviePlayerController.shouldAutoplay = YES;
[_videoView addSubview:_moviePlayerController.view];
[_videoView setHidden:NO];
}
I am really clueless of what the problem could be, Help please! :)