【问题标题】:How can I play a sound on iOS?如何在 iOS 上播放声音?
【发布时间】:2020-02-03 13:41:34
【问题描述】:

我已经构建了一个随机数生成器,我希望它在按下按钮时播放声音。 Xcode 没有给我任何错误,当我模拟我的应用程序时,它生成数字没问题,但没有声音。我的声音在声音文件夹中。

这是我的代码。

import UIKit
import AVFoundation


class ViewController: UIViewController {

    var player: AVAudioPlayer!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBOutlet weak var operations: UIImageView!
    @IBOutlet weak var bottomRightNumber: UIImageView!
    @IBOutlet weak var bottomMiddleNumber: UIImageView!
    @IBOutlet weak var bottomLeftNumber: UIImageView!
    @IBOutlet weak var topRightNumber: UIImageView!
    @IBOutlet weak var topMiddleNumber: UIImageView!
    @IBOutlet weak var topLeftNumber: UIImageView!

    @IBAction func buttonPressed(_ sender: UIButton) {

        let numberArray = [#imageLiteral(resourceName: "RN1"), #imageLiteral(resourceName: "RN2"), #imageLiteral(resourceName: "RN3"), #imageLiteral(resourceName: "RN4"),#imageLiteral(resourceName: "RN5"), #imageLiteral(resourceName: "RN6"), #imageLiteral(resourceName: "RN7"), #imageLiteral(resourceName: "RN8"), #imageLiteral(resourceName: "RN9"), #imageLiteral(resourceName: "RN0")]

        bottomRightNumber.image = numberArray.randomElement()
        bottomLeftNumber.image = numberArray.randomElement()
        bottomMiddleNumber.image = numberArray.randomElement()
        topRightNumber.image = numberArray.randomElement()
        topMiddleNumber.image = numberArray.randomElement()
        topLeftNumber.image = numberArray.randomElement()

        let operationArray = [#imageLiteral(resourceName: "-"), #imageLiteral(resourceName: "+")]

        operations.image = operationArray.randomElement()

            func playSound() {
                guard let url = Bundle.main.url(forResource: "A", withExtension: "wav") else { return }

             do { /* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
                    player = try! AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
                player.play()

                }
            }
        }
}

【问题讨论】:

标签: ios swift avaudioplayer


【解决方案1】:

看起来您只是复制并粘贴了其他人的代码。但是您将它粘贴到其他代码中,所以现在的问题是您播放声音的代码最终被包裹在一个嵌套函数声明中,在您的func buttonPressed 代码中:

func playSound() {
    guard let url = Bundle.main.url(forResource: "A", withExtension: "wav") else { return }
    do { 
        player = try! AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
        player.play() // this is where sound _would_ play
    }
}

没有任何东西调用过这个函数,所以它永远不会运行。

只需删除包装代码的那两行,现在代码就可以作为buttonPressed 的一部分运行。我还建议删除毫无意义的 do 构造,所以你最终会得到这个:

    guard let url = Bundle.main.url(forResource: "A", withExtension: "wav") else { return }
    player = try! AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
    player.play() // this is where sound _would_ play

您的声音仍然可能无法播放,或者您可能会崩溃,但至少代码现在可以实际运行!


说了这么多,让我稍微修改一下代码来展示最佳实践:

    guard let url = Bundle.main.url(forResource: "A", withExtension: "wav") else {
        print("the URL was not valid") // tell yourself what went wrong
        return
    }
    do {
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
        player.play()
    } catch { print(error) } // tell yourself what went wrong

在那个版本中,我把 do 结构放回去了,但这一次它实际上做了一些有用的事情。

【讨论】:

  • 这看起来像食物我要试一试,我会让你知道结果。感谢您的宝贵时间。
  • 声音仍然无法播放 代码运行良好,我的按钮在按下时工作。无论如何感谢您的帮助。
  • 但是现在有了我的扩展版本,控制台中应该有一些东西可以告诉你原因。如果播放线运行,您将播放。
  • 啊,我明白了,在调试控制台中,它会打印“url 无效”的语句
  • 没错。这就是为什么你应该打印错误,而不是抛弃它们。
【解决方案2】:

你可以做两件事: 1.从buttonPressed动作中取出函数playSound()并调用playSound()函数——因为我看到你没有调用函数来播放声音。 2. 如果你最终要在 playSound() 函数中使用它,你可以直接从函数中取出音频代码。

【讨论】:

    【解决方案3】:

    这是播放声音的示例类,

    import Foundation
    import AudioToolbox
    import AVKit
    
    class SoundManager {
    
        static var objPlayer: AVAudioPlayer?
        class func playAppLaunchSound() {
    
            registerAndPlaySoundForFile(fileName: "AppLaunchSound", fileExtension: "mp3")
        }
    
        class func playEnterButtonSound() {
    
            registerAndPlaySoundForFile(fileName: "EnterButtonSound", fileExtension: "mp3")
        }
    
        private class func registerAndPlaySoundForFile(fileName: String, fileExtension: String, withVibration: Bool = true) {
    
            let bundle = Bundle.main
            guard let url = bundle.url(forResource: fileName, withExtension: fileExtension) else {
                return
            }
            do {
                try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient)
                try AVAudioSession.sharedInstance().setActive(true)
                            objPlayer = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)
                guard let aPlayer = objPlayer else { return }
                aPlayer.play()
    
            } catch let error {
                print(error.localizedDescription)
            }
        }
    }
    

    registerAndPlaySoundForFile是负责播放声音的主要方法! 您可以像SoundManager.playEnterButtonSound() 一样使用它。你可以像这样在这个类中创建多个方法。

    【讨论】:

      【解决方案4】:

      如果您想在您的 iOS 应用程序中播放声音,请停止您正在做的事情。扔掉关于 swifts 内置音频服务的手册并使用框架。

      AudioKit 是一个令人难以置信的强大框架,由一些非常称职的音频程序员构建。这个库有一个很好的 API,有很好的文档并且非常强大。他们有很多示例应用程序,包括帮助您入门的示例代码。如果您只想播放声音,您将被覆盖。如果您想构建粒度合成器,您也将被覆盖。

      特别是如果您是编程新手,通常有人会为您完成艰苦的工作。不要重新发明轮子!

      【讨论】:

      • 我一直在学习 Udemy 课程,这就是他们展示的方式。如果您知道学习如何编码的更好方法,我很乐意尝试 :) 谢谢您的建议。
      • 太好了,请确保您查看开源应用程序。我发现 udemy 非常适合让您站起来,但有时会向您介绍在专业环境中无法接受的坏习惯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-19
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 2015-12-17
      相关资源
      最近更新 更多