web-dev-qa-db-fra.com

Enregistrement audio dans Swift

Est-ce que quelqu'un sait où je peux trouver des informations sur la manière d'enregistrer de l'audio dans une application Swift? Je suis en train de regarder quelques exemples de lecture audio mais je n'arrive pas à trouver quoi que ce soit pour implémenter l'enregistrement audio. Merci

38
Michael Bain

Voici le code.Vous pouvez enregistrer facilement.Écrivez ce code sur IBAction.Il enregistrera l'enregistrement en Documents par son nom recordTest.caf

//declare instance variable 
var audioRecorder:AVAudioRecorder!
func record(){        
    var audioSession:AVAudioSession = AVAudioSession.sharedInstance()
    audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, error: nil)
    audioSession.setActive(true, error: nil)

    var documents: AnyObject = NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.DocumentDirectory,  NSSearchPathDomainMask.UserDomainMask, true)[0]
    var str =  documents.stringByAppendingPathComponent("recordTest.caf")
    var url = NSURL.fileURLWithPath(str as String)

    var recordSettings = [AVFormatIDKey:kAudioFormatAppleIMA4,
        AVSampleRateKey:44100.0,
        AVNumberOfChannelsKey:2,AVEncoderBitRateKey:12800,
        AVLinearPCMBitDepthKey:16,
        AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue]

    println("url : \(url)")
    var error: NSError?

    audioRecorder = AVAudioRecorder(URL:url, settings: recordSettings, error: &error)
    if let e = error {
        println(e.localizedDescription)
    } else {
        audioRecorder.record()
    }        
}
40
codester

Dans Swift 3

 enter image description here

  • Ajouter un cadre AVFoundation
  • Dans info.plist, touche add: Confidentialité - Utilisation du microphone Description et valeur: Pour utiliser un microphone (les applications se bloqueront si vous ne fournissez pas la valeur - description pourquoi vous demandez l'autorisation.)

 enter image description here

  • Importer AVFoundation & AVAudioRecorderDelegate, AVAudioPlayerDelegate 

    import AVFoundation
    
     class RecordVC: UIViewController , AVAudioRecorderDelegate, AVAudioPlayerDelegate
    
  • Bouton Create pour l'enregistrement audio et la lecture audio, et le libellé pour l'affichage, le minutage et l'affichage des sorties et des actions comme start_recording, play_recording & declare des variables que nous utiliserons ultérieurement

    @IBOutlet var recordingTimeLabel: UILabel!
    @IBOutlet var record_btn_ref: UIButton!
    @IBOutlet var play_btn_ref: UIButton!
    
    var audioRecorder: AVAudioRecorder!
    var audioPlayer : AVAudioPlayer!
    var meterTimer:Timer!
    var isAudioRecordingGranted: Bool!
    var isRecording = false
    var isPlaying = false
    
  • Dans viewDidLoad, autorisation d'enregistrement de contrôle

    override func viewDidLoad() {
        super.viewDidLoad()
        check_record_permission()
    }
    
    func check_record_permission()
    {
        switch AVAudioSession.sharedInstance().recordPermission() {
        case AVAudioSessionRecordPermission.granted:
            isAudioRecordingGranted = true
            break
        case AVAudioSessionRecordPermission.denied:
            isAudioRecordingGranted = false
            break
        case AVAudioSessionRecordPermission.undetermined:
            AVAudioSession.sharedInstance().requestRecordPermission({ (allowed) in
                    if allowed {
                        self.isAudioRecordingGranted = true
                    } else {
                        self.isAudioRecordingGranted = false
                    }
            })
            break
        default:
            break
        }
    }
    
  • générer le chemin où vous souhaitez enregistrer cet enregistrement sous le nom myRecording.m4a

    func getDocumentsDirectory() -> URL
    {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let documentsDirectory = paths[0]
        return documentsDirectory
    }
    
    func getFileUrl() -> URL
    {
        let filename = "myRecording.m4a"
        let filePath = getDocumentsDirectory().appendingPathComponent(filename)
    return filePath
    }
    
  • Configurer l'enregistreur

    func setup_recorder()
    {
        if isAudioRecordingGranted
        {
            let session = AVAudioSession.sharedInstance()
            do
            {
                try session.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)
                try session.setActive(true)
                let settings = [
                    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                    AVSampleRateKey: 44100,
                    AVNumberOfChannelsKey: 2,
                    AVEncoderAudioQualityKey:AVAudioQuality.high.rawValue
                ]
                audioRecorder = try AVAudioRecorder(url: getFileUrl(), settings: settings)
                audioRecorder.delegate = self
                audioRecorder.isMeteringEnabled = true
                audioRecorder.prepareToRecord()
            }
            catch let error {
                display_alert(msg_title: "Error", msg_desc: error.localizedDescription, action_title: "OK")
            }
        }
        else
        {
            display_alert(msg_title: "Error", msg_desc: "Don't have access to use your microphone.", action_title: "OK")
        }
    }
    
  • Commencez l'enregistrement lorsque le bouton démarrer_enregistrez appuyez et affichez les secondes à l'aide de updateAudioMeter, & si l'enregistrement commence, terminez l'enregistrement

    @IBAction func start_recording(_ sender: UIButton)
    {
        if(isRecording)
        {
            finishAudioRecording(success: true)
            record_btn_ref.setTitle("Record", for: .normal)
            play_btn_ref.isEnabled = true
            isRecording = false
        }
        else
        {
            setup_recorder()
    
            audioRecorder.record()
            meterTimer = Timer.scheduledTimer(timeInterval: 0.1, target:self, selector:#selector(self.updateAudioMeter(timer:)), userInfo:nil, repeats:true)
            record_btn_ref.setTitle("Stop", for: .normal)
            play_btn_ref.isEnabled = false
            isRecording = true
        }
    }
    
    func updateAudioMeter(timer: Timer)
    {
        if audioRecorder.isRecording
        {
            let hr = Int((audioRecorder.currentTime / 60) / 60)
            let min = Int(audioRecorder.currentTime / 60)
            let sec = Int(audioRecorder.currentTime.truncatingRemainder(dividingBy: 60))
            let totalTimeString = String(format: "%02d:%02d:%02d", hr, min, sec)
            recordingTimeLabel.text = totalTimeString
            audioRecorder.updateMeters()
        }
    }
    
    func finishAudioRecording(success: Bool)
    {
        if success
        {
            audioRecorder.stop()
            audioRecorder = nil
            meterTimer.invalidate()
            print("recorded successfully.")
        }
        else
        {
            display_alert(msg_title: "Error", msg_desc: "Recording failed.", action_title: "OK")
        }
    }
    
  • Lecture de l'enregistrement

    func prepare_play()
    {
        do
        {
            audioPlayer = try AVAudioPlayer(contentsOf: getFileUrl())
            audioPlayer.delegate = self
            audioPlayer.prepareToPlay()
        }
        catch{
            print("Error")
        }
    }
    
    @IBAction func play_recording(_ sender: Any)
    {
        if(isPlaying)
        {
            audioPlayer.stop()
            record_btn_ref.isEnabled = true
            play_btn_ref.setTitle("Play", for: .normal)
            isPlaying = false
        }
        else
        {
            if FileManager.default.fileExists(atPath: getFileUrl().path)
            {
                record_btn_ref.isEnabled = false
                play_btn_ref.setTitle("pause", for: .normal)
                prepare_play()
                audioPlayer.play()
                isPlaying = true
            }
            else
            {
                display_alert(msg_title: "Error", msg_desc: "Audio file is missing.", action_title: "OK")
            }
        }
    }
    
  • Lorsque l'enregistrement est terminé, activez le bouton de lecture et lorsque la lecture est terminée, activez le bouton d'enregistrement

    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool)
    {
        if !flag
        {
            finishAudioRecording(success: false)
        }
        play_btn_ref.isEnabled = true
    }
    
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
    {
        record_btn_ref.isEnabled = true
    }
    
  • Fonction de généralisation pour l'alerte d'affichage

    func display_alert(msg_title : String , msg_desc : String ,action_title : String)
    {
        let ac = UIAlertController(title: msg_title, message: msg_desc, preferredStyle: .alert)
        ac.addAction(UIAlertAction(title: action_title, style: .default)
        {
            (result : UIAlertAction) -> Void in
        _ = self.navigationController?.popViewController(animated: true)
        })
        present(ac, animated: true)
    }
    
30
Mili Shah

Version Swift2 de la réponse de @ codester.

func record() {
    //init
    let audioSession:AVAudioSession = AVAudioSession.sharedInstance()

    //ask for permission
    if (audioSession.respondsToSelector("requestRecordPermission:")) {
        AVAudioSession.sharedInstance().requestRecordPermission({(granted: Bool)-> Void in
            if granted {
                print("granted")

                //set category and activate recorder session
                try! audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
                try! audioSession.setActive(true)


                //get documnets directory
                let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
                let fullPath = documentsDirectory.stringByAppendingPathComponent("voiceRecording.caf")
                let url = NSURL.fileURLWithPath(fullPath)

                //create AnyObject of settings
                let settings: [String : AnyObject] = [
                    AVFormatIDKey:Int(kAudioFormatAppleIMA4), //Int required in Swift2
                    AVSampleRateKey:44100.0,
                    AVNumberOfChannelsKey:2,
                    AVEncoderBitRateKey:12800,
                    AVLinearPCMBitDepthKey:16,
                    AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue
                ]

                //record
                try! self.audioRecorder = AVAudioRecorder(URL: url, settings: settings)

            } else{
                print("not granted")
            }
        })
    }

}
15
Kristian

En plus des réponses précédentes, j'ai essayé de le faire fonctionner sur Xcode 7.2 et je n'ai entendu aucun son après, pas plus quand j'ai envoyé le fichier par courrier électronique. Aucun avertissement ou exception . J'ai donc modifié les paramètres comme suit et les ai enregistrés dans un fichier .m4a.

let recordSettings = [AVSampleRateKey : NSNumber(float: Float(44100.0)),
    AVFormatIDKey : NSNumber(int: Int32(kAudioFormatMPEG4AAC)),
    AVNumberOfChannelsKey : NSNumber(int: 1),
    AVEncoderAudioQualityKey : NSNumber(int: Int32(AVAudioQuality.Medium.rawValue))]

Après cela, je pouvais écouter le son . Pour enregistrer le fichier, j'ai ajouté ceci à viewDidLoad pour initialiser l'enregistreur:

let audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
        try audioRecorder = AVAudioRecorder(URL: self.directoryURL()!,
            settings: recordSettings)
        audioRecorder.prepareToRecord()
    } catch {
    }

Et pour créer le répertoire:

func directoryURL() -> NSURL? {
    let fileManager = NSFileManager.defaultManager()
    let urls = fileManager.URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    let documentDirectory = urls[0] as NSURL
    let soundURL = documentDirectory.URLByAppendingPathComponent("sound.m4a")
    return soundURL 
}

J'ajoute également les actions utilisées pour démarrer l'enregistrement, arrêter et jouer après

@IBAction func doRecordAction(sender: AnyObject) {
    if !audioRecorder.recording {
        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setActive(true)
            audioRecorder.record()
        } catch {
        }
   }
}
@IBAction func doStopRecordingAction(sender: AnyObject) {
    audioRecorder.stop()
    let audioSession = AVAudioSession.sharedInstance()

    do {
        try audioSession.setActive(false)
    } catch {
    }
}

@IBAction func doPlayAction(sender: AnyObject) {
    if (!audioRecorder.recording){
        do {
            try audioPlayer = AVAudioPlayer(contentsOfURL: audioRecorder.url)
            audioPlayer.play()
        } catch {
        }
    }
}
6
Andreas777

Ici enregistreur audio avec une interface simple écrite sur Swift 4.2.

final class AudioRecorderImpl: NSObject {
  private let session = AVAudioSession.sharedInstance()
  private var player: AVAudioPlayer?
  private var recorder: AVAudioRecorder?
  private lazy var permissionGranted = false
  private lazy var isRecording = false
  private lazy var isPlaying = false
  private var fileURL: URL?
  private let settings = [
    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
    AVSampleRateKey: 44100,
    AVNumberOfChannelsKey: 2,
    AVEncoderAudioQualityKey:AVAudioQuality.high.rawValue
  ]

  override init() {
    fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("note.m4a")
  }

  func record(to url: URL?) {
    guard permissionGranted,
      let url = url ?? fileURL else { return }

    setupRecorder(url: url)

    if isRecording {
      stopRecording()
    }

    isRecording = true
    recorder?.record()
  }

  func stopRecording() {
    isRecording = false
    recorder?.stop()
    try? session.setActive(false)
  }

  func play(from url: URL?) {
    guard let url = url ?? fileURL else { return }

    setupPlayer(url: url)

    if isRecording {
      stopRecording()
    }

    if isPlaying {
      stopPlaying()
    }

    if FileManager.default.fileExists(atPath: url.path) {
      isPlaying = true
      setupPlayer(url: url)
      player?.play()
    }
  }

  func stopPlaying() {
    player?.stop()
  }

  func pause() {
    player?.pause()
  }

  func resume() {
    if player?.isPlaying == false {
      player?.play()
    }
  }

  func checkPermission(completion: ((Bool) -> Void)?) {
    func assignAndInvokeCallback(_ granted: Bool) {
      self.permissionGranted = granted
      completion?(granted)
    }

    switch session.recordPermission {
    case .granted:
      assignAndInvokeCallback(true)

    case .denied:
      assignAndInvokeCallback(false)

    case .undetermined:
      session.requestRecordPermission(assignAndInvokeCallback)
    }
  }
}

extension AudioRecorderImpl: AVAudioRecorderDelegate, AVAudioPlayerDelegate {

}

private extension AudioRecorderImpl {
  func setupRecorder(url: URL) {
    guard
      permissionGranted else { return }
    try? session.setCategory(.playback, mode: .default)
    try? session.setActive(true)
    let settings = [
      AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
      AVSampleRateKey: 44100,
      AVNumberOfChannelsKey: 2,
      AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]
    recorder = try? AVAudioRecorder(url: url, settings: settings)
    recorder?.delegate = self
    recorder?.isMeteringEnabled = true
    recorder?.prepareToRecord()
  }

  func setupPlayer(url: URL) {
    player = try? AVAudioPlayer(contentsOf: url)
    player?.delegate = self
    player?.prepareToPlay()
  }
}
1
Bohdan Savych

Version Swift 3 Code: Solution complète pour l'enregistrement audio!

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioRecorderDelegate {

    //Outlets
    @IBOutlet weak var recordingTimeLabel: UILabel!

    //Variables
    var audioRecorder: AVAudioRecorder!
    var meterTimer:Timer!
    var isAudioRecordingGranted: Bool!


    override func viewDidLoad() {
        super.viewDidLoad()

        switch AVAudioSession.sharedInstance().recordPermission() {
        case AVAudioSessionRecordPermission.granted:
            isAudioRecordingGranted = true
            break
        case AVAudioSessionRecordPermission.denied:
            isAudioRecordingGranted = false
            break
        case AVAudioSessionRecordPermission.undetermined:
            AVAudioSession.sharedInstance().requestRecordPermission() { [unowned self] allowed in
                DispatchQueue.main.async {
                    if allowed {
                        self.isAudioRecordingGranted = true
                    } else {
                        self.isAudioRecordingGranted = false
                    }
                }
            }
            break
        default:
            break
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

        audioRecorder = nil
    }

    //MARK:- Audio recorder buttons action.
    @IBAction func audioRecorderAction(_ sender: UIButton) {

        if isAudioRecordingGranted {

            //Create the session.
            let session = AVAudioSession.sharedInstance()

            do {
                //Configure the session for recording and playback.
                try session.setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)
                try session.setActive(true)
                //Set up a high-quality recording session.
                let settings = [
                    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
                    AVSampleRateKey: 44100,
                    AVNumberOfChannelsKey: 2,
                    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
                ]
                //Create audio file name URL
                let audioFilename = getDocumentsDirectory().appendingPathComponent("audioRecording.m4a")
                //Create the audio recording, and assign ourselves as the delegate
                audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
                audioRecorder.delegate = self
                audioRecorder.isMeteringEnabled = true
                audioRecorder.record()
                meterTimer = Timer.scheduledTimer(timeInterval: 0.1, target:self, selector:#selector(self.updateAudioMeter(timer:)), userInfo:nil, repeats:true)
            }
            catch let error {
                print("Error for start audio recording: \(error.localizedDescription)")
            }
        }
    }

    @IBAction func stopAudioRecordingAction(_ sender: UIButton) {

        finishAudioRecording(success: true)

    }

    func finishAudioRecording(success: Bool) {

        audioRecorder.stop()
        audioRecorder = nil
        meterTimer.invalidate()

        if success {
            print("Recording finished successfully.")
        } else {
            print("Recording failed :(")
        }
    }

    func updateAudioMeter(timer: Timer) {

        if audioRecorder.isRecording {
            let hr = Int((audioRecorder.currentTime / 60) / 60)
            let min = Int(audioRecorder.currentTime / 60)
            let sec = Int(audioRecorder.currentTime.truncatingRemainder(dividingBy: 60))
            let totalTimeString = String(format: "%02d:%02d:%02d", hr, min, sec)
            recordingTimeLabel.text = totalTimeString
            audioRecorder.updateMeters()
        }
    }

    func getDocumentsDirectory() -> URL {

        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let documentsDirectory = paths[0]
        return documentsDirectory
    }

    //MARK:- Audio recoder delegate methods
    func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {

        if !flag {
            finishAudioRecording(success: false)
        }
    }
}
0
mriaz0011

Code dans le fichier de classe Utilisation de Swift 4

La classe est AGAudioRecorder

Code est 

class AudioRecordViewController: UIViewController {

    @IBOutlet weak var recodeBtn: UIButton!
    @IBOutlet weak var playBtn: UIButton!

    var state: AGAudioRecorderState = .Ready

    var recorder: AGAudioRecorder = AGAudioRecorder(withFileName: "TempFile")

    override func viewDidLoad() {
        super.viewDidLoad()

        recodeBtn.setTitle("Recode", for: .normal)
        playBtn.setTitle("Play", for: .normal)
        recorder.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    @IBAction func recode(_ sender: UIButton) {
        recorder.doRecord()
    }

    @IBAction func play(_ sender: UIButton) {
        recorder.doPlay()
    }
}

extension AudioRecordViewController: AGAudioRecorderDelegate {
    func agAudioRecorder(_ recorder: AGAudioRecorder, withStates state: AGAudioRecorderState) {
        switch state {
        case .error(let e): debugPrint(e)
        case .Failed(let s): debugPrint(s)

        case .Finish:
            recodeBtn.setTitle("Recode", for: .normal)

        case .Recording:
            recodeBtn.setTitle("Recoding Finished", for: .normal)

        case .Pause:
            playBtn.setTitle("Pause", for: .normal)

        case .Play:
            playBtn.setTitle("Play", for: .normal)

        case .Ready:
            recodeBtn.setTitle("Recode", for: .normal)
            playBtn.setTitle("Play", for: .normal)
            refreshBtn.setTitle("Refresh", for: .normal)
        }
        debugPrint(state)
    }

    func agAudioRecorder(_ recorder: AGAudioRecorder, currentTime timeInterval: TimeInterval, formattedString: String) {
        debugPrint(formattedString)
    }
}
0
AshvinGudaliya