Swift 使用AVPlayer 和 AVPlayerItem 做语音播放

前言:

最近工作内容用到了语音播放,从 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,最好慎重一些

猜你喜欢

转载自blog.csdn.net/u014651417/article/details/124293427
今日推荐