检查 mp3 是不是可以快速播放

Posted

技术标签:

【中文标题】检查 mp3 是不是可以快速播放【英文标题】:Check if mp3 is playable in swift检查 mp3 是否可以快速播放 【发布时间】:2015-05-15 15:16:13 【问题描述】:

我正在尝试下载和播放远程 mp3。

基本上:

    用户点击了 mp3, 从后台开始下载 然后在可能的情况下开始播放。

一切正常 - 下载由 AFHTTPRequestOperation 执行,它直接将 mp3 下载到文件中,我每隔 1000 字节 左右获得一次进度更新。

问题是我不知道何时开始播放 AVAudioPlayer.

AVAudioPlayer 可以播放未完成的 mp3,但如果没有足够的数据,它会触发 fatalError (EXC_BREAKPOINT) 并且我的应用程序崩溃

它甚至不返回错误。

我提前知道 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
        
    
)

那么,是否有一些可靠的方法可以确定文件是否可播放?

我知道提高播放开始的限制会有所帮助,但这似乎并不正确。 “等到下载完成”不是答案... :)

非常感谢!

【问题讨论】:

【参考方案1】:

知道 mp3 文件的比特率可以让您估计需要多少文件才能安全地开始播放,但是谁知道AVAudioPlayer 在打开文件后如果文件发生变化会做什么?

如果您播放完后不需要保留 mp3,您可以从只能播放本地文件的AVAudioPlayer 切换到也可以播放来自互联网的文件的AVPlayer

 var url = NSURL(string:"http://YOUR_URL")
 player = AVPlayer(URL:url)
 player.play()

只要有足够的数据可用于持续播放,它就会立即播放。

如果您想保留AVPlayer 正在播放的流式字节,事情会变得更加复杂,但可以通过AVAssetResourceLoader 实现,详见this blog post

更新 如果你想在后台下载多个文件,那就去做吧!您仍然可以通过AVAssetResourceLoader 将数据交给AVPlayerAVPlayer 将决定何时有足够的数据进行播放(这就是您所说的可播放的意思吗?)

【讨论】:

感谢您的回答!是的,这将解决问题,你是对的。但问题是它并不真正符合应用程序的概念。该应用程序旨在播放有声读物,其中有多个曲目(它们都是单独的 mp3)。通常,该应用程序会在后台下载几首曲目并仅播放其中一首,因此有两种下载方式会很混乱。另外我想知道如何检查它是否可以播放,而不是如何播放远程音频文件......但正如我所说,谢谢!这会起作用,但它并不能完全回答我的问题...... :) +1 抱歉,您没有在问题中提及多个文件。您需要定义“可玩”的含义。 没问题!我很抱歉没有提到它:) 检查我的答案 -> 我终于能弄明白了......【参考方案2】:

我想通了。如果文件不可播放(无论出于何种原因),此函数将返回错误。在我的测试中,对于完全没有音频数据的不完整文件,它成功返回 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 是不是可以快速播放的主要内容,如果未能解决你的问题,请参考以下文章

检查用户是不是在语音频道 discord.py

如何检查歌曲是否尚未添加到播放列表? (“。包含”将不起作用)

如何以编程方式检查视频或音频文件格式是不是可以在 iPhone 中播放?

检查从 torrent 下载的视频文件是不是可以播放

检查 WebView 是不是正在播放视频

如何检查音乐是不是正在从哪个音乐应用程序播放?