title: Extract audio from video in mp3 format
body: <p><strong>Objective:</strong> I want to extract an audio from video in mp3 format. Video can be in any iOS supported format</p>
  
  <p>I have tried the following technique to achieve the above objective and i am using lame library:</p>
  
  <p><strong>Step 1:</strong> Create an AVURLAsset object by passing source file URL to it.</p>
  
  <p><strong>Step 2:</strong> Create an AVAssetExportSession object with source asset set its outputfileType to m4a.</p>
  
  <p><strong>Step 3:</strong> Extracts its audio and after that i try to convert it into mp3 format.</p>
  
  <p><strong>Here is the code that i have used:</strong></p>
  
  <pre><code>NSURL *videoFileUrl = [NSURL fileURLWithPath:originalVideoPath];
  AVURLAsset *anAsset = [[AVURLAsset alloc] initWithURL:videoFileUrl options:nil];
  
  exportSession=[AVAssetExportSession exportSessionWithAsset:anAsset presetName:AVAssetExportPresetPassthrough];
  
  [exportSession determineCompatibleFileTypesWithCompletionHandler:^(NSArray *compatibleFileTypes) {
      NSLog(@"compatiblefiletypes: %@",compatibleFileTypes);
  }];
  
  NSURL *furl = [NSURL fileURLWithPath:tmpVideoPath];
  exportSession.outputURL = furl;
  exportSession.outputFileType=AVFileTypeAppleM4A;
  
  CMTime duration = anAsset.duration;
  CMTimeRange range = CMTimeRangeMake(kCMTimeZero, duration);
  exportSession.timeRange = range;
  
  [exportSession exportAsynchronouslyWithCompletionHandler:^{
      dispatch_async(dispatch_get_main_queue(), ^{
          [SVProgressHUD dismiss];
      });
      switch (exportSession.status)
      {
          case AVAssetExportSessionStatusCompleted:
          {
              dispatch_async(dispatch_get_main_queue(), ^{
                      [SVProgressHUD showProgress:0 status:@"Converting..." maskType:SVProgressHUDMaskTypeGradient];
                      [self performSelector:@selector(convertToMp3) withObject:nil afterDelay:0.3f];       
              });
              break;
          }
          case AVAssetExportSessionStatusFailed:
          {
              dispatch_async(dispatch_get_main_queue(), ^{
                  [MyUtility showAlertViewWithTitle:kAlertTitle msg:exportSession.error.localizedDescription];
              });
              break;
          }
          case AVAssetExportSessionStatusCancelled:
              NSLog(@"Export canceled");
              break;
          default:
  
              break;
      }
  }];
  
  __weak AVAssetExportSession *weakSession = exportSession;
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
      while (weakSession.status == AVAssetExportSessionStatusWaiting
             || weakSession.status == AVAssetExportSessionStatusExporting) {
          dispatch_sync(dispatch_get_main_queue(), ^{
              [SVProgressHUD showProgress:exportSession.progress status:@"Extracting..." maskType:SVProgressHUDMaskTypeGradient];
          });
      }
  });
  - (void)convertToMp3
  {
  NSURL *extractedAudioFileURL = [[NSURL alloc] initWithString:tmpVideoPath];
  NSError *error;
  AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:extractedAudioFileURL error:&amp;error];
  
  float noOfChannels = [[audioPlayer.settings objectForKey:AVNumberOfChannelsKey] floatValue];
  float sampleRate = [[audioPlayer.settings objectForKey:AVSampleRateKey] floatValue];
  float bitRate = 16;//[[audioPlayer.settings objectForKey:AVLinearPCMBitDepthKey] floatValue];
  
  @try {
      int read, write;
  
      FILE *pcm = fopen([tmpVideoPath cStringUsingEncoding:1], "rb");  //source
      fseek(pcm, 4*1024, SEEK_CUR);                                   //skip file header
      FILE *mp3 = fopen([tmpMp3FilePath cStringUsingEncoding:1], "wb");  //output
  
      const int PCM_SIZE = 8192;
      const int MP3_SIZE = 8192;
      short int pcm_buffer[PCM_SIZE*2];
      unsigned char mp3_buffer[MP3_SIZE];
  
      lame_t lame = lame_init();
      lame_set_in_samplerate(lame, sampleRate);
      lame_set_VBR(lame, vbr_default);
      lame_init_params(lame);
  
      long long fileSize = [[[[NSFileManager defaultManager] attributesOfItemAtPath:tmpVideoPath error:nil] objectForKey:NSFileSize] longLongValue];
      long duration = (fileSize * 8.0f) / (sampleRate * noOfChannels);
  
      lame_set_num_samples(lame, (duration * sampleRate));
      lame_get_num_samples(lame);
  
      int percent     = 0;
      int totalframes = lame_get_totalframes(lame);
  
      do {
          read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
          if (read == 0)
              write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
          else
              write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
  
          fwrite(mp3_buffer, write, 1, mp3);
  
          int frameNum    = lame_get_frameNum(lame);
          if (frameNum &lt; totalframes)
              percent = (int) (100. * frameNum / totalframes + 0.5);
          else
              percent = 100;
  
          [SVProgressHUD showProgress:percent status:@"Converting..." maskType:SVProgressHUDMaskTypeGradient];
  
          NSLog(@"progress: %d",percent);
  
      } while (read != 0);
  
      lame_close(lame);
      fclose(mp3);
      fclose(pcm);
  }
  @catch (NSException *exception) {
      NSLog(@"%@",[exception description]);
  }
  @finally {
      [SVProgressHUD dismiss];
  }
  }
  </code></pre>
  
  <p><em>The resultant audio that i get has nothing but a noise and its duration is also wrong.
  I googled and found that the "libmp3lame" only understand the Linear PCM audio where as the m4a is compressed audio format.</em></p>
  
  <p><strong>Now how can i convert the audio into mp3 format from m4a or any other way to directly extract audio from video in mp3 format.</strong></p>
  
  <p>Thanks.</p>