代码之家  ›  专栏  ›  技术社区  ›  Hosein Abbaspoor

斯威夫特:我怎样才能录下一段音频然后反向播放呢

  •  -2
  • Hosein Abbaspoor  · 技术社区  · 6 年前

    有一些话题,但他们太老了,我不知道如何。 如果有人能帮我,我将不胜感激。 我在AVAudioEngine和其他框架中搜索,似乎没有任何方法。至少一个简单的

    1 回复  |  直到 6 年前
        1
  •  2
  •   Enea Dume    6 年前

    首先需要导入 AVFoundation 框架到视图控制器中/

    您需要向视图控制器添加三个属性:一个用于用户点击以开始或停止录制的按钮、一个用于管理录制的音频会话和一个用于处理实际读取和保存数据的音频记录器。如果愿意,您可以在InterfaceBuilder中创建按钮;我们将在这里的代码中进行。

    将以下三个属性放入视图控制器: var recordButton:ui按钮!

    录制音频需要用户的权限来阻止恶意应用程序进行恶意操作,因此我们需要请求用户的录制权限。如果他们允许,我们就创建录音按钮。把这个放进去 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!
        }
    

    您应该替换//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 :(
        }
    }
    

    ,因为它只需要调用 startRecording() finishRecording()

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

    在您完成之前,还有一件事需要注意:iOS可能会因为您无法控制的原因停止您的录音,例如如果有电话进来。我们是录音机的代表,因此如果出现这种情况,你将被派去 audioRecorderDidFinishRecording() 完成录制() 这样地:

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

    hackingwithswift