Search code examples
iosswiftxcodeavaudiorecorderavassetexportsession

How to convert .caf Audio file into .mp4 file in swift


I'm recording audio using device microphone with AVAudioRecorder which return file in .caf format that is playable only in Apple devices but not on Android devices. Since Apple is not supporting .mp3 file so I want to convert it in .mp4 format before uploading to server. Is .mp4 is good for audio only? Can I convert it with AVAssetExportSession ?

Following is audio recorder code:

func setupAudioRecorder ()
    {

    let fileMgr = FileManager.default
    let dirPaths = fileMgr.urls(for:.documentDirectory,
                                in:.userDomainMask)

    let soundFileURL = dirPaths[0].appendingPathComponent("myaudio.caf")

    let recordSettings =
        [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
         AVEncoderBitRateKey: 16,
         AVNumberOfChannelsKey: 2,
         AVSampleRateKey: 44100.0] as [String : Any]

    do {
        try audioSession.setCategory(
            AVAudioSessionCategoryPlayAndRecord)
    } catch let error as NSError {
        print("audioSession error: \(error.localizedDescription)")
    }

    do {
        try audioRecorder = AVAudioRecorder(url: soundFileURL,
                                            settings: recordSettings as [String : AnyObject])
        audioRecorder?.prepareToRecord()
    } catch let error as NSError {
        print("audioSession error: \(error.localizedDescription)")
    }
}

Solution

  • After lot of search i am able to convert .caf into .mp4 using this piece of code

        let audioURL = ".caf audio file url"
    
        let fileMgr = FileManager.default
    
        let dirPaths = fileMgr.urls(for: .documentDirectory,
                                    in: .userDomainMask)
    
        let outputUrl = dirPaths[0].appendingPathComponent("audiosound.mp4")
    
        let asset = AVAsset.init(url: audioURL)
    
        let exportSession = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetHighestQuality)
    
        // remove file if already exits
        let fileManager = FileManager.default
        do{
            try? fileManager.removeItem(at: outputUrl)
    
        }catch{
            print("can't")
        }
    
    
        exportSession?.outputFileType = AVFileTypeMPEG4
    
        exportSession?.outputURL = outputUrl
    
        exportSession?.metadata = asset.metadata
    
        exportSession?.exportAsynchronously(completionHandler: {
            if (exportSession?.status == .completed)
            {
                print("AV export succeeded.")
    
               // outputUrl to post Audio on server
    
            }
            else if (exportSession?.status == .cancelled)
            {
                print("AV export cancelled.")
            }
            else
            {
                print ("Error is \(String(describing: exportSession?.error))")
    
            }
        })