6

I managed it to download a youtube video using NSUrlConnection and save it to the device. Now I want to convert this (I guess .mp4) file to an .mp3 audio file. Does anyone know a solution for this problem? Maybe there's a way to only download the audio from the video? This would save a lot of time.

Toseef Khilji
  • 17,192
  • 12
  • 80
  • 121
Valle
  • 67
  • 1
  • 4
  • I don't think so its duplicate. As there is no accepted answer in so called original question. – Alok C Jan 22 '16 at 17:29

1 Answers1

7

First of all, you don't want to convert anything, that's slow. Instead you want to extract the audio stream from the mp4 file. You can do this by creating an AVMutableComposition containing only the audio track of the original file and then exporting the composition with an AVAssetExportSession. This is currently m4a centric. If you want to handle both m4a and mp3 output, check the audio track type, make sure to set the right file extension and choose between AVFileTypeMPEGLayer3 or AVFileTypeAppleM4A in the export session.

    NSURL*      dstURL = [NSURL fileURLWithPath:dstPath];
    [[NSFileManager defaultManager] removeItemAtURL:dstURL error:nil];

    AVMutableComposition*   newAudioAsset = [AVMutableComposition composition];

    AVMutableCompositionTrack*  dstCompositionTrack;
    dstCompositionTrack = [newAudioAsset addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];


    AVAsset*    srcAsset = [AVURLAsset URLAssetWithURL:srcURL options:nil];
    AVAssetTrack*   srcTrack = [[srcAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];


    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 = AVFileTypeAppleM4A;
    exportSesh.outputURL = dstURL;

    [exportSesh exportAsynchronouslyWithCompletionHandler:^{
        AVAssetExportSessionStatus  status = exportSesh.status;
        NSLog(@"exportAsynchronouslyWithCompletionHandler: %i\n", status);

        if(AVAssetExportSessionStatusFailed == status) {
            NSLog(@"FAILURE: %@\n", exportSesh.error);
        } else if(AVAssetExportSessionStatusCompleted == status) {
            NSLog(@"SUCCESS!\n");
        }
    }];
Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159