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