【问题标题】:Swift: play the audio recordedSwift:播放录制的音频
【发布时间】:2023-03-15 10:39:01
【问题描述】:

我试着记录下来,我可以在这里找到一个很好的答案: Recording audio in Swift

我可以让它工作。但现在我想知道如何播放录制的音频。从录音中我已经有了通用的 var audioRecorder,并定义了 url 路径。所以我尝试了 audioRecorder.play() 但它不起作用。

我想问题来自这样一个事实,即全局 var audioRecorder 是 AVAudioRecorder 的一个实例,如果它是 AVAudioPlayer 的一个实例来播放它?这两件事有什么关系?

我不想复制粘贴和平我想理解的代码。这就是我在这里简化代码的原因。请解释为什么它在这个特定的代码中不起作用以及如何解决它。

(我做了很多相关的教程。问题是我丢失了太多代码。我的问题是了解这个特定部分是如何工作的)

import AVFoundation
var audioRecorder:AVAudioRecorder!
@IBAction func record(sender: AnyObject) {       
    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)
    println(url)

    audioRecorder = AVAudioRecorder(URL:url, settings: nil, error: nil)
    audioRecorder.record()
}

@IBAction func play(sender: AnyObject) {
   // this gives the error 'AVAudioRecorder' does not have a member named 'play'
   // audioRecorder.play() 
}

【问题讨论】:

    标签: ios swift audio


    【解决方案1】:

    这是录制音频然后将其存储到文件然后播放的完整工作代码:

    import UIKit
    import AVFoundation
    
    class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
    
        @IBOutlet weak var recordButton: UIButton!
        @IBOutlet weak var stopButton: UIButton!
        @IBOutlet weak var playButton: UIButton!
        
        var audioPlayer : AVAudioPlayer?
        var audioRecorder : AVAudioRecorder?
        
        
        override func viewDidLoad() {
            super.viewDidLoad()
            playButton.enabled = false
            stopButton.enabled = false
            
            // getting URL path for audio
            let dirPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
            let docDir = dirPath[0] as! String
            let soundFilePath = docDir.stringByAppendingPathComponent("sound.caf")
            let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
            println(soundFilePath)
            
            //Setting for recorder
            let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.Min.rawValue,
                AVEncoderBitRateKey: 16,
                AVNumberOfChannelsKey : 2,
                AVSampleRateKey: 44100.0]
            var error : NSError?
            let audioSession = AVAudioSession.sharedInstance()
            audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, error: &error)
            if let err = error{
                println("audioSession error: \(err.localizedDescription)")
            }
            audioRecorder = AVAudioRecorder(URL: soundFileURL, settings: recordSettings as [NSObject : AnyObject], error: &error)
            
            if let err = error{
                println("audioSession error: \(err.localizedDescription)")
            }else{
                audioRecorder?.prepareToRecord()
            }
        }
        //record audio
        @IBAction func recordAudio(sender: AnyObject) {
            
            if audioRecorder?.recording == false{
                playButton.enabled = false
                stopButton.enabled = true
                audioRecorder?.record()
            }
        }
        //stop recording audio
        @IBAction func stopAudio(sender: AnyObject) {
            
            stopButton.enabled = false
            playButton.enabled = true
            recordButton.enabled = true
            
            if audioRecorder?.recording == true{
                audioRecorder?.stop()
            }else{
                audioPlayer?.stop()
            }
        }
        //play your recorded audio
        @IBAction func playAudio(sender: AnyObject) {
            
            if audioRecorder?.recording == false{
                stopButton.enabled = true
                recordButton.enabled = false
                
                var error : NSError?
                
                audioPlayer = AVAudioPlayer(contentsOfURL: audioRecorder?.url, error: &error)
                
                audioPlayer?.delegate = self
                
                if let err = error{
                    println("audioPlayer error: \(err.localizedDescription)")
                }else{
                    audioPlayer?.play()
                }
            }
        }
        
        func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
            recordButton.enabled = true
            stopButton.enabled = false
        }
        
        func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
            println("Audio Play Decode Error")
        }
        
        func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {
        }
        
        func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
            println("Audio Record Encode Error")
        }
    }
    

    查看THIS 示例项目了解更多信息。

    在您的代码中,audioRecorder 用于录制音频,audioPlayer 用于播放音频。这就是为什么audioRecorder 没有属性play()

    所以你不能使用audioRecorder.play()

    【讨论】:

      【解决方案2】:

      这是@DharmeshKheni 的答案 + 为 swift 4.0 更新 创建三个按钮并向它们添加插座和方法。

      新版本

      import UIKit
      import AVFoundation
      
      class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
      
      @IBOutlet weak var recordButton: UIButton!
      @IBOutlet weak var stopButton: UIButton!
      @IBOutlet weak var playButton: UIButton!
      
      var audioPlayer : AVAudioPlayer?
      var audioRecorder : AVAudioRecorder?
      
      
      override func viewDidLoad() {
          super.viewDidLoad()
          playButton.isEnabled = false
          stopButton.isEnabled = false
      
          // getting URL path for audio
          let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
          let docDir = dirPath[0]
          let soundFilePath = (docDir as NSString).appendingPathComponent("sound.caf")
          let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
          print(soundFilePath)
      
          //Setting for recorder
          let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
              AVEncoderBitRateKey: 16,
              AVNumberOfChannelsKey : 2,
              AVSampleRateKey: 44100.0] as [String : Any] as [String : Any] as [String : Any] as [String : Any]
          var error : NSError?
          let audioSession = AVAudioSession.sharedInstance()
          do {
              try audioSession.setCategory(AVAudioSession.Category.playAndRecord)
              audioRecorder = try AVAudioRecorder(url: soundFileURL as URL, settings: recordSettings as [String : AnyObject])
          } catch _ {
              print("Error")
          }
      
          if let err = error {
              print("audioSession error: \(err.localizedDescription)")
          }else{
              audioRecorder?.prepareToRecord()
          }
      }
      //record audio
      @IBAction func recordAudio(sender: AnyObject) {
      
          if audioRecorder?.isRecording == false{
              playButton.isEnabled = false
              stopButton.isEnabled = true
              audioRecorder?.record()
          }
      }
      //stop recording audio
      @IBAction func stopAudio(sender: AnyObject) {
      
          stopButton.isEnabled = false
          playButton.isEnabled = true
          recordButton.isEnabled = true
      
          if audioRecorder?.isRecording == true{
              audioRecorder?.stop()
          }else{
              audioPlayer?.stop()
          }
      }
      //play your recorded audio
      @IBAction func playAudio(sender: AnyObject) {
      
          if audioRecorder?.isRecording == false{
              stopButton.isEnabled = true
              recordButton.isEnabled = false
      
              var error : NSError?
              do {
                  let player = try AVAudioPlayer(contentsOf: audioRecorder!.url)
                   audioPlayer = player
               } catch {
                   print(error)
               }
      
              audioPlayer?.delegate = self
      
              if let err = error{
                  print("audioPlayer error: \(err.localizedDescription)")
              }else{
                  audioPlayer?.play()
              }
          }
      }
      
      func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
          recordButton.isEnabled = true
          stopButton.isEnabled = false
      }
      
      private func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
          print("Audio Play Decode Error")
      }
      
      func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
      }
      
      private func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
          print("Audio Record Encode Error")
      }
      

      }

      旧版本

      import UIKit
      import AVFoundation
      
      class PlayVC: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
      
          @IBOutlet weak var recordButton: UIButton!
          @IBOutlet weak var stopButton: UIButton!
          @IBOutlet weak var playButton: UIButton!
      
          var audioPlayer : AVAudioPlayer?
          var audioRecorder : AVAudioRecorder?
      
      
          override func viewDidLoad() {
              super.viewDidLoad()
              playButton.isEnabled = false
              stopButton.isEnabled = false
      
              // getting URL path for audio
              let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
              let docDir = dirPath[0] as! String
              let soundFilePath = docDir.stringByAppendingPathComponent(path: "sound.caf")
              let soundFileURL = NSURL(fileURLWithPath: soundFilePath)
              print(soundFilePath)
      
              //Setting for recorder
              let recordSettings = [AVEncoderAudioQualityKey: AVAudioQuality.min.rawValue,
                                    AVEncoderBitRateKey: 16,
                                    AVNumberOfChannelsKey : 2,
                                    AVSampleRateKey: 44100.0] as [String : Any]
              var error : NSError?
              let audioSession = AVAudioSession.sharedInstance()
      
              do {
                  try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
              } catch {
                  print(error)
              }
              if let err = error{
                  print("audioSession error: \(err.localizedDescription)")
              }
              do {
                  audioRecorder = try AVAudioRecorder(url: soundFileURL as URL, settings: recordSettings as [String : Any])
              } catch {
                  print(error)
              }
      
      
              if let err = error{
                  print("audioSession error: \(err.localizedDescription)")
              }else{
                  audioRecorder?.prepareToRecord()
              }
          }
          //record audio
          @IBAction func recordAudio(sender: AnyObject) {
      
              if audioRecorder?.isRecording == false{
                  playButton.isEnabled = false
                  stopButton.isEnabled = true
                  audioRecorder?.record()
              }
          }
          //stop recording audio
          @IBAction func stopAudio(sender: AnyObject) {
      
              stopButton.isEnabled = false
              playButton.isEnabled = true
              recordButton.isEnabled = true
      
              if audioRecorder?.isRecording == true{
                  audioRecorder?.stop()
              }else{
                  audioPlayer?.stop()
              }
          }
          //play your recorded audio
          @IBAction func playAudio(sender: AnyObject) {
      
              if audioRecorder?.isRecording == false{
                  stopButton.isEnabled = true
                  recordButton.isEnabled = false
      
                  var error : NSError?
      
                  do {
      
                      audioPlayer = try AVAudioPlayer(contentsOf: (audioRecorder?.url)!)
                  } catch {
                      print(error)
                  }
      
                  audioPlayer?.delegate = self
      
                  if let err = error{
                      print("audioPlayer error: \(err.localizedDescription)")
                  }else{
                      audioPlayer?.play()
                  }
              }
          }
      
          func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
              recordButton.isEnabled = true
              stopButton.isEnabled = false
          }
      
          func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {
              print("Audio Play Decode Error")
          }
      
          func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {
          }
      
          func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {
              print("Audio Record Encode Error")
          }
      }
      

      【讨论】:

      • mate 此代码与当前的 swift 版本 aka 4 存在很多问题。如果您说此代码适用于 Swift 4,请考虑改进它。
      • 感谢您的评论,请帮助我为社区改进此答案。
      • 使用 swift 4 在 Xcode 10.x 中运行它,您会遇到错误,然后解决它们并更新答案。就是这样。
      • 感谢您的评论,请帮助我,因为我已经点击了录制音频,但没有发生任何事情。
      • @Ayushjain,它仍然无法正常工作吗?我想我应该为 swift 5 更新它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-23
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多