使用AVAudioPlayer播放声音


73

我正在尝试播放声音,AVAudioPlayer但无法正常工作。

编辑1:仍然行不通。

编辑2:此代码有效。我的设备处于静音模式。

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("button-09", ofType: "wav"))
        println(alertSound)

        var error:NSError?
        audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }
}

2
nil为何不传递某些错误而不是将错误传递给错误参数,以找出错误的实质呢?
Michael Dautermann 2014年

错误包含零
user3722523

我实际上在为osx应用程序使用与您完全相同的代码,并且除错误代码似乎本身引发某种错误外,其他所有方法均有效:“致命错误:在解开可选值时意外发现nil”,这导致我认为错误声明有问题。我对迅速的错误了解不多,但这是您以前遇到过的事情吗?
Uzebeckatrente,2015年

@Uzebeckatrente-检查您是否未使用NSURL(string:...)。在某些情况下,由于某种原因,它返回nil。您应该将NSURL(fileURLWithPath:...)用于文件位置。
djb 2015年

9
哈哈哈...静音模式的荣誉!
animal_chin 2015年

Answers:


63

对您的代码进行了修改:

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("button-09", ofType: "wav"))
        println(alertSound)

        // Removed deprecated use of AVAudioSessionDelegate protocol
        AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
        AVAudioSession.sharedInstance().setActive(true, error: nil)

        var error:NSError?
        audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    }

}

Swift 3和Swift 4.1:

import UIKit
import AVFoundation

class ViewController: UIViewController {
    private var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: "button-09", ofType: "wav")!)
        print(alertSound)

        try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try! AVAudioSession.sharedInstance().setActive(true)

        try! audioPlayer = AVAudioPlayer(contentsOf: alertSound)
        audioPlayer!.prepareToPlay()
        audioPlayer!.play()
    }
}

1
嗨,我正在尝试使用大约相同的代码向我的程序添加声音,并且它崩溃了。您将音频文件放在哪里?在资产文件夹中还是..?
skyguy

2
@skyguy,您可以将声音文件拖到您的项目中,然后选择要添加的适当目标。
vladof81

关于如何将其用于pls或远程mp3文件的任何想法?
danielsalare 2014年

1
“该AVplayer不流媒体提供支持,你可以用AVPlayer stackoverflow.com/questions/3635792/...
houguet皮埃尔

1
是否需要为AVAudioPlayer要播放的每个声音文件创建一个新的实例?
提交

36

根据Swift 2的代码应该是

var audioPlayer : AVAudioPlayer!

func playSound(soundName: String)
{
    let coinSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(soundName, ofType: "m4a")!)
    do{
        audioPlayer = try AVAudioPlayer(contentsOfURL:coinSound)
        audioPlayer.prepareToPlay()//there is also an async version
        audioPlayer.play()
    }catch {
        print("Error getting the audio file")
    }
}

20
您应该将audioPlayer设置为某个实例变量。调用.play()后,此代码将立即释放该代码,您将不会听到任何声音。
scrrr

该应用程序还会略有滞后,因为它需要立即加载文件并准备播放器。
AppreciateIt


12

该解决方案适用于AudioPlayer,它在导航栏中具有播放/暂停/停止按钮作为栏按钮项目

在Swift 2.1中,您可以使用以下代码

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var player:AVAudioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
            super.viewDidLoad()

            let audioPath = NSBundle.mainBundle().pathForResource("ARRehman", ofType: "mp3")
            var error:NSError? = nil
            do {
                player = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioPath!))
            }
            catch {
                print("Something bad happened. Try catching specific errors to narrow things down")
            }

        }

    @IBAction func play(sender: UIBarButtonItem) {
        player.play()

    }


    @IBAction func stop(sender: UIBarButtonItem) {
        player.stop()
        print(player.currentTime)
        player.currentTime = 0
    }


    @IBAction func pause(sender: UIBarButtonItem) {

        player.pause()
    }


    @IBOutlet weak var sliderval: UISlider!


    @IBAction func slidermov(sender: UISlider) {

        player.volume = sliderval.value
        print(player.volume)
    }

}

7

这将工作...

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var ding:AVAudioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        prepareAudios()
        ding.play()
    }

    func prepareAudios() {

        var path = NSBundle.mainBundle().pathForResource("ding", ofType: "mp3")
        ding = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: path!), error: nil)
        ding.prepareToPlay()
    }
}

1
“这将起作用”但是为什么会起作用?请解释一下OP的问题以及如何解决它,以便将来的用户了解其背后的概念。
Prudhvi 2015年

2

使用此功能可以在Swift中发出声音(可以在需要发出声音的地方使用此功能。)

首先添加SpriteKit和AVFoundation框架。

import SpriteKit
import AVFoundation
func playEffectSound(filename: String){
     runAction(SKAction.playSoundFileNamed("\(filename)", waitForCompletion: false))
}// use this function to play sound

playEffectSound("Sound File Name With Extension")
// Example :- playEffectSound("BS_SpiderWeb_CollectEgg_SFX.mp3")

1
这可能会“起作用”,但不会预加载音频,并且在首次执行时会导致性能降低
Ray

2

这是一个非常老的问题,但是我没有看到适用于Swift 3.0的答案,因此我对代码进行了现代化处理并添加了一些安全检查以防止崩溃。

我还采取了将演奏部分发挥作用的方法,以帮助遇到此问题的任何人重复使用。

import UIKit
import AVFoundation

class ViewController: UIViewController {
    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        play(for: "button-09", type: "wav")
    }

    func play(for resource: String, type: String) {
        // Prevent a crash in the event that the resource or type is invalid
        guard let path = Bundle.main.path(forResource: resource, ofType: type) else { return }
        // Convert path to URL for audio player
        let sound = URL(fileURLWithPath: path)
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: sound)
            audioPlayer?.prepareToPlay()
            audioPlayer?.play()
        } catch {
            // Create an assertion crash in the event that the app fails to play the sound
            assert(false, error.localizedDescription)
        }
    }
}

将audioPlayer
设为

2

从Swift 4.2开始,AudioSession类别设置选项已更改。(尝试从Swift 4.2开始使用以下代码)

import UIKit
import AVFoundation


class ViewController: UIViewController {


    var audioPlayer: AVAudioPlayer?

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


    func prepareAudioSession() -> Void {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
            try AVAudioSession.sharedInstance().setActive(true)

            prepareAudioPlayer()

        } catch {
            print("Issue with Audio Session")
        }
    }


    func prepareAudioPlayer() -> Void {

        let audioFileName = "test"
        let audioFileExtension = "mp3"

        guard let filePath = Bundle.main.path(forResource: audioFileName, ofType: audioFileExtension) else {
            print("Audio file not found at specified path")
            return
        }

        let alertSound = URL(fileURLWithPath: filePath)
        try? audioPlayer = AVAudioPlayer(contentsOf: alertSound)
        audioPlayer?.prepareToPlay()
    }


    func playAudioPlayer() -> Void {
        audioPlayer?.play()
    }


    func pauseAudioPlayer() -> Void {
        if audioPlayer?.isPlaying ?? false {
            audioPlayer?.pause()
        }
    }


    func stopAudioPlayer() -> Void {
        if audioPlayer?.isPlaying ?? false {
            audioPlayer?.stop()
        }
    }

    func resetAudioPlayer() -> Void {
        stopAudioPlayer()
        audioPlayer?.currentTime = 0
        playAudioPlayer()
    }

}

我在prepareAudioSession函数中出错...您在iOS 12中遇到过此问题吗?
Hardik Thakkar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.