Skip to content

Instantly share code, notes, and snippets.

@jayeshk
Created January 19, 2017 11:54
Show Gist options
  • Save jayeshk/6519a47fbd00e61a88eb392f4996579d to your computer and use it in GitHub Desktop.
Save jayeshk/6519a47fbd00e61a88eb392f4996579d to your computer and use it in GitHub Desktop.
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
//typedef (^AudioWriteComplection)(Bool, NSError);
@interface AVAsset (AudiExtract)
- (void)writeAudioTrack:(NSURL *)url complection:(void (^)(BOOL, NSError *))completion;
- (void)extractAudioFromVideo:(NSURL*)videoSrcPath audioFilePath:(NSString*)dstPath complection:(void (^)(BOOL, NSError *))completion;
- (NSURL *)documentFileWithExt:(NSString *)ext;
@end
@interface ViewController ()
@property (nonatomic, strong) NSURL *storedVideo;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL* videoURL = [[NSBundle mainBundle] URLForResource:@"demo" withExtension:@"mp4"];;
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
ALAssetsLibraryWriteVideoCompletionBlock completionBlock =
^(NSURL *savedURL, NSError *error) {
if (error) {
NSLog( @"Error while saving video Photo Library: %@", error );
} else {
NSLog( @"Successfuly saved video to Photo Library %@", savedURL.absoluteString);
self.storedVideo = savedURL;
[self processAudio:self.storedVideo];
}
};
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:videoURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:videoURL completionBlock:completionBlock];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)processAudio:(NSURL *)url
{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
NSURL *outputUrl = [asset documentFileWithExt:@"m4a"];
NSLog(@"Storing at %@", outputUrl.absoluteString);
[asset writeAudioTrack:outputUrl complection:^(BOOL success, NSError *error) {
if( success)
{
NSLog(@"...E.X.P.O.R.T.E.D...");
}
else
{
NSLog(@"...F.A.I.L...");
}
}];
/*
[asset extractAudioFromVideo:url audioFilePath:fileName complection:^(BOOL success, NSError *error) {
if(success)
{
NSLog(@"Second approch...E.X.P.O.R.T.E.D...");
}
else
{
NSLog(@"Second approch...F.A.I.L...");
}
}];
*/
}
@end
@implementation AVAsset (AudiExtract)
- (NSURL *)documentFileWithExt:(NSString *)ext
{
NSArray *arr = [[NSFileManager defaultManager] URLsForDirectory: NSDocumentDirectory
inDomains: NSUserDomainMask];
NSURL *documentsUrl = [arr firstObject];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"YYYYMMddHHmmss";
NSString *fileName = [NSString stringWithFormat:@"output_%@.%@", [formatter stringFromDate:[NSDate new]], ext];
NSURL *outputUrl = [documentsUrl URLByAppendingPathComponent:fileName];
return outputUrl;
}
- (void)writeAudioTrack:(NSURL *)url complection:(void (^)(BOOL, NSError *))completion;
{
AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:self presetName:AVAssetExportPresetAppleM4A];
if(session != nil)
{
session.outputFileType = AVFileTypeAppleM4A;
session.outputURL = url;
session.timeRange = CMTimeRangeMake(kCMTimeZero, [self duration]);
[session exportAsynchronouslyWithCompletionHandler:^{
if(session.status == AVAssetExportSessionStatusCompleted)
{
NSLog(@"Completed..");
completion(true, nil);
}
else if (session.status == AVAssetExportSessionStatusExporting)
{
NSLog(@"Exporting...");
}
else
{
NSLog(@"Export Failed status = %ld", (long)session.status);
completion(false, nil);
}
}];
}
else
{
NSLog(@"Failed to create session");
completion(false, nil);
}
}
- (void)extractAudioFromVideo:(NSURL*)videoSrcPath audioFilePath:(NSString*)dstPath complection:(void (^)(BOOL, NSError *))completion
{
AVMutableComposition* newAudioAsset = [AVMutableComposition composition];
AVMutableCompositionTrack* dstCompositionTrack;
dstCompositionTrack = [newAudioAsset addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
//NSURL *srcURL=[NSURL fileURLWithPath:videoSrcPath];
NSURL *srcURL=videoSrcPath;
AVAsset* srcAsset = [AVURLAsset URLAssetWithURL:srcURL options:nil];
AVAssetTrack* srcTrack = [[srcAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
NSArray *formatDescriptions=srcTrack.formatDescriptions;
NSString *fileType = nil;
NSString *ex = nil;
if ([formatDescriptions count] > 0)
{
CMAudioFormatDescriptionRef formatDesc=(__bridge CMFormatDescriptionRef)[formatDescriptions objectAtIndex:0];
FourCharCode mediaSubType = CMFormatDescriptionGetMediaSubType(formatDesc);
NSLog(@"mediaSubType>>%u",(unsigned int)mediaSubType);
const AudioStreamBasicDescription * asbd=CMAudioFormatDescriptionGetStreamBasicDescription(formatDesc);
FourCharCode formatID = asbd->mFormatID;
NSLog(@"formatID>>%u",(unsigned int)mediaSubType);
switch (formatID) {
case kAudioFormatLinearPCM:
{
UInt32 flags = asbd->mFormatFlags;
if (flags & kAudioFormatFlagIsBigEndian) {
fileType = @"public.aiff-audio";
ex = @"aif";
} else {
fileType = @"com.microsoft.waveform-audio";
ex = @".wav";
}
}
break;
case kAudioFormatMPEGLayer3:
fileType = @"com.apple.quicktime-movie";
ex = @".mp3";
break;
case kAudioFormatMPEG4AAC:
fileType = @"com.apple.m4a-audio";
ex = @".m4a";
break;
case kAudioFormatAppleLossless:
fileType = @"com.apple.m4a-audio";
ex = @".m4a";
break;
default:
break;
}
}
NSURL *outputUrl = [self documentFileWithExt:@"m4a"];
[[NSFileManager defaultManager] removeItemAtURL:outputUrl error:nil];
CMTimeRange timeRange = srcTrack.timeRange;
NSError* error;
if(NO == [dstCompositionTrack insertTimeRange:timeRange ofTrack:srcTrack atTime:kCMTimeZero error:&error]) {
NSLog(@"track insert failed: %@\n", error);
return;
}
AVAssetExportSession* exportSesh = [[AVAssetExportSession alloc] initWithAsset:newAudioAsset presetName:AVAssetExportPresetPassthrough];
exportSesh.outputFileType = fileType;
exportSesh.outputURL = outputUrl;
[exportSesh exportAsynchronouslyWithCompletionHandler:^{
AVAssetExportSessionStatus status = exportSesh.status;
NSLog(@"exportAsynchronouslyWithCompletionHandler: %li\n", (long)status);
if(AVAssetExportSessionStatusFailed == status) {
dispatch_async(dispatch_get_main_queue(), ^(void){
completion(false,nil);
});
NSLog(@"FAILURE: %@\n", exportSesh.error);
} else if(AVAssetExportSessionStatusCompleted == status) {
dispatch_async(dispatch_get_main_queue(), ^(void){
completion(true,nil);
});
}
}];
}
@end
Copy link

ghost commented Jan 19, 2017

nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment