Swift AVAudioPlayer (Xcode) - 在应用程序包外播放音频文件
Posted
技术标签:
【中文标题】Swift AVAudioPlayer (Xcode) - 在应用程序包外播放音频文件【英文标题】:Swift AVAudioPlayer (Xcode) - Play Audio File Outside Application Bundle 【发布时间】:2019-06-11 09:28:21 【问题描述】:在我的 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 的文件路径(包含在应用程序包中)传递给 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 库设计用于访问应用程序资产和捆绑媒体文件,以及来自互联网的流媒体。但它无法播放目录中的媒体。
我找到了几个关于这个问题的帖子,都是不完整或没有答案的,例如:https://forums.developer.apple.com/thread/18272
如果 AVKit 不能做我认为它应该做的事情,我可以使用什么库或方法来访问目录文件? OSX 的音乐播放器应用程序当然能够提示用户扫描目录和访问音乐文件。他们是怎么做到的?
【问题讨论】:
【参考方案1】:看来问题出在这里:
guard let filePath = filePathOptional else
print("ERROR: Failed to retrieve music file Path")
return
请将打印改为:
print("ERROR: Failed to retrieve music file Path \(error.localizedDescription)")
我想您会发现问题在于您无权访问此文件。 默认情况下,您只能访问应用程序和桌面文件夹的沙盒。
同时尝试将您的文件放到桌面并播放。
【讨论】:
我尝试将文件放在桌面上,但同样的事情发生了。然后我尝试根据在应用程序包中的格式化方式自行将 filePath 格式化为 fileURL,并将其传递给初始化程序。正如我推测的那样,似乎无法使用捆绑包之外的 URL 初始化 audioPlayer。如果确实是访问权限问题,我会尝试要求访问权限。 我们更正了,我已经捕获了错误消息并将其打印到控制台。它说“permErr:权限错误(打开文件时)”。然后我进一步阅读了 Apple 文档,结果发现出于隐私原因启用了 Sanboxing。禁用 Sanboxing 是一个选项,但这意味着您不能再将应用程序提交到应用程序商店。正确的解决方案是导入文件/目录 uisng NSOpenPanel。谢谢!以上是关于Swift AVAudioPlayer (Xcode) - 在应用程序包外播放音频文件的主要内容,如果未能解决你的问题,请参考以下文章
将 AirPlay 添加到 AVAudioPlayer (Swift)