前言:
最近工作内容用到了语音播放,从 AVPlayer 到 AVPlayerItem, 期间遇到挺多问题,趟了很多 bug, 也总结了一些心得。对 AVPlayer 了解的更多一些,因为涉及点比较多,所以打算做一个系列详尽的写一下这部分内容。希望大家多多支持,有问题的地方欢迎指正。
AVPlayer 是一个可以播放任何格式的全功能影音播放器 支持视频格式: WMV,AVI,MKV,RMVB,RM,XVID,MP4,3GP,MPG 等。 支持音频格式:MP3,WMA,RM,ACC,OGG,APE,FLAC,FLV 等。 所以不得不说苹果亲儿子还是很强大的,是做视频开发的首选。
如何使用
AVPlayer 存在于 AVFoundation 框架,我们使用时需要导入:
import AVFoundation
几个播放相关的参数(此处暂时只说下我用到的)
在创建一个播放器之前我们需要先了解一些播放器相关的类
AVPlayer: 控制播放器的播放,暂停,播放速度 AVPlayerItem: 管理资源对象,提供播放数据源
1.创建AVPlayer
因为我这边播放,需要播放、暂停、重新播放、进度条拖动播放,所以我这边使用了AVPlayerItem
if let url = URL(string: "http://img.youluwx.com/qa/20200917/video/c94869f4-0ddc-4e45-be7e-b0620acc544d.mp3") {
let playerItem = AVPlayerItem(url: url)
let play = AVPlayer(playerItem: playerItem)
}
1.2 音频播放、暂停
player.play()
player.pause()
1.3 重新播放
重新播放就是,先把进度调整到开始,然后播放
let seekTime = CMTime(value: CMTimeValue(0), timescale: 1)
player.seek(to: seekTime, completionHandler: { _ in
})
player.play()
1.3 进度条拖动播放
此处使用 UISlider滑杆来拖动使用 Swift 使用 UISlider
let playTime = slider.value * duration
let seekTime = CMTime(value: CMTimeValue(playTime), timescale: 1)
player.seek(to: seekTime, completionHandler: { _ in
})
1.4 播放进度监听
let playerItem = AVPlayerItem(url: url)
let player = AVPlayer(playerItem: playerItem)
player.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 1), queue: DispatchQueue.main) { time in
if let duration = self.playerItem?.duration {
let nowDuration = CMTimeGetSeconds(duration)
let currentTime = Int(time.seconds)
let text = "\(currentTime)/\(nowDuration)\""
let progress = Float(currentTime) / Float(nowDuration)
print("text:\(text) progress:\(progress)")
}
}
2.遇到的问题
2.1 获取网络音频总时间
使用 AVPlayer 播放网络流媒体,发现一个坑: 就是 playerItem.duration 有可能不返回该网络多媒体资源的播放总时间长度,而是返回了一个奇怪的数据:nan, 因为我通过 CMTimeGetSeconds (playerItem.duration) 得到的一直是 nan,只有在监听播放进度,开始播放之后才能拿到数据
let playerItem = AVPlayerItem(url: url)
if let duration = playerItem?.duration {
print(CMTimeGetSeconds(duration))
}
而几经周折费劲,发现 CMTimeGetSeconds (playerItem.asset.duration) 返回的却是该网络多媒体资源的正确的播放总时间长度.
let playerItem = AVPlayerItem(url: url)
if let duration = playerItem?.asset.duration {
print(CMTimeGetSeconds(duration))
}
最后,总时间可能和播放时间差那么一点,这点一直没搞明白,有知道的大佬麻烦留个言
最大的问题
在最后的测试期间,遇到了更加严重的问题,我发现我们的语音有一部分能播放,另外一部分不能播放, 可播放语音
http://img.youluwx.com/qa/20200917/video/c94869f4-0ddc-4e45-be7e-b0620acc544d.mp3
不可播放语音
http://img.youluwx.com/qa/20201110/video/47e36af4-8fc2-432f-b7c6-ccd982140694.mp3
我分别下载下来音频文件对比: 不能播放在 Safari 浏览器中打开显示如下,能播放的就暂不展示了 具体原因应该是AVPlayer不支持吧,至于更加具体的问题:可能是因为我太菜了吧,找不到问题所在, 也没找到具体解决办法,只能借用其他视频播放器暂时使用了 嗯,最后,如果你要使用AVPlayer,最好慎重一些
|