[英]How to play NSData from Core Data in AVAudioPlayer
我將 mp3 文件作為 NSData 二進制數據保存到 Core Data 中。 然后我在NSFetchedResultsController
幫助下加載這個文件。 然后我編寫了以下代碼,但出現錯誤。 我該如何解決?
致命錯誤:在解開 Optional 值時意外發現 nil
var audioPlayer = AVAudioPlayer()
func play() {
if musicData != nil {
audioPlayer = AVAudioPlayer(data: musicData, error: nil)
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
}
更新我檢查了它,我看到AVAudioPlayer
為零,但我在這門課的開頭初始化了這個播放器。
我仍然更改了代碼,但出現相同的錯誤 第二種方法
var av = AVAudioPlayer()
func play() {
let object = fetchedResultsController.fetchedObjects?.first as! Entity
let songData = object.mp3
var urlData: NSURL!
songData.writeToURL(urlData, atomically: true)
av = AVAudioPlayer(contentsOfURL: urlData, error: nil)
av.prepareToPlay()
av.play()
}
我添加了文件類型提示,它對我有用。
func playMusic() {
let url = NSBundle.mainBundle().URLForResource("Music", withExtension: "mp3")!
let data = NSData(contentsOfURL: url)!
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
audioPlayer = AVAudioPlayer(data: data, fileTypeHint: AVFileTypeMPEGLayer3, error: nil)
audioPlayer.prepareToPlay()
audioPlayer.play()
}
從 Core Data 播放 mp3 文件時遇到了同樣的問題。 還有另一種解決方案,它不需要您制作資源,而只需要文件管理器。 適用於 Swift 5:
final class AudioPlayer: AVPlayer, ObservableObject {
private func changeSong(with newSong: Song) { // struct Song has function findInDatabase, which can return saved data from CoreData (or error)
// trying to find song in CoreData
newSong.findInDatabase() { (result: Result<SavedSong, CoreDataError>) in
switch result {
case .success(let savedSong):
// SavedSong struct has variable 'file' which is of type Data
guard let songFile = savedSong.file, !songFile.isEmpty else {
// your error handling
return
}
guard var localURL = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first else { return } // or error handling
localURL.appendPathComponent("song.mp3")
try! songFile.write(to: localURL) // saving song data in url
// now just playing from created URL
let nextPlayerItem = AVPlayerItem(url: localURL)
self.replaceCurrentItem(with: nextPlayerItem) // 'self' - is AVPlayer instance
self.play()
case .failure( _):
// error handling, for example try to play from URL
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.