I've been trying to extract audio from a .mov file for a while now and I just can't seem to get it working. Specifically, I need to extract the audio and save it as an .aif or .aiff file .
I've tried using an AVMutableComposition, and loading the mov file as a AVAsset. Adding only the audio track to the AVMutableComposition before finally using an AVAssetExportSession (setting the output file type to AVFileTypeAIFF, which is the format I need it in), to write the file to an aif.
I get an error saying that this output file type is invalid, I'm unsure why:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid output file type'
AVAssetExportSession *exporter;
exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality] ;
exporter.audioMix = audioMix;
exporter.outputURL=[NSURL fileURLWithPath:filePath];
exporter.outputFileType=AVFileTypeAIFF; //Error occurs on this line
I'm not sure if the above approach would work, but im open to the possibility that I'm just doing something wrong. However if anyone knows another way to accomplish what I'm trying to achieve, than any help would be greatly appreciated.
I can post more detailed code if it is needed, but at the moment I'm trying a few other approaches so its a bit messy right now.
Thanks for the help!
-(void)getAudioFromVideo {
float startTime = 0;
float endTime = 10;
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *audioPath = [documentsDirectory stringByAppendingPathComponent:@"soundOneNew.m4a"];
AVAsset *myasset = [AVAsset assetWithURL:[[NSBundle mainBundle] URLForResource:@"VideoName" withExtension:@"mp4"]];
AVAssetExportSession *exportSession=[AVAssetExportSession exportSessionWithAsset:myasset presetName:AVAssetExportPresetAppleM4A];
exportSession.outputURL=[NSURL fileURLWithPath:audioPath];
exportSession.outputFileType=AVFileTypeAppleM4A;
CMTime vocalStartMarker = CMTimeMake((int)(floor(startTime * 100)), 100);
CMTime vocalEndMarker = CMTimeMake((int)(ceil(endTime * 100)), 100);
CMTimeRange exportTimeRange = CMTimeRangeFromTimeToTime(vocalStartMarker, vocalEndMarker);
exportSession.timeRange= exportTimeRange;
if ([[NSFileManager defaultManager] fileExistsAtPath:audioPath]) {
[[NSFileManager defaultManager] removeItemAtPath:audioPath error:nil];
}
[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status==AVAssetExportSessionStatusFailed) {
NSLog(@"failed");
}
else {
NSLog(@"AudioLocation : %@",audioPath);
}
}];
}
Because the outputFileType is wrong. For .mov file, it often is @"com.apple.quicktime-movie". And the audio extracted is .mov format. To make sure, you can use this method to get the supported output type:
NSArray *supportedTypeArray=exportSession.supportedFileTypes;
for (NSString *str in supportedTypeArray)
NSLog(@"%@",str);
And you can export audio in audio format (.m4a, can be played by AVAudioPlayer) by using methods like this:
AVAssetExportSession *exportSession=[AVAssetExportSession exportSessionWithAsset:self.mAsset presetName:AVAssetExportPresetAppleM4A];
exportSession.outputURL=myUrl;
exportSession.outputFileType=AVFileTypeAppleM4A;
exportSession.timeRange=timeRange;
[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status==AVAssetExportSessionStatusFailed) {
NSLog(@"failed");
}
}];
Just small info for others (I did not know that..)
If you have video file(in my case it was mp4),You can play only the audio with AVAudioPlayer.
You don't need to extract(or convert) the audio from the video.