[英]How can I play a sound from the asset catalog using AVAudioPlayerNode?
I'm trying to use an AVAudioPlayerNode
to play sounds from the Assets.xcassets
asset catalog, but I can't figure out how to do it. 我正在尝试使用
AVAudioPlayerNode
来播放Assets.xcassets
资产目录中的声音,但我无法弄清楚如何去做。
I've been using AVAudioPlayer
, which can be initialized with an NSDataAsset
like this: 我一直在使用
AVAudioPlayer
,它可以用这样的NSDataAsset
初始化:
let sound = NSDataAsset(name: "beep")!
do {
let player = try AVAudioPlayer(data: sound.data, fileTypeHint: AVFileTypeWAVE)
player.prepareToPlay()
player.play()
} catch {
print("Failed to create AVAudioPlayer")
}
I want to use an AVAudioPlayerNode
instead (for pitch shifting and other reasons). 我想改用
AVAudioPlayerNode
(用于音高变换等原因)。 I can create the engine and hook up the node OK: 我可以创建引擎并连接节点OK:
var engine = AVAudioEngine()
func playSound(named name: String) {
let mixer = engine.mainMixerNode
let playerNode = AVAudioPlayerNode()
engine.attach(playerNode)
engine.connect(playerNode, to: mixer, format: mixer.outputFormat(forBus: 0))
// play the file (this is what I don't know how to do)
}
It looks like the method to use for playing the file is playerNode.scheduleFile()
. 看起来用于播放文件的方法是
playerNode.scheduleFile()
。 It takes an AVAudioFile
, so I thought I'd try to make one. 它需要一个
AVAudioFile
,所以我想我会尝试制作一个。 But the initializer for AVAudioFile
wants a URL. 但是
AVAudioFile
的初始化程序需要一个URL。 As far as I can tell, assets in the asset catalog are not available by URL. 据我所知,资产目录中的资产不能通过URL获得。 I can get the data directly using
NSDataAsset
, but there doesn't seem to be any way to use it to populate an AVAudioFile
. 我可以使用
NSDataAsset
直接获取数据,但似乎没有任何方法可以使用它来填充AVAudioFile
。
Is it possible to play sounds from the asset catalog with an AVAudioPlayerNode
? 是否可以使用
AVAudioPlayerNode
播放资产目录中的声音? And if so, how? 如果是这样,怎么样?
OK so your problem is that you would like to get a URL
from a file in your Asset catalog right? 好的,你的问题是你想从资产目录中的文件中获取一个
URL
吗?
I've looked around but only found this answer 我环顾四周但却发现了这个答案
As it says 正如它所说
It basically just gets image from assets, saves its data to disk and return file URL
它基本上只是从资产中获取图像,将其数据保存到磁盘并返回文件URL
You should probably change it to look for MP3 files (or WAV or whatever you prefer, maybe that could be an input parameter) 您应该更改它以查找MP3文件(或WAV或您喜欢的任何内容,也许这可能是输入参数)
So you could end up with something like: 所以你最终会得到类似的东西:
enum SoundType: String {
case mp3 = "mp3"
case wav = "wav"
}
class AssetExtractor {
static func createLocalUrl(forSoundNamed name: String, ofType type: SoundType = .mp3) -> URL? {
let fileManager = FileManager.default
let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let url = cacheDirectory.appendingPathComponent("\(name).\(type)")
guard fileManager.fileExists(atPath: url.path) else {
guard
let image = UIImage(named: name),
let data = UIImagePNGRepresentation(image)
else { return nil }
fileManager.createFile(atPath: url.path, contents: data, attributes: nil)
return url
}
return url
}
}
Maybe a bit far fetched but I haven't found any other options. 也许有点牵强,但我还没有找到任何其他选择。
Hope that helps you. 希望对你有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.