2

我試圖使用AVAudioPlayerNode播放Assets.xcassets資產目錄中的聲音,但我無法弄清楚如何操作。如何使用AVAudioPlayerNode從資產目錄播放聲音?

我一直在使用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") 
} 

我想用一個AVAudioPlayerNode,而不是(對變調等原因)。我可以創建發動機和掛鉤節點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) 
} 

它看起來像使用的方法爲播放文件是playerNode.scheduleFile()。這需要一個AVAudioFile,所以我想我會嘗試做一個。但AVAudioFile的初始化程序需要一個URL。據我所知,資產目錄中的資產不能通過URL獲得。我可以直接使用NSDataAsset獲取數據,但似乎沒有辦法使用它來填充AVAudioFile

是否可以使用AVAudioPlayerNode播放資產目錄中的聲音?如果是這樣,怎麼樣?

回答

0

好的,您的問題是您希望從Asset目錄中的文件中獲得URL

我環顧四周,但只找到this answer

,因爲它說

它基本上只是會從資產圖像​​,保存數據到磁盤,返回文件的URL

你可能應該改變它尋找MP3文件(或WAV或任何你喜歡的,也許這可能是一個輸入參數)

所以,你可能最終的東西,如:

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 
    } 
} 

也許有點牽強,但我還沒有發現任何其他選項。

希望能幫到你。