Swift: Как я могу записать аудио, а затем воспроизвести его в обратном порядке

Как я могу записать аудио, а затем воспроизвести его в обратном порядке? в кратчайшие сроки!

Есть некоторые темы об этом, но они слишком стары, и я не могу понять, как. Буду очень признателен, если кто-нибудь сможет мне помочь. Я искал в AVAudioEngine и других фреймворках, и, кажется, нет никакого способа. по крайней мере, простой

1 ответ

Сначала вам нужно импортировать AVFoundation рамки в вашем контроллере представления /

Вам потребуется добавить три свойства в свой контроллер представления: кнопку, с которой пользователь может нажать, чтобы начать или остановить запись, аудиосеанс для управления записью и аудиорекордер для обработки фактического чтения и сохранения данных. Вы можете создать кнопку в Интерфейсном Разработчике, если хотите; мы будем делать это в коде здесь.

Поместите эти три свойства в свой контроллер представления: var recordButton: UIButton! var recordingSession: AVAudioSession! var audioRecorder: AVAudioRecorder!

Для записи звука требуется разрешение пользователя, чтобы остановить вредоносные приложения, которые совершают вредоносные действия, поэтому мы должны запросить разрешение на запись у пользователя. Если они дадут разрешение, мы создадим нашу кнопку записи. Поместите это в viewDidLoad()

recordingSession = AVAudioSession.sharedInstance()

    do {
        try recordingSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
        try recordingSession.setActive(true)
        recordingSession.requestRecordPermission() { [unowned self] allowed in
            DispatchQueue.main.async {
                if allowed {
                    self.loadRecordingUI()
                } else {
                    // failed to record!
                }
            }
        }
    } catch {
        // failed to record!
    }

Вы должны заменить // не удалось записать! комментируйте со значимым предупреждением об ошибке для вашего пользователя, или, возможно, с меткой на экране.

Я сделал код для loadRecordingUI() отделить, так что вы можете легко заменить его с работой IB или что-то еще. Вот минимум, что вам нужно сделать:

func loadRecordingUI() {
    recordButton = UIButton(frame: CGRect(x: 64, y: 64, width: 128, height: 64))
    recordButton.setTitle("Tap to Record", for: .normal)
    recordButton.titleLabel?.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.title1)
    recordButton.addTarget(self, action: #selector(recordTapped), for: .touchUpInside)
    view.addSubview(recordButton)
}

Это настраивает кнопку для вызова метода с именем recordTapped() когда это постучал. Не волнуйтесь, мы еще этого не написали!

Прежде чем писать код для recordTapped() нам нужно сделать несколько других вещей. Во-первых, нам нужен метод, чтобы начать запись. Для этого необходимо решить, где сохранить звук, настроить параметры записи, а затем начать запись. Вот код:

func startRecording() {
    let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")

    let settings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 12000,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]

    do {
        audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
        audioRecorder.delegate = self
        audioRecorder.record()

        recordButton.setTitle("Tap to Stop", for: .normal)
    } catch {
        finishRecording(success: false)
    }
}

Этот код пока не будет собран, потому что у него есть две проблемы. Во-первых, он использует метод getDocumentsDirectory(), который является вспомогательным методом, который я включаю в большинство моих проектов. Вот:

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

Во-вторых, он назначает self быть делегатом аудиорекордера, а это значит, что вы должны соответствовать AVAudioRecorderDelegate протокол как это:

class ViewController: UIViewController, AVAudioRecorderDelegate {

С кодом, написанным для начала записи, нам нужен соответствующий код для завершения записи. Это сообщит аудиорекордеру о необходимости прекратить запись, а затем верните заголовок кнопки либо к "Tap to Record" (если запись завершилась успешно), либо к "Tap to Re-record", если возникла проблема. Вот код:

func finishRecording(success: Bool) {
    audioRecorder.stop()
    audioRecorder = nil

    if success {
        recordButton.setTitle("Tap to Re-record", for: .normal)
    } else {
        recordButton.setTitle("Tap to Record", for: .normal)
        // recording failed :(
    }
}

С этими двумя на месте, мы можем наконец написать recordTapped()потому что это просто нужно позвонить либо startRecording() или же finishRecording() в зависимости от состояния аудиорегистратора. Вот код:

@objc func recordTapped() {
    if audioRecorder == nil {
        startRecording()
    } else {
        finishRecording(success: true)
    }
} 

Прежде чем закончить, нужно знать еще одну вещь: iOS может по какой-то причине остановить вашу запись вне вашего контроля, например, при поступлении телефонного звонка. Мы являемся делегатом аудио-рекордера, поэтому, если эта ситуация всплывает, вы получите audioRecorderDidFinishRecording() сообщение, которое вы можете передать finishRecording() как это:

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
    if !flag {
        finishRecording(success: false)
    }
}

Источник и для получения дополнительной информации читайте hackingwithswift

Другие вопросы по тегам