【问题标题】:Play background music in app?在应用程序中播放背景音乐?
【发布时间】:2023-11-09 00:49:01
【问题描述】:

我希望用户能够打开应用并开始播放音乐。我希望用户能够转到任何视图控制器并返回到最初的视图控制器而不会停止音乐。我希望它无限循环。

我已尝试放入初始视图控制器的viewDidLoad 方法以使其开始播放。发生的情况是,用户离开初始视图控制器,当他们回来时,音乐再次开始播放,与原始副本重叠。

为了解决这个问题,我放置了一个 if 语句来检查声音是否已经在播放而不启动另一个副本,并且 viewDidLoad 方法完全忽略了 if 语句并再次播放它。我也尝试使用viewDid/WillAppear。我尝试将声音放在 applicationDidLaunchWithOptions 方法中的应用程序委托中,但我完全静默。

【问题讨论】:

    标签: ios swift audio avfoundation avaudioplayer


    【解决方案1】:

    使用单例也可以:

    Swift 3 或更高版本

    import AVFoundation
    
    class MusicHelper {
        static let sharedHelper = MusicHelper()
        var audioPlayer: AVAudioPlayer?
        
        func playBackgroundMusic() {
            let aSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "coolsong", ofType: "mp3")!)
            do {
                audioPlayer = try AVAudioPlayer(contentsOf:aSound as URL)
                audioPlayer!.numberOfLoops = -1
                audioPlayer!.prepareToPlay()
                audioPlayer!.play()
            } catch {
                print("Cannot play the file")
            }
        }
    }
    

    Swift 2.2.1 或更早版本

    import AVFoundation
    
    class MusicHelper {
        static let sharedHelper = MusicHelper()
        var audioPlayer: AVAudioPlayer?
        
        func playBackgroundMusic() {
            let aSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("coolsong", ofType: "mp3")!)
            do {
                audioPlayer = try AVAudioPlayer(contentsOfURL:aSound)
                audioPlayer!.numberOfLoops = -1
                audioPlayer!.prepareToPlay()
                audioPlayer!.play()
            } catch {
                print("Cannot play the file")
            }
        }
    }
    

    然后你可以在任何类中使用它(根据 Swift 2.1)

    MusicHelper.sharedHelper.playBackgroundMusic()
    

    【讨论】:

    • 显式展开选项是一种不好的做法。
    • @hamitron 为什么显式展开是一种不好的做法?谢谢
    【解决方案2】:

    这就是我的做法。在您希望开始播放音乐的课堂场景之外的任何地方添加此代码。你甚至可以创建一个全新的 Swift 文件,然后在其中添加这段代码(导入 AVFoundation)

    var backgroundMusicPlayer: AVAudioPlayer!
    
    func playBackgroundMusic(filename: String) {
    
        //The location of the file and its type
        let url = NSBundle.mainBundle().URLForResource(filename, withExtension: "mp3")
    
        //Returns an error if it can't find the file name
        if (url == nil) {
            println("Could not find the file \(filename)")
        }
    
        var error: NSError? = nil
    
        //Assigns the actual music to the music player
        backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
    
        //Error if it failed to create the music player
        if backgroundMusicPlayer == nil {
        println("Could not create audio player: \(error!)")
        return
        }
    
        //A negative means it loops forever
        backgroundMusicPlayer.numberOfLoops = -1
        backgroundMusicPlayer.prepareToPlay()
        backgroundMusicPlayer.play()
    }
    

    完成后,转到 didMoveToView 函数并使用文件名调用该函数。

    playBackgroundMusic("IntroMusic")
    

    我刚刚测试过,切换场景后效果很好。

    【讨论】:

    • 你在哪里定义了didMoveToView函数?
    • 抱歉回复晚了,但它是超类 SKScene 的功能。当应用程序移动到该视图时调用它。基本上在准备场景时会调用 didMoveToView。所以如果你想要你的类中的函数,它必须被覆盖 func didMoveToView()
    【解决方案3】:

    Swift 4.2 更新

    第 1 步。创建一个新类“MusicHelper”

    第 2 步。从下面复制并粘贴代码

    import AVFoundation
    
    class MusicHelper {
    static let sharedHelper = MusicHelper()
    var audioPlayer: AVAudioPlayer?
    
    func playBackgroundMusic() {
        let aSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "MUSICNAME(replece file name)", ofType: "mp3")!)
        do {
            audioPlayer = try AVAudioPlayer(contentsOf:aSound as URL)
            audioPlayer!.numberOfLoops = -1
            audioPlayer!.prepareToPlay()
            audioPlayer!.play()
        }
        catch {
            print("Cannot play the file")
        }
    }
    

    第 3 步。将下面的代码复制并粘贴到您的视图控制器中

    import AVFoundation  //import at the top
    
    var player: AVAudioPlayer?  //declare in code
    
    MusicHelper.sharedHelper.playBackgroundMusic() //paste in viewDidLoad
    

    【讨论】:

    • 如果这条评论不适用于 Swift 5,请回复。我会尝试更新它。
    【解决方案4】:

    只需添加“numberofLoops = -1”,它就会在后台无限播放。

    示例(斯威夫特):

    func playBackgroundMusic() {
        do {
            if let bundle = NSBundle.mainBundle().pathForResource("someMP3file", ofType: "mp3") {
                let alertSound = NSURL(fileURLWithPath: bundle)
                try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
                try AVAudioSession.sharedInstance().setActive(true)
                try audioPlayer = AVAudioPlayer(contentsOfURL: alertSound)
                audioPlayer.numberOfLoops = -1
                audioPlayer.prepareToPlay()
                audioPlayer.play()
    
            }
        } catch {
            print(error)
        }
    }
    

    玩得开心。

    【讨论】:

      【解决方案5】:

      找到了解决办法。我声明了一个名为 signal 的视图控制器属性。我说信号:布尔? - 然后在 viewDidLoad 我放了一个 if 语句,如果信号 == nil 则只播放背景歌曲。然后,在我的其他视图控制器中,我将其设置为当它们返回主视图控制器时,信号属性 = false。然后,歌曲将不再播放,一切正常。

      【讨论】:

        【解决方案6】:

        对于 Swift 4:

        func playBackgroundMusic() {
                let aSound = NSURL(fileURLWithPath: Bundle.main.path(forResource: "music", ofType: "mp3")!)
                do {
                    audioPlayer = try AVAudioPlayer(contentsOf:aSound as URL)
                    audioPlayer!.numberOfLoops = -1
                    audioPlayer!.prepareToPlay()
                    audioPlayer!.play()
                } catch {
                    print("Cannot play the file")
                }
            }
        

        【讨论】:

          【解决方案7】:

          解决了 ALHAMDULELLAH 仅更改 Xcode 设置的问题

          进入设置页面>>功能>>背景>>模式>>允许音频文件

          【讨论】:

            【解决方案8】:

            我认为您应该尝试在 AppDelegate.swift 文件中。 在方法 application(.....didFinishLaunchingWithOptions.....){} 中定义您的 AVAudioPlayer() 和 .play()

            【讨论】: