检查 mp3 是否可以在 swift 中播放
Check if mp3 is playable in swift
我正在尝试下载和播放远程 mp3。
基本上:
- 用户点击 mp3,
- 后台开始下载
- 然后,如果可能,开始播放。
几乎一切正常 - 下载由 AFHTTPRequestOperation
执行,它将 mp3 直接下载到文件中,我每隔 1000 字节 左右获得进度更新。
The problem is I don't know exactly when to start playback via
AVAudioPlayer
.
AVAudioPlayer
可以播放未完成的 mp3,但如果没有足够的数据,它会触发 fatalError (EXC_BREAKPOINT) 并且我的应用程序崩溃
- it doesn't even return an error.
我预先知道 mp3 的持续时间,我可以从中确定大约。下载了多少秒的回放,如 - (sizeDownloaded/totalSize)*duration
,但这很愚蠢,有时会失败(我猜是因为文件开头有 ID3 标签,它可以包含巨大的图像我的近似值毫无意义)。
我当前的代码:
op.setDownloadProgressBlock({bytesRead, totalBytesRead, totalBytesExpectedToRead in
let approxBytesForOneSecond = totalBytesExpectedToRead/Int64(downloadableItem.length)
let approxSecondsDownloaded = totalBytesRead/approxBytesForOneSecond
if approxSecondsDownloaded > kMinimumSecondsDownloadedForPlay { //min. secs = 5
var error: NSError?
self.player = AVAudioPlayer(contentsOfURL: url, error: &error) // This is the line where I sometimes get EXC_Breakpoint. The reason for this is that the mp3 is not playable yet ...
if (error != nil) {
// Error initializing item - never called
} else {
// Item initialized OK -> Play
}
}
})
那么,是否有一些可靠的方法可以确定文件是否可以播放?
我知道提高播放开始的限制会有所帮助,但似乎不对。 "wait until download is finished" 不是答案...:)
非常感谢!
知道 mp3 文件的比特率可以让您估计需要多少文件才能安全地开始播放,但是谁知道 AVAudioPlayer
如果文件在打开后发生变化,会发生什么是吗?
如果播放完后不需要保留mp3,可以从只能播放本地文件的AVAudioPlayer
切换到也可以播放的AVPlayer
从互联网流式传输的文件:
var url = NSURL(string:"http://YOUR_URL")
player = AVPlayer(URL:url)
player.play()
一旦有足够的数据可用于持续播放,它将立即播放。
如果你想保留 AVPlayer
正在播放的流字节,事情会变得更复杂,但可以通过 AVAssetResourceLoader
实现,详见 this blog post
更新
如果您想在后台下载多个文件,那就去做吧!您仍然可以通过 AVAssetResourceLoader
将数据交给 AVPlayer
,AVPlayer
将决定何时有足够的数据进行播放(这就是您所说的可播放的意思吗?)
我明白了。此函数 returns 错误,如果文件不可播放(无论出于何种原因)。在我的测试中,它成功地为完全没有音频数据的不完整文件返回 false,如果至少有东西可以播放(无论文件是否不完整)则返回 true。在我看来,这与 AVAudioPlayer/AVPlayer 使用的功能相同。它在 Obj-C 中,我还没有在 swift 中重写它,因为我不确定它是否会泄漏...
+ (BOOL) isFilePlayable:(NSURL*)url {
// Try opening audiofile -> if it's playable it will open, if not, it will return error
AudioFileID audioFileID;;
OSErr err;
err = AudioFileOpenURL((__bridge CFURLRef)url,
kAudioFileReadPermission,
0,
&audioFileID);
if (err != noErr) {
NSLog(@"Couldn't open audio file...");
return NO;
}
AudioFileClose(audioFileID);
return YES;
}
我正在尝试下载和播放远程 mp3。
基本上:
- 用户点击 mp3,
- 后台开始下载
- 然后,如果可能,开始播放。
几乎一切正常 - 下载由 AFHTTPRequestOperation
执行,它将 mp3 直接下载到文件中,我每隔 1000 字节 左右获得进度更新。
The problem is I don't know exactly when to start playback via
AVAudioPlayer
.
AVAudioPlayer
可以播放未完成的 mp3,但如果没有足够的数据,它会触发 fatalError (EXC_BREAKPOINT) 并且我的应用程序崩溃
- it doesn't even return an error.
我预先知道 mp3 的持续时间,我可以从中确定大约。下载了多少秒的回放,如 - (sizeDownloaded/totalSize)*duration
,但这很愚蠢,有时会失败(我猜是因为文件开头有 ID3 标签,它可以包含巨大的图像我的近似值毫无意义)。
我当前的代码:
op.setDownloadProgressBlock({bytesRead, totalBytesRead, totalBytesExpectedToRead in
let approxBytesForOneSecond = totalBytesExpectedToRead/Int64(downloadableItem.length)
let approxSecondsDownloaded = totalBytesRead/approxBytesForOneSecond
if approxSecondsDownloaded > kMinimumSecondsDownloadedForPlay { //min. secs = 5
var error: NSError?
self.player = AVAudioPlayer(contentsOfURL: url, error: &error) // This is the line where I sometimes get EXC_Breakpoint. The reason for this is that the mp3 is not playable yet ...
if (error != nil) {
// Error initializing item - never called
} else {
// Item initialized OK -> Play
}
}
})
那么,是否有一些可靠的方法可以确定文件是否可以播放?
我知道提高播放开始的限制会有所帮助,但似乎不对。 "wait until download is finished" 不是答案...:)
非常感谢!
知道 mp3 文件的比特率可以让您估计需要多少文件才能安全地开始播放,但是谁知道 AVAudioPlayer
如果文件在打开后发生变化,会发生什么是吗?
如果播放完后不需要保留mp3,可以从只能播放本地文件的AVAudioPlayer
切换到也可以播放的AVPlayer
从互联网流式传输的文件:
var url = NSURL(string:"http://YOUR_URL")
player = AVPlayer(URL:url)
player.play()
一旦有足够的数据可用于持续播放,它将立即播放。
如果你想保留 AVPlayer
正在播放的流字节,事情会变得更复杂,但可以通过 AVAssetResourceLoader
实现,详见 this blog post
更新
如果您想在后台下载多个文件,那就去做吧!您仍然可以通过 AVAssetResourceLoader
将数据交给 AVPlayer
,AVPlayer
将决定何时有足够的数据进行播放(这就是您所说的可播放的意思吗?)
我明白了。此函数 returns 错误,如果文件不可播放(无论出于何种原因)。在我的测试中,它成功地为完全没有音频数据的不完整文件返回 false,如果至少有东西可以播放(无论文件是否不完整)则返回 true。在我看来,这与 AVAudioPlayer/AVPlayer 使用的功能相同。它在 Obj-C 中,我还没有在 swift 中重写它,因为我不确定它是否会泄漏...
+ (BOOL) isFilePlayable:(NSURL*)url {
// Try opening audiofile -> if it's playable it will open, if not, it will return error
AudioFileID audioFileID;;
OSErr err;
err = AudioFileOpenURL((__bridge CFURLRef)url,
kAudioFileReadPermission,
0,
&audioFileID);
if (err != noErr) {
NSLog(@"Couldn't open audio file...");
return NO;
}
AudioFileClose(audioFileID);
return YES;
}