I am trying to create app like dubsmash. I want mute audio in recording video and playing only custom audio. I am playing custom audio using AVPlayer. my problem is mute only recording video only not custom audio. I tried to set AVAudioSessionCategoryPlayback but, they mute both sound. pls suggest some ideas
Merging audio and video is working:
-(NSURL *)videoAndAudioMergin:(NSURL *)videoTrack
{
NSURL *playerurl = [[NSBundle mainBundle] URLForResource:trackName
withExtension:#"mp3"
subdirectory:nil];
AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:playerurl options:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoTrack options:nil];
AVMutableComposition* mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetHighestQuality];
NSString* videoName = #"export.mov";
NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
return exportUrl;
}
Related
I try to play a m3u8 file and a mp3 file simultaneously:
NSURL *audioURL = [NSURL URLWithString:#"https://XXX.de/XXX.mp3"];
AVAsset *audioAsset = [AVAsset assetWithURL:audioURL];
NSURL *videoURL = [NSURL URLWithString:#"https://XXX.de/XXX.m3u8"];
AVAsset *videoAsset = [AVAsset assetWithURL:videoURL];
NSError *error;
AVMutableComposition* mixAsset = [[AVMutableComposition alloc] init];
AVMutableCompositionTrack* audioTrack = [mixAsset addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error: &error];
AVMutableCompositionTrack* videoTrack = [mixAsset addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error: &error];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:mixAsset];
movie = [AVPlayer playerWithPlayerItem:playerItem];
but it is not working. I get the following error:
*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
With a mp4-Files it is working but not with m3u8 file.
The apple docs say that avasset works with local or remote URLs:
https://developer.apple.com/documentation/avfoundation/avasset?language=objc
i wonder if m3u8 is basically not working.
I have this code to add a overlay to my asset and export it to a URL:
AVAsset *videoAsset = editableAsset;
AVMutableComposition* mixComposition = [AVMutableComposition composition];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
AVAssetTrack *clipVideoTrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject];
AVMutableCompositionTrack *compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipVideoTrack atTime:kCMTimeZero error:nil];
if ([videoAsset tracksWithMediaType:AVMediaTypeAudio].count != 0) {
AVAssetTrack *clipAudioTrack = [[videoAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
[compositionAudioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:clipAudioTrack atTime:kCMTimeZero error:nil];
}
[compositionVideoTrack setPreferredTransform:[[[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject] preferredTransform]];
CGSize sizeOfVideo = [videoAsset naturalSize];
CALayer *layerCa = [CALayer layer];
layerCa.contents = (id)[UIImage imageNamed:#"Overlay.png"].CGImage;
layerCa.frame = CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height);
layerCa.opacity = 1.0;
CALayer *parentLayer=[CALayer layer];
CALayer *videoLayer=[CALayer layer];
parentLayer.frame=CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height);
videoLayer.frame=CGRectMake(0, 0, sizeOfVideo.width, sizeOfVideo.height);
[parentLayer addSublayer:videoLayer];
[parentLayer addSublayer:layerCa];
AVMutableVideoComposition *videoComposition=[AVMutableVideoComposition videoComposition] ;
videoComposition.frameDuration=CMTimeMake(1, 30);
videoComposition.renderSize = sizeOfVideo;
videoComposition.animationTool=[AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
instruction.timeRange = CMTimeRangeMake(kCMTimeZero, [mixComposition duration]);
AVAssetTrack *videoTrack = [[mixComposition tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVMutableVideoCompositionLayerInstruction* layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
videoComposition.instructions = [NSArray arrayWithObject: instruction];
NSString* docFolder = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString* outputPath = [docFolder stringByAppendingPathComponent:#"output.mov"];
if ([[NSFileManager defaultManager] fileExistsAtPath:outputPath])
[[NSFileManager defaultManager] removeItemAtPath:outputPath error:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:editableAsset presetName:AVAssetExportPresetHighestQuality];
exportSession.videoComposition = videoComposition;
exportSession.outputURL = [NSURL fileURLWithPath:outputPath];
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
assetURL = [NSURL fileURLWithPath:outputPath];
});
}];
The strange think: It tilt the AVAsset and I get a landscape video instead of portrait. But I dont have any code to change the orientation. Can you explain it to me?
I have an application in which I need to merge an audio file in to the video recorded by AVCapture session, so that both audio of recorded movie and merged audio can be heard.
I am able to merge the audio to video with avcomposition and it does fine . But the problem is that the original audio file can not be heard. Here is my code.
NSString *resourceAudioName = [NSString stringWithFormat:#"%#_audio",getTitle];
NSURL *audio_inputFileUrl = [[NSBundle mainBundle] URLForResource:resourceAudioName withExtension:#"mp3"];
NSString * video_inputFilePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
video_inputFilePath = [video_inputFilePath stringByAppendingPathComponent:#"movie1.mp4"];
self.outputFilePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"/Documents/OutPutMovie-%#.mp4",[NSDate date]]];
NSURL * outputFileUrl = [NSURL fileURLWithPath:self.outputFilePath];
if (audio_inputFileUrl) {
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSURL * video_inputFileUrl = [NSURL fileURLWithPath:video_inputFilePath];
CMTime nextClipStartTime = kCMTimeZero;
AVURLAsset * videoAsset = [[AVURLAsset alloc]initWithURL:video_inputFileUrl options:nil];
NSArray * videoAssetTracks2 = [videoAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack * videoAssetTrack2 = ([videoAssetTracks2 count] > 0 ? [videoAssetTracks2 objectAtIndex:0] : nil);
CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero,videoAsset.duration);
AVMutableCompositionTrack * a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:videoAssetTrack2 atTime:nextClipStartTime error:nil];
AVURLAsset * audioAsset = [[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil];
NSArray * videoAssetTracks = [audioAsset tracksWithMediaType:AVMediaTypeAudio];
AVAssetTrack * videoAssetTrack = ([videoAssetTracks count] > 0 ? [videoAssetTracks objectAtIndex:0] : nil);
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration);
AVMutableCompositionTrack * b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:videoAssetTrack atTime:nextClipStartTime error:nil];
AVAssetExportSession * _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
_assetExport.outputFileType = #"com.apple.quicktime-movie";
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
if (AVAssetExportSessionStatusCompleted == _assetExport.status) {
[videoAsset release];
[audioAsset release];
[_assetExport release];
[self performSelectorOnMainThread:#selector(moveNextView) withObject:nil waitUntilDone:YES];
}
}
];
-(void)mergeAndSave
{
//Create AVMutableComposition Object which will hold our multiple AVMutableCompositionTrack or we can say it will hold our video and audio files.
AVMutableComposition* mixComposition = [AVMutableComposition composition];
//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:#"kick" ofType:#"mp3"]];
self.audioAsset = [[AVURLAsset alloc]initWithURL:audio_url options:nil];
CMTimeRange audio_timeRange = CMTimeRangeMake(kCMTimeZero, self.audioAsset.duration);
//Now we are creating the first AVMutableCompositionTrack containing our audio and add it to our AVMutableComposition object.
AVMutableCompositionTrack *b_compositionAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[b_compositionAudioTrack insertTimeRange:audio_timeRange ofTrack:[[self.audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
//Now we will load video file.
NSURL *video_url = mediaUrl;
self.videoAsset = [[AVURLAsset alloc]initWithURL:video_url options:nil];
CMTimeRange video_timeRange = CMTimeRangeMake(kCMTimeZero,self.audioAsset.duration);
//Now we are creating the second AVMutableCompositionTrack containing our video and add it to our AVMutableComposition object.
AVMutableCompositionTrack *a_compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[a_compositionVideoTrack insertTimeRange:video_timeRange ofTrack:[[self.videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
//decide the path where you want to store the final video created with audio and video merge.
NSArray *dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsDir = [dirPaths objectAtIndex:0];
NSString *outputFilePath = [docsDir stringByAppendingPathComponent:[NSString stringWithFormat:#"video.mov"]];
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:AVAssetExportPresetHighestQuality];
_assetExport.outputFileType = #"com.apple.quicktime-movie";
_assetExport.outputURL = outputFileUrl;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
dispatch_async(dispatch_get_main_queue(), ^{
[self exportDidFinish:_assetExport];
});
}
];
}
- (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, nil];
[alert show];
}else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Video Saved" message:#"Saved To Photo Album" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
//[self loadMoviePlayer:outputURL];
}
});
}];
}
}
self.audioAsset = nil;
self.videoAsset = nil;
//[activityView stopAnimating];
//[activityView setHidden:YES];
}
try this
I believe you have to use AVMutableAudioMix in order to do a mixing of more than one audio. With your approach only the audioAsset gets added to the composition. There is a video about this in WWDC 2010, which explains how to do this. I have tried to implement without success here. Hopefully someone will help us fix it.
I am developing a video recording application and I would like to be able to integrate a music file selected by the user from the iPod library. Please share your inputs as to how I can achieve this requirement. Sample code is helpful.
Finally succeeded Integrate a selected music file into video
Using AVAssetExportSession we can merge Video and audio together using AVMutableComposition.
Thanks for update all of you!!
//This method merges the audio and video.
- (void)mergeAudioAtUrl:(NSURL *)audioUrl withVideoAtUrl:(NSURL *)videoUrl toUrl:(NSURL *)outputUrl
{
//_imageCaptureCount = [_imagesArray count]*100;
AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];
AVMutableComposition* mixComposition = [AVMutableComposition composition];
if([[audioAsset tracksWithMediaType:AVMediaTypeAudio] count])
{
AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
}
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
atTime:kCMTimeZero error:nil];
[audioAsset release];
[videoAsset release];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition
presetName:AVAssetExportPresetPassthrough];
NSURL *exportUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/Documents/%#Video.mp4", NSHomeDirectory(),pcNameString]];
if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:#"%#/Documents/%#Video.mp4", NSHomeDirectory(),pcNameString]])
{
[[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:#"%#/Documents/%#Video.mp4", NSHomeDirectory(),pcNameString] error:nil];
}
_assetExport.outputFileType = #"com.apple.quicktime-movie"; //com.apple.m4v-video
_assetExport.outputURL = exportUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void ) {
// your completion code here
// NSLog(#"completed");
removeProgresBarFlag = YES;
/* NSString* savedVideoFilePath = [NSString stringWithFormat:#"%#/Documents/PC%d.mp4", NSHomeDirectory(),[videosListArray count]];
if(UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(savedVideoFilePath))
{
[[UIApplication sharedApplication]beginIgnoringInteractionEvents];
UISaveVideoAtPathToSavedPhotosAlbum(savedVideoFilePath, self, nil, nil);
[[UIApplication sharedApplication]endIgnoringInteractionEvents];
} */
NSMutableDictionary* videoDetailDict = [[NSMutableDictionary alloc] initWithCapacity:0];
NSStringEncoding encoding;
NSError* error;
NSString * persistentID;
NSFileManager* fileManager = [NSFileManager defaultManager];
if([fileManager fileExistsAtPath:PRESENTSONGS_FILE_PATH])
persistentID = [NSString stringWithContentsOfFile:PRESENTSONGS_FILE_PATH usedEncoding:&encoding error:&error];
else
persistentID = #"";
[videoDetailDict setObject:persistentID forKey:KSong];
if([fileManager fileExistsAtPath:PRESENTIMAGES_FILE])
{
NSMutableArray* currentImagesArray = [[NSMutableArray alloc] initWithContentsOfFile:IMAGESDATA_FILE_PATH];
NSMutableArray* durationArray = [[NSMutableArray alloc] initWithContentsOfFile:[NSString stringWithFormat:#"%#/videoduration.plist", [[NSBundle mainBundle] resourcePath]]];
[videoDetailDict setObject:[durationArray objectAtIndex:[currentImagesArray count]-1] forKey:KfileSize];
[durationArray release];
[videoDetailDict setObject:currentImagesArray forKey:KImagesList];
if([fileManager fileExistsAtPath:TEMPVIDEO_FILE_PATH])
[fileManager removeItemAtPath:TEMPVIDEO_FILE_PATH error:nil];
NSString* mainPath;
mainPath = [NSString stringWithFormat:#"%#/Documents/%#File",NSHomeDirectory(),pcNameString];
if([fileManager fileExistsAtPath:mainPath])
[fileManager removeItemAtPath:mainPath error:nil];
[fileManager createDirectoryAtPath:mainPath withIntermediateDirectories:NO attributes:nil error:nil];
for(int i=0;i<[currentImagesArray count];i++)
{
[fileManager copyItemAtPath:[NSString stringWithFormat:#"%#%#",PRESENTIMAGES_FILE,[currentImagesArray objectAtIndex:i]] toPath:[NSString stringWithFormat:#"%#/%#",mainPath,[currentImagesArray objectAtIndex:i]] error:nil];
}
[currentImagesArray release];
}
if([fileManager fileExistsAtPath:KMESSAGE_FILEPATH])
{
NSMutableDictionary* currentMessageDictioanry = [[NSMutableDictionary alloc] initWithContentsOfFile:KMESSAGE_FILEPATH];
[videoDetailDict setObject:currentMessageDictioanry forKey:Kmessage];
[currentMessageDictioanry release];
}
[videoDetailDict setObject:pcNameString forKey:KPostCardName]; //[NSString stringWithFormat:#"PostCard Video%d",[videosListArray count]]
//[videosListArray insertObject:videoDetailDict atIndex:0];
[videosListArray addObject:videoDetailDict];
[videoDetailDict release];
[videosListArray writeToFile:VIDEOS_FILE_PATH atomically:YES];
}
];
}
I want to merge an Audion CAF file and a video/image UIImage to create a movie file (in .mov format).
Say that my audio is 30 seconds long and I have a UIImage; I want to create a .mov file such that the UIImage is displayed the entire time the audio is playing.
I found this reference:
How to add audio to video file on iphone SDK
Can anyone tell me, is it helpful in my case, since the length of my audio and image/video is different?
Thanks in advance.
Yes, you should use AVMutableComposition. To create the video track from your UIImage use AVAssetWriter.
Quicktime Pro can do this. Done that for my own app.
You create the movie from the images. Quicktime offers to read a sequence of images and creates a movie from it. He ask for the FPS during import as well.
The audio track can then simply merged, pasted somewhere or scaled to a selected range of the movie.
use this i found this somewhere in net, i don't remember,....
NSString *fileNamePath = #"audio.caf";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *oldappSettingsPath = [documentsDirectory stringByAppendingPathComponent:fileNamePath];
NSURL *audioUrl = [NSURL fileURLWithPath:oldappSettingsPath];
NSString *fileNamePath1 = #"output.mp4";
NSArray *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths1 objectAtIndex:0];
NSString *oldappSettingsPath1 = [documentsDirectory1 stringByAppendingPathComponent:fileNamePath1];
NSLog(#"oldpath=%#",oldappSettingsPath);
NSURL *videoUrl = [NSURL fileURLWithPath:oldappSettingsPath1];
if (avPlayer.duration >0.00000)
{
NSLog(#"SOMEDATA IS THERE ");
AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
AVURLAsset* videoAsset = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];
AVMutableComposition* mixComposition = [AVMutableComposition composition];
NSLog(#"audio =%#",audioAsset);
AVMutableCompositionTrack *compositionCommentaryTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionCommentaryTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:[[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0] atTime:kCMTimeZero error:nil];
AVMutableCompositionTrack *compositionVideoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration) ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] atTime:kCMTimeZero error:nil];
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetPassthrough];
NSString* videoName = #"export.mov";
NSString *exportPath = [NSTemporaryDirectory() stringByAppendingPathComponent:videoName];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
{
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
_assetExport.outputFileType = #"com.apple.quicktime-movie";
NSLog(#"file type %#",_assetExport.outputFileType);
_assetExport.outputURL = exportUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void )
{
NSString *fileNamePath = #"sound_record.mov";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *oldappSettingsPath = [documentsDirectory stringByAppendingPathComponent:fileNamePath];
// if ([[NSFileManager defaultManager] fileExistsAtPath:oldappSettingsPath]) {
//
// NSFileManager *fileManager = [NSFileManager defaultManager];
// [fileManager removeItemAtPath: oldappSettingsPath error:NULL];
//
// }
NSURL *documentDirectoryURL = [NSURL fileURLWithPath:oldappSettingsPath];
[[NSFileManager defaultManager] copyItemAtURL:exportUrl toURL:documentDirectoryURL error:nil];
[audioAsset release];
[videoAsset release];
[_assetExport release];
}
];