Swift AVAudioPlayer(Xcode)-在应用程序捆绑之外播放音频文件

时间:2019-06-11 09:28:21

标签: swift xcode macos avaudioplayer avkit

在我的Xcode项目中,我设置了以下代码(简化代码):

import Cocoa
import AVKit

class ViewController: NSViewController {

    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            guard let filePath = Bundle.main.path(forResource: "sample", ofType: "mp3") else {
                print("ERROR: Failed to retrieve music file Path")
                return
            }
            let fileURL = URL.init(fileURLWithPath: filePath)
            print(" PATH: \(filePath)")
            print("  URL: \(fileURL)")
            try audioPlayer = AVAudioPlayer.init(contentsOf: fileURL)
        } catch {
            print("ERROR: Failed to retrieve music file URL")
        }

        audioPlayer.play() 
    }
}

//CONSOLE PRINTS ----------:
// PATH: /Users/vakho/Library/Developer/Xcode/DerivedData/MusicPlayer-foqzsckozmcjnofvlvhuwabfssqi/Build/Products/Debug/MusicPlayer.app/Contents/Resources/sample.mp3
//  URL: file:///Users/vakho/Library/Developer/Xcode/DerivedData/MusicPlayer-foqzsckozmcjnofvlvhuwabfssqi/Build/Products/Debug/MusicPlayer.app/Contents/Resources/sample.mp3

通过首先转换为URL,我能够成功将sample.mp3的filePath(包含在应用程序捆绑包中)传递给audioPlayer。调用play()函数将播放音频文件。

但是,由于我正在创建音乐播放器应用程序,因此我希望能够播放驻留在目录文件夹(如桌面,下载文件夹等)中的音频文件。但是,当我尝试传递一个应用程序包外的音频文件的filePath,代码中断:

import Cocoa
import AVKit

class ViewController: NSViewController {

    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        do {
            let filePathOptional: String? = "/Users/vakho/Downloads/sample.mp3"
            guard let filePath = filePathOptional else {
                print("ERROR: Failed to retrieve music file Path")
                return
            }
            let fileURL = URL.init(fileURLWithPath: filePath)
            print(" PATH: \(filePath)")
            print("  URL: \(fileURL)")
            try audioPlayer = AVAudioPlayer.init(contentsOf: fileURL)
        } catch {
            print("ERROR: Failed to retrieve music file URL")
        }

        audioPlayer.play()
    }
}

//CONSOLE PRINTS ----------:
// PATH: /Users/vakho/Downloads/sample.mp3
//  URL: file:///Users/vakho/Downloads/sample.mp3
//ERROR: Failed to retrieve music file URL

//ERRORS ----------:
//  (lldb)
//  Thread 1: EXC_BAD_ACCESS (code=1, address=0x38)

根据我的结论,AVAudioPlayer和AVKit库设计用于访问应用程序资产和捆绑媒体文件,以及来自Internet的流媒体。但是它无法播放目录中的媒体。

我发现了有关此问题的多个线索,全部未完成或未答复,例如:https://forums.developer.apple.com/thread/18272

因此,如果AVKit无法执行我认为应该拥有的功能,我可以使用哪种库或方法来访问目录文件? OSX的音乐播放器应用程序当然能够提示用户扫描目录并访问音乐文件。他们怎么样?

1 个答案:

答案 0 :(得分:0)

似乎问题出在这里

guard let filePath = filePathOptional else {
    print("ERROR: Failed to retrieve music file Path")
    return
}

请将打印内容更改为:

print("ERROR: Failed to retrieve music file Path \(error.localizedDescription)")

我想您会发现问题在于您无权访问此文件。 默认情况下,您只能访问您的应用和桌面文件夹的沙箱。

还尝试将文件放入桌面并播放。