如何使用Swift播放声音?

Mic*_*sou 108 avfoundation ios swift

我想用Swift播放声音.

我的代码在Swift 1.0中运行,但现在它在Swift 2或更新版本中不再起作用了.

override func viewDidLoad() {
  super.viewDidLoad()

  let url:NSURL = NSBundle.mainBundle().URLForResource("soundName", withExtension: "mp3")!

  do { 
    player = try AVAudioPlayer(contentsOfURL: url, fileTypeHint: nil) 
  } catch _{
    return
  }

  bgMusic.numberOfLoops = 1
  bgMusic.prepareToPlay()

  if (Data.backgroundMenuPlayed == 0){
    player.play()
    Data.backgroundMenuPlayed = 1
  }
}
Run Code Online (Sandbox Code Playgroud)

Dev*_*per 225

最优选的是,您可能想要使用AVFoundation.它提供了使用视听媒体的所有必需品.

更新:根据评论中的一些人的建议,与Swift 2,Swift 3Swift 4兼容.


斯威夫特2.3

import AVFoundation

var player: AVAudioPlayer?

func playSound() {
    let url = NSBundle.mainBundle().URLForResource("soundName", withExtension: "mp3")!

    do {
        player = try AVAudioPlayer(contentsOfURL: url)
        guard let player = player else { return }

        player.prepareToPlay()
        player.play()

    } catch let error as NSError {
        print(error.description)
    }
}
Run Code Online (Sandbox Code Playgroud)

斯威夫特3

import AVFoundation

var player: AVAudioPlayer?

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

    do {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        let player = try AVAudioPlayer(contentsOf: url)

        player.play()

    } catch let error {
        print(error.localizedDescription)
    }
}
Run Code Online (Sandbox Code Playgroud)

Swift 4(iOS 12兼容)

import AVFoundation

var player: AVAudioPlayer?

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

    do {
        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)            
        try AVAudioSession.sharedInstance().setActive(true)

        /* 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.mp3.rawValue)

        /* iOS 10 and earlier require the following line:
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */

        guard let player = player else { return }

        player.play()

    } catch let error {
        print(error.localizedDescription)
    }
}
Run Code Online (Sandbox Code Playgroud)

确保更改您的曲调名称和扩展名. 需要正确导入文件(Project Build Phases> Copy Bundle Resources).您可能希望将其置于assets.xcassets更方便的位置.

对于简短的声音文件,您可能希望采用非压缩音频格式,例如,.wav因为它们具有最佳质量和较低的CPU影响.对于短声音文件来说,更高的磁盘空间消耗不应该是一个大问题.这些文件的时间越长,你可能想要去的压缩格式,如.mp3等页.检查兼容的音频格式CoreAudio.


有趣的事实:有一些简洁的小库,使播放声音更容易.:)
例如:SwiftySound

  • 我必须使AVAudioPlayer对象成为一个实例变量才能使其工作.作为局部变量,它不会播放任何内容,也不会出错.代表们也不会被召唤. (7认同)
  • 将`bgMusic = AVAudioPlayer(contentsOfURL:bgMusicURL,fileTypeHint:nil)替换为`do {bgMusic = try AVAudioPlayer(contentsOfURL:bgMusicURL,fileTypeHint:nil)} catch _ {return \\如果它不存在,请不要播放它}` (2认同)
  • 你为什么在这里使用警卫?`player = try AVAudioPlayer(contentsOf:url)guard let player = player else {return}`对我来说似乎是额外的工作,为什么不只是`让玩家=尝试AVAudioPlayer(contentsOf:url)`? (2认同)
  • 使用guard语句可以让您非常安全地因为零值而崩溃. (2认同)

小智 61

Swift 版本:5.4 及以上

import AVFoundation
var player: AVAudioPlayer?

func playSound() {
    guard let path = Bundle.main.path(forResource: "beep", ofType:"mp3") else {
        return }
    let url = URL(fileURLWithPath: path)

    do {
        player = try AVAudioPlayer(contentsOf: url)
        player?.play()
        
    } catch let error {
        print(error.localizedDescription)
    }
}
Run Code Online (Sandbox Code Playgroud)


Adi*_*oho 40

对于Swift 3:

import AVFoundation

/// **must** define instance variable outside, because .play() will deallocate AVAudioPlayer 
/// immediately and you won't hear a thing
var player: AVAudioPlayer?

func playSound() {
    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else {
        print("url not found")
        return
    }

    do {
        /// this codes for making this app ready to takeover the device audio
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        /// change fileTypeHint according to the type of your audio file (you can omit this)

        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)

        // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
        player!.play()
    } catch let error as NSError {
        print("error: \(error.localizedDescription)")
    }
}
Run Code Online (Sandbox Code Playgroud)

本地资产的最佳实践是将其放入内部assets.xcassets并加载文件,如下所示:

func playSound() {
    guard let url = Bundle.main.url(forResource: "soundName", withExtension: "mp3") else {
        print("url not found")
        return
    }

    do {
        /// this codes for making this app ready to takeover the device audio
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        try AVAudioSession.sharedInstance().setActive(true)

        /// change fileTypeHint according to the type of your audio file (you can omit this)

        /// for iOS 11 onward, use :
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)

        /// else :
        /// player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3)

        // no need for prepareToPlay because prepareToPlay is happen automatically when calling play()
        player!.play()
    } catch let error as NSError {
        print("error: \(error.localizedDescription)")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您将 `AVAudioSessionCategoryPlayback` 提供给 `setCategory`,它将确保即使手机处于锁定屏幕或静音模式也始终播放音频。`setActive` 就像告诉系统您的应用程序已准备好播放音频 (2认同)

Ton*_*ard 14

iOS 12 - Xcode 10 beta 6 - Swift 4.2

仅使用1个IBAction并将所有按钮指向该1个动作.

import AVFoundation

    var player = AVAudioPlayer()

@IBAction func notePressed(_ sender: UIButton) {

        print(sender.tag) // testing button pressed tag

        let path = Bundle.main.path(forResource: "note\(sender.tag)", ofType : "wav")!
        let url = URL(fileURLWithPath : path)

        do {
            player = try AVAudioPlayer(contentsOf: url)
            player.play()

        } catch {

            print ("There is an issue with this code!")

        }

}
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,您假设每个人都在观看“ iOS 11和Swift 4-完整的iOS应用程序开发训练营” (2认同)

Akb*_*han 13

斯威夫特 4、4.2 和 5

从 URL 和您的项目(本地文件)播放音频

import UIKit
import AVFoundation

class ViewController: UIViewController{

var audioPlayer : AVPlayer!

override func viewDidLoad() {
        super.viewDidLoad()
// call what ever function you want.
    }

    private func playAudioFromURL() {
        guard let url = URL(string: "https://geekanddummy.com/wp-content/uploads/2014/01/coin-spin-light.mp3") else {
            print("error to get the mp3 file")
            return
        }
        do {
            audioPlayer = try AVPlayer(url: url as URL)
        } catch {
            print("audio file error")
        }
        audioPlayer?.play()
    }

    private func playAudioFromProject() {
        guard let url = Bundle.main.url(forResource: "azanMakkah2016", withExtension: "mp3") else {
            print("error to get the mp3 file")
            return
        }

        do {
            audioPlayer = try AVPlayer(url: url)
        } catch {
            print("audio file error")
        }
        audioPlayer?.play()
    }

}
Run Code Online (Sandbox Code Playgroud)


Era*_*nKT 10

如果代码没有产生任何错误,但是您听不到声音,请创建播放器作为实例:

   static var player: AVAudioPlayer!
Run Code Online (Sandbox Code Playgroud)

对我来说,当我进行此更改时,第一个解决方案有效:)

  • @kuzdu这是由于您未将`player`放置在外部范围内。否则,“ player”会被本地化,因此无法播放任何声音,因为它不再存在。 (3认同)
  • 我不认为它必须是静态的(不再吗?),但似乎您在创建后就让它超出了范围,即使您已经调用play(),它也不会播放?我只是将其设为类的实例变量,并且可以正常工作。 (2认同)

小智 7

对于Swift 5AVFoundation ”\

简单的代码,无需错误处理即可从本地路径播放音频

import AVFoundation
var audio:AVPlayer!

func stopAlarm() {
    // To pause or stop audio in swift 5 audio.stop() isn't working
    audio.pause()
}

func playAlarm() {
    // need to declare local path as url
    let url = Bundle.main.url(forResource: "Alarm", withExtension: "mp3")
    // now use declared path 'url' to initialize the player
    audio = AVPlayer.init(url: url!)
    // after initialization play audio its just like click on play button
    audio.play()
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


小智 6

这很简单,完成工作!

import AVFoundation
var player: AVAudioPlayer!
            
    let url = Bundle.main.url(forResource: "sound_name", withExtension: "mp3")
     
    player = try! AVAudioPlayer(contentsOf: url!)
    player.play()
Run Code Online (Sandbox Code Playgroud)


Fat*_*tie 5

游戏风格:

文件Sfx.swift

import AVFoundation

public let sfx = Sfx.shared
public final class Sfx: NSObject {
    
    static let shared = Sfx()
    
    var apCheer: AVAudioPlayer? = nil
    // etc
    
    private override init() {
        guard let s = Bundle.main.path(forResource: "cheer", ofType: "mp3") else { print("Sfx woe"); return }
        do { apCheer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: s)) } catch { print("Sfx woe"); return }
        // etc
    }
    
    func cheer() { apCheer?.play() }
    func plonk() { apPlonk?.play() }
    func crack() { apCrack?.play() }
    // etc
}
Run Code Online (Sandbox Code Playgroud)

只需拥有其中之一...

    var apCheer: AVAudioPlayer? = nil
Run Code Online (Sandbox Code Playgroud)

对于你的每一个音频刺痛。所以你可能有 5 个、20 个、10 个,等等。

对于每一个,只需复制/粘贴两行初始化代码:

guard let s = Bundle.main.path(forResource: "cheer", ofType: "mp3") else { return print("Sfx woe") }
do { apCheer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: s)) } catch { return print("Sfx woe") }
Run Code Online (Sandbox Code Playgroud)

然后,在任何地方、任何代码、任何文件中,您都可以:

sfx.cheer()
sfx.crack()
Run Code Online (Sandbox Code Playgroud)