iOS Audio Trimming - ios

I searched a lot and couldn't find anything relevant... I am working on iOS audio files and here is what I want to do...
Record Audio and Save Clip (Checked, I did this using AVAudioRecorder)
Change the pitch (Checked, Did this using Dirac)
Trimming :(
I have two markers i.e. starting & ending offset and using this info I want to trim recorded file and want to save it back. I don't want to use "seek" because later on I want to play all recorded files in sync (just like flash movie clips in timeline) and then finally I want to export as one audio file.

Here's the code that I've used to trim audio from a pre-existing file. You'll need to change the M4A related constants if you've saved or are saving to another format.
- (BOOL)trimAudio
{
float vocalStartMarker = <starting time>;
float vocalEndMarker = <ending time>;
NSURL *audioFileInput = <your pre-existing file>;
NSURL *audioFileOutput = <the file you want to create>;
if (!audioFileInput || !audioFileOutput)
{
return NO;
}
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
presetName:AVAssetExportPresetAppleM4A];
if (exportSession == nil)
{
return NO;
}
CMTime startTime = CMTimeMake((int)(floor(vocalStartMarker * 100)), 100);
CMTime stopTime = CMTimeMake((int)(ceil(vocalEndMarker * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.outputURL = audioFileOutput;
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^
{
if (AVAssetExportSessionStatusCompleted == exportSession.status)
{
// It worked!
}
else if (AVAssetExportSessionStatusFailed == exportSession.status)
{
// It failed...
}
}];
return YES;
}
There's also Technical Q&A 1730, which gives a slightly more detailed approach.

import following two libraries in .m
#import "BJRangeSliderWithProgress.h"
#import < AVFoundation/AVFoundation.h >
and after that paste following code you will be able to trim an audio file with the help of two thumbs.
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
mySlider = [[BJRangeSliderWithProgress alloc] initWithFrame:CGRectMake(20, 100, 300, 50)];
[mySlider setDisplayMode:BJRSWPAudioSetTrimMode];
[mySlider addTarget:self action:#selector(valueChanged) forControlEvents:UIControlEventValueChanged];
[mySlider setMinValue:0.0];
NSString *strInputFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"saewill.mp3"];
NSURL *audioFileInput = [NSURL fileURLWithPath:strInputFilePath];
audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:audioFileInput error:nil];
[mySlider setMaxValue:audioPlayer.duration];
[self.view addSubview:mySlider];
}
-(void)valueChanged {
NSLog(#"%f %f", mySlider.leftValue, mySlider.rightValue);
}
-(IBAction)playTheSong
{
// Path of your source audio file
NSString *strInputFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"saewill.mp3"];
NSURL *audioFileInput = [NSURL fileURLWithPath:strInputFilePath];
// Path of your destination save audio file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryCachesDirectory = [paths objectAtIndex:0];
//libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:#"Caches"];
NSString *strOutputFilePath = [libraryCachesDirectory stringByAppendingPathComponent:#"output.mov"];
NSString *requiredOutputPath = [libraryCachesDirectory stringByAppendingPathComponent:#"output.m4a"];
NSURL *audioFileOutput = [NSURL fileURLWithPath:requiredOutputPath];
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
presetName:AVAssetExportPresetAppleM4A];
float startTrimTime = mySlider.leftValue;
float endTrimTime = mySlider.rightValue;
CMTime startTime = CMTimeMake((int)(floor(startTrimTime * 100)), 100);
CMTime stopTime = CMTimeMake((int)(ceil(endTrimTime * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.outputURL = audioFileOutput;
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^
{
if (AVAssetExportSessionStatusCompleted == exportSession.status)
{
NSLog(#"Success!");
NSLog(#" OUtput path is \n %#", requiredOutputPath);
NSFileManager * fm = [[NSFileManager alloc] init];
[fm moveItemAtPath:strOutputFilePath toPath:requiredOutputPath error:nil];
//[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
NSURL *url=[NSURL fileURLWithPath:requiredOutputPath];
NSError *error;
audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops=0;
[audioPlayer play];
}
else if (AVAssetExportSessionStatusFailed == exportSession.status)
{
NSLog(#"failed with error: %#", exportSession.error.localizedDescription);
}
}];
}

// Swift 4.2
If anybody is still looking for answer in swift here it is.
//Audio Trimming
func trimAudio(asset: AVAsset, startTime: Double, stopTime: Double, finished:#escaping (URL) -> ())
{
let compatiblePresets = AVAssetExportSession.exportPresets(compatibleWith:asset)
if compatiblePresets.contains(AVAssetExportPresetMediumQuality) {
guard let exportSession = AVAssetExportSession(asset: asset,
presetName: AVAssetExportPresetAppleM4A) else{return}
// Creating new output File url and removing it if already exists.
let furl = createUrlInAppDD("trimmedAudio.m4a") //Custom Function
removeFileIfExists(fileURL: furl) //Custom Function
exportSession.outputURL = furl
exportSession.outputFileType = AVFileType.m4a
let start: CMTime = CMTimeMakeWithSeconds(startTime, preferredTimescale: asset.duration.timescale)
let stop: CMTime = CMTimeMakeWithSeconds(stopTime, preferredTimescale: asset.duration.timescale)
let range: CMTimeRange = CMTimeRangeFromTimeToTime(start: start, end: stop)
exportSession.timeRange = range
exportSession.exportAsynchronously(completionHandler: {
switch exportSession.status {
case .failed:
print("Export failed: \(exportSession.error!.localizedDescription)")
case .cancelled:
print("Export canceled")
default:
print("Successfully trimmed audio")
DispatchQueue.main.async(execute: {
finished(furl)
})
}
})
}
}
You can use it for video trimming as well. For Video trimming replace the value of export session as bellow:
guard let exportSession = AVAssetExportSession(asset: asset,
presetName: AVAssetExportPresetPassthrough) else{return}
and filetype to mp4
exportSession.outputFileType = AVFileType.mp4

Here is a sample code which trim audio file from starting & ending offset and save it back.
Please check this iOS Audio Trimming.
// Path of your source audio file
NSString *strInputFilePath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"abc.mp3"];
NSURL *audioFileInput = [NSURL fileURLWithPath:strInputFilePath];
// Path of your destination save audio file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *libraryCachesDirectory = [paths objectAtIndex:0];
libraryCachesDirectory = [libraryCachesDirectory stringByAppendingPathComponent:#"Caches"];
NSString *strOutputFilePath = [NSString stringWithFormat:#"%#%#",libraryCachesDirectory,#"/abc.mp4"];
NSURL *audioFileOutput = [NSURL fileURLWithPath:strOutputFilePath];
if (!audioFileInput || !audioFileOutput)
{
return NO;
}
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset presetName:AVAssetExportPresetAppleM4A];
if (exportSession == nil)
{
return NO;
}
float startTrimTime = 0;
float endTrimTime = 5;
CMTime startTime = CMTimeMake((int)(floor(startTrimTime * 100)), 100);
CMTime stopTime = CMTimeMake((int)(ceil(endTrimTime * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.outputURL = audioFileOutput;
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^
{
if (AVAssetExportSessionStatusCompleted == exportSession.status)
{
NSLog(#"Success!");
}
else if (AVAssetExportSessionStatusFailed == exportSession.status)
{
NSLog(#"failed");
}
}];

Related

Objective C/IOS - AVAsset - Error

I'm trying to use the following code to save a snippet of audio from a url stream (e.g., a radio station broadcast):
float vocalStartMarker = 0.0;
float vocalEndMarker = 20.0;
NSURL *audioFileInput = [[NSURL alloc] initWithString: #"http://streamedaudio.mp3"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"TestName.m4a"]; //Add the file name
//[audioFileInput writeToFile:filePath atomically:YES]; //Write the file
NSURL *audioFileOutput = [[NSURL alloc] initWithString: filePath];
NSLog(#"%#", audioFileOutput);
if (!audioFileInput || !audioFileOutput)
{
return NO;
}
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVAsset *asset = [AVAsset assetWithURL:audioFileInput];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
presetName:AVAssetExportPresetAppleM4A];
if (exportSession == nil)
{
return NO;
}
CMTime startTime = CMTimeMake((int)(floor(vocalStartMarker * 100)), 100);
CMTime stopTime = CMTimeMake((int)(ceil(vocalEndMarker * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.outputURL = audioFileOutput;
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^
{
if (AVAssetExportSessionStatusCompleted == exportSession.status)
{
// It worked!
}
else if (AVAssetExportSessionStatusFailed == exportSession.status)
{
NSLog(#"%#", exportSession.error);
return;
}
}];
I get the following error:
2015-12-26 14:17:11.523 SaveURL[4135:24621] Error Domain=AVFoundationErrorDomain Code=-11838 "Operation Stopped" UserInfo={NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The operation is not supported for this media.}
Is this because i'm trying to convert an MP3 to M4A?
Thanks in advance for your help with this.
Application Transport Security restricts requests to HTTPS unless you explicitly allow it.

+ exportSessionWithAsset:presetName: returning nil on iOS7

I'm using the following code:
- (AVAssetExportSession *)testRecording
{
AVMutableComposition *composition = [[AVMutableComposition alloc] init];
NSURL *url = [[NSBundle mainBundle] URLForResource:kTestSongName withExtension:#"mp3"];
AVAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
CMTimeRange range = CMTimeRangeMake(CMTimeMake(0, 600), asset.duration);
NSError *editError;
BOOL result = [composition insertTimeRange:range ofAsset:asset atTime:kCMTimeZero error:&editError];
if (!result) {
NSLog(#"Error inserting timerange");
}
AVAssetExportSession *exportSession = [AVAssetExportSession
exportSessionWithAsset:composition
presetName:AVAssetExportPresetAppleM4A];
return exportSession;
}
This does what it's supposed to on iOS8 but on iOS7 exportSession is always nil at the end of the method. I tried using assets with different formats (mp3, caf) but the result was the same.
If I play the composition instead of exporting it the sound is fine:
AVPlayerItem * item = [[AVPlayerItem alloc] initWithAsset:composition];
AVPlayer * player = [AVPlayer playerWithPlayerItem:item];
[player play];
Any idea about what might be wrong?
exportSession = [[AVAssetExportSession alloc]
initWithAsset:songAsset
presetName:AVAssetExportPresetAppleM4A];
exportSession.outputFileType = #"com.apple.m4a-audio";
filePath = [[docDir stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:#"m4a.mov"]
exportSession.outputURL = [NSURL fileURLWithPath:filePath];
[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
NSString *newPath = [NSString stringWithFormat:#"%#/%#", documentDirectory, [[[filePath lastPathComponent] substringToIndex:[[filePath lastPathComponent] length]-5] stringByAppendingString:#"a"]];
[[NSFileManager defaultManager] removeItemAtPath:newPath error:nil];
NSError *error = nil;
[[NSFileManager defaultManager] moveItemAtPath:filePath toPath:newPath error:&error];
}
if (exportSession.status == AVAssetExportSessionStatusCancelled) {
}
if (exportSession.status == AVAssetExportSessionStatusExporting) {
}
if (exportSession.status == AVAssetExportSessionStatusFailed) {
NSLog(#"erros:%#",exportSession.error);
}
if (exportSession.status == AVAssetExportSessionStatusUnknown) {
}
if (exportSession.status == AVAssetExportSessionStatusWaiting) {
}
}];
If you want to save in mp3 format, use ffmpeg.

Cutting video on iPhone

I have a video file from the device camera -- stored as /private/var/mobile/Media/DCIM/100APPLE/IMG_0203.MOV, for example, and I need to cut the first 10 seconds of this video. What API or libraries I can use?
I found solution with standard API: AVAssetExportSession
- (void)getTrimmedVideoForFile:(NSString *)filePath withInfo:(NSArray *)info
{
//[[NSFileManager defaultManager] removeItemAtURL:outputURL error:nil];
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:filePath] options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetLowQuality];
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);
// NSString *outputURL = paths[0];
NSFileManager *manager = [NSFileManager defaultManager];
// [manager createDirectoryAtPath:outputURL withIntermediateDirectories:YES attributes:nil error:nil];
// outputURL = [outputURL stringByAppendingPathComponent:#"output.mp4"];
NSString *outputURL = [NSString stringWithFormat:#"/tmp/%#.mp4", [info objectAtIndex:2]];
NSLog(#"OUTPUT: %#", outputURL);
// Remove Existing File
// [manager removeItemAtPath:outputURL error:nil];
if (![manager fileExistsAtPath:outputURL]) {
exportSession.outputURL = [NSURL fileURLWithPath:outputURL];
exportSession.shouldOptimizeForNetworkUse = YES;
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
CMTime start = kCMTimeZero;
CMTime duration = kCMTimeIndefinite;
if ([[NSString stringWithFormat:#"%#", [info objectAtIndex:3]] floatValue] > 20.0) {
start = CMTimeMakeWithSeconds(1.0, 600);
duration = CMTimeMakeWithSeconds(10.0, 600);
}
CMTimeRange range = CMTimeRangeMake(start, duration);
exportSession.timeRange = range;
[exportSession exportAsynchronouslyWithCompletionHandler:^(void) {
switch (exportSession.status) {
case AVAssetExportSessionStatusCompleted:
NSLog(#"Export Complete %d %#", exportSession.status, exportSession.error);
[self sendVideoPreview:info];
break;
case AVAssetExportSessionStatusFailed:
NSLog(#"Failed:%#",exportSession.error);
// [self addToDelayed:info withAction:#"add"];
break;
case AVAssetExportSessionStatusCancelled:
NSLog(#"Canceled:%#",exportSession.error);
// [self addToDelayed:info withAction:#"add"];
break;
default:
break;
}
}];
} else {
[self sendVideoPreview:info];
}

Objective - C, how do I crop .caf file?

I've recorded sound into .caf file using AVAudioRecorder.
I want to cut/trim first 2 seconds of this file.
How to do that? (I've spent hours to find the solution, but no luck)
You can do this with AVAssetExportSession..
Try this code..
float vocalStartMarker = 0.0f;
float vocalEndMarker = 2.0f;
NSURL *audioFileInput = #"input filePath"; // give your audio file path
NSString *docsDirs;
NSArray *dirPath;
dirPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDirs = [dirPath objectAtIndex:0];
NSString *destinationURLs = [docsDirs stringByAppendingPathComponent:#"trim.caf"];
audioFileOutput = [NSURL fileURLWithPath:destinationURLs];
if (!audioFileInput || !audioFileOutput)
{
return NO;
}
[[NSFileManager defaultManager] removeItemAtURL:audioFileOutput error:NULL];
AVAsset *asset = [AVURLAsset URLAssetWithURL:audioFileInput options:nil];
AVAssetExportSession *exportSession = [AVAssetExportSession exportSessionWithAsset:asset
presetName:AVAssetExportPresetAppleM4A];
if (exportSession == nil)
{
return NO;
}
CMTime startTime = CMTimeMake((int)(floor(vocalStartMarker * 100)), 100);
CMTime stopTime = CMTimeMake((int)(ceil(vocalEndMarker * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(startTime, stopTime);
exportSession.outputURL = audioFileOutput;
exportSession.outputFileType = AVFileTypeAppleM4A;
exportSession.timeRange = exportTimeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^
{
if (AVAssetExportSessionStatusCompleted == exportSession.status)
{
// It worked!
NSLog(#"DONE TRIMMING.....");
NSLog(#"ouput audio trim file %#",audioFileOutput);
}
else if (AVAssetExportSessionStatusFailed == exportSession.status)
{
// It failed...
NSLog(#"FAILED TRIMMING.....");
}
}];

Trim video without displaying UIVideoEditorController?

Currently I'm working on a application which deals with the videos.
In my application user can trim the video, I have a custom control for selecting the start time and end time. I need to trim the video by these two values. I tried with UIVideoEditorController like follows.
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 );
}
But the issue is the above code will display apple's video editor control and user can do some operations on that view. I don't want to display this view, because I have already displayed the video on MPMoviePlayer and received the user input (start time and end time) for trimming the video on a custom control.
How can I trim a video without displaying UIVideoEditorController ?
Finally I found the solution.
We can use AVAssetExportSession for trimming video without displaying UIVideoEditorController.
My code is like:
- (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]);
}
}
This method trims the video
- (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]);
}
}
This method checks the status of trimming:
- (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;
}
}];
}
I'm calling the splitVideo method from the export button action method and passes the output URL as argument.
We can import 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;
}

Resources