【发布时间】:2018-07-28 12:21:28
【问题描述】:
如何录制音频然后反向播放?很快!
有一些关于这个的话题,但它们太老了,我不知道怎么做。 如果有人可以帮助我,我将不胜感激。 我搜索了 AVAudioEngine 和其他框架,似乎没有任何办法。至少一个简单的
【问题讨论】:
标签: ios swift avaudioplayer avaudioengine
如何录制音频然后反向播放?很快!
有一些关于这个的话题,但它们太老了,我不知道怎么做。 如果有人可以帮助我,我将不胜感激。 我搜索了 AVAudioEngine 和其他框架,似乎没有任何办法。至少一个简单的
【问题讨论】:
标签: ios swift avaudioplayer avaudioengine
首先你需要将AVFoundation 框架导入你的视图控制器/
您需要向视图控制器添加三个属性:一个供用户点击以开始或停止录制的按钮、一个用于管理录制的音频会话以及一个用于处理实际读取和保存数据的录音机。如果您愿意,可以在 Interface Builder 中创建按钮;我们将在这里的代码中进行。
将这三个属性放入您的视图控制器中: var 记录按钮:UIButton! var 录音会话: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 {
编写开始录制的代码后,我们需要匹配的代码来完成录制。这将告诉录音机停止录制,然后将按钮标题放回“点击录制”(如果录制成功完成)或“点击重新录制”如果有问题。代码如下:
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
【讨论】: