iOS音频播放之AudioQueue(终结篇):缓存系统的实现

本文介绍了iOS音频播放使用AudioQueue服务实现缓存系统,包括缓存系统的设计演变、实现细节,如缓存文件命名、播放器初始化、Seek操作等。并提供了示例程序,展示如何在播放、暂停、进度条拖动等场景下使用缓存系统。
摘要由CSDN通过智能技术生成

对于移动开发来说,省流量是必须的。前三篇讲了用AudioQueue来编写流媒体播放,但是缓存的重要不言而喻。有网络的时候可以使用网络播放,没网络的时候就可以利用缓存播放。实现离线播放。本次的实现是当有缓存的时候使用缓存播放,没有缓存的时候才联网去请求数据。

缓存系统的设计

当时在考虑这个的时候,我一直想以一种简单的方式来实现,从当初的构思到实现,总共经过三次变化。

第一次设计

在我看来,音频缓存的难点应该是在于Seek操作的时候,因为中间都是空的,在Linux中,称做“空洞文件”。怎么样才能对应起来呢?我的想法是从http的响应头中,拿到整个文件的长度,然后在硬盘中创建一个同等大小的文件,文件内容设置为空,然后再配置一个描述文件,用于描述该文件已经缓存好的字节段,如果以后再有缓存好的字节段,再进行合并。最终描述文件中只剩一个段,即0到fileLen[文件长度]。

第二次设计

第一次设计想法我觉得是可以的,但是实现有点难,于是我在想,能不能把这个描述文件去掉,利用文件本身来描述自己哪些部分已经下载了,哪些部分未下载呢?我试过使用一个0或者EOF(-1)来描述,基本功能都已经实现了,但是我却忽略了一个问题,我是以二进制的方法读入文件的,文件本身也包含EOF(-1),看来这种想法也行不通。看来还是需要一个描述文件。

第三次设计

既然以我目前的设计,依旧无法省略描述文件,也不能利用文件结束符,那么我可以简化描述文件的结构,并由此定义描述文件(desc),一个和音频文件等长的描述文件,用于记录音频缓存中对应字节的数据是否已经下载成功,如果下载成功,则将该们置置为1,初始为0,这样做的好处是编码简单,但是缺点就是音频文件有多大,就增加了一个与音频等长的描述文件。可以说是以空间换复杂度吧。根据该设计,最终完成了一个基本的缓存系统。

缓存系统的实现

缓存文件的命名

首先,缓存文件当然是存放在硬盘上的,在这里,我使用一般的常规方法,即利用url的md5字符串来做文件名,最终在缓存目录中会生成两个文件,即音频文件和描述文件,如图所示:
音频文件和描述文件

相关代码如下所示:
md5加密
这段代码利用了iOS自带的CommonCrypto中的CC_MD5方法进行加密。。如果url中带有文件的后缀名,那么就从url上截取,如果没有,那么默认为mp3。如下所示:

初始化方法
但是有个问题,即使url中没有后缀,但是仍可以以.*结尾,所以我这里就自定义了几个常见的后缀。

init方法里只是计算了文件名,并没有创建文件,应该什么时候创建音频文件和描述文件呢?可以试想想,如果没有网络请求的时候,缓存文件也根本用不着,而且没有网络请求,也根本无法知道文件到底有多长。所以缓存文件的建立或打开,应该放到第一次网络请求之后。建立的过程如下所示:

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值