ios 边录音边放_iOS开发:AVPlayer实现流音频边播边存

概述

1. AVPlayer简介AVPlayer存在于AVFoundation中,可以播放视频和音频,可以理解为一个随身听

AVPlayer的关联类:AVAsset:一个抽象类,不能直接使用,代表一个要播放的资源。可以理解为一个磁带子类AVURLAsset是根据URL生成的包含媒体信息的资源对象。我们就是要通过这个类的代理实现音频的边播边下的

AVPlayerItem:可以理解为一个装在磁带盒子里的磁带

2. AVPlayer播放原理给播放器设置好想要它播放的URL

播放器向URL所在的服务器发送请求,请求两个东西所需音频片段的起始offset

所需的音频长度

服务器根据请求的内容,返回数据

播放器拿到数据拼装成文件

播放器从拼装好的文件中,找出现在需要播放的片段,进行播放

3. 边播边下的原理

实现边下边播,其实就是手动实现AVPlayer的上列播放过程。当播放器需要预先缓存一些数据的时候,不让播放器直接向服务器发起请求,而是向我们自己写的某个类(暂且称之为播放器的秘书)发起缓存请求

秘书根据播放器的缓存请求的请求内容,向服务器发起请求。

服务器返回秘书所需的数据

秘书把服务器返回的数据写进本地的缓存文件中

当需要播放某段声音的时候,向秘书发出播放请求索要这段音频文件

秘书从本地的缓存文件中找到播放器播放请求所需片段,返回给播放器

播放器拿到数据开心滴播放

当整首歌都缓存完成以后,秘书需要把缓存文件拷贝一份,改个名字,这个文件就是我们所需要的本地持久化文件

下次播放器再播放歌曲的时候,先判断下本地有木有这个名字的文件,有则播放本地文件,木有则向秘书要数据

技术实现OK,边播边下的原理知道了,我们可以正式写代码了~建议先从文末链接处把Demo下载下来,对着Demo咱们慢慢道来~

1. 类

共需要三个类:MusicPlayerManager:CEO。单例,负责整个工程所有的播放、暂停、下一曲、结束、判断应该播放本地文件还是从服务器拉数据之类的事情

RequestLoader:就是上文所说的秘书,负责给播放器提供播放所需的音频片段,以及找人向服务器索要数据

RequestTask:秘书的小弟。负责和服务器连接、向服务器请求数据、把请求回来的数据写到本地缓存文件、把写完的缓存文件移到持久化目录去。所有脏活累活都是他做。

2. 方法先从小弟说起

2.1.  RequestTask

2.1.0. 概说

如上文所说,小弟是负责做脏活累活的。 负责和服务器连接、向服务器请求数据、把请求回来的数据写到本地缓存文件、把写完的缓存文件移到持久化目录去

2.1.1. 初始化音频文件持久化文件夹 & 缓存文件private func _initialTmpFile() {

do {

try NSFileManager.defaultManager().createDirectoryAtPath(StreamAudioConfig.audioDicPath, withIntermediateDirectories: true, attributes: nil)

} catch {

print("creat dic false -- error:\(error)")

}

if NSFileManager.defaultManager().fileExistsAtPath(StreamAudioConfig.tempPath) {

try! NSFileManager.defaultManager().removeItemAtPath(StreamAudioConfig.tempPath)

}

NSFileManager.defaultManager().createFileAtPath(StreamAudioConfig.tempPath, contents: nil, attributes: nil)

}

2.1.2. 与服务器建立连接请求数据/**

连接服务器,请求数据(或拼range请求部分数据)(此方法中会将协议头修改为http)

- parameter offset: 请求位置

*/

public func set(URL url: NSURL, offset: Int) {

func initialTmpFile() {

try! NSFileManager.defaultManager().removeItemAtPath(StreamAudioConfig.tempPath)

NSFileManager.defaultManager().createFileAtPath(StreamAudioConfig.tempPath, contents: nil, attributes: nil)

}

_updateFilePath(url)

self.url = url

self.offset = offset

//  如果建立第二次请求,则需初始化缓冲文件

if taskArr.count >= 1 {

initialTmpFile()

}

//  初始化已下载文件长度

downLoadingOffset = 0

//  把stream://xxx的头换成http://的头

let actualURLComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)

actualURLComponents?.scheme = "http"

guard let URL = actualURLComponents?.URL else {return}

let request = NSMutableURLRequest(URL: URL, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringCacheData, timeoutInterval: 20.0)

//  若非从头下载,且视频长度已知且大于零,则下载offset到videoLength的范围(拼request参数)

if offset > 0 && videoLength > 0 {

request.addValue("bytes=\(offset)-\(videoLength - 1)", forHTTPHeaderField: "Range")

}

connection?.cancel()

connection = NSURLConnection(request: request, delegate: self, startImm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值