带你用AVPlayer实现音频和视频播放
项目概述
- 以下项目是基于AVPlayer的实际运用,实现音频播放、横竖屏视频切换播放、类似抖音的竖屏全屏播放效果。
项目地址:AVPlayerAudioVideo
如果文章和项目对你有帮助,还请给个Star️,你的Star️是我持续输出的动力,谢谢啦
1.音频播放器效果:
2.竖屏和横屏的切换效果:
3.类似抖音竖屏全屏的效果:
竖屏全屏用UICollectionView实现,只创建了三个UICollectionViewCell视图实例。无论有多少视频需要播放,都是复用这三个UICollectionViewCell视图实例,有效控制内存大小,避免内存加载过大、内存爆满的情况。
UICollectionViewCell复用时有一个难点,就是记录视频当前已播放的位置,一开始用CMTime来保存发现不行,然后用CMTimeValue和CMTimeScale分别记录也是存在各种问题,后来使用AVPlayerItem来保存已播放位置才彻底解决。
遇到的问题
- 播放时,扬声器没有声音,插上耳机才有声音。
原因是app扬声器默认跟随系统声音模式,而手机调了静音模式,因此扬声器跟随静音模式,没有声音。
解决方式:设置Category,让扬声器不跟随系统声音模式。
//必须设置,否则扬声器默认跟随系统声音模式
//AVAudioSessionCategoryPlayAndRecord模式能播放能录音,该模式下声音默认出口是听筒(戴耳机才有声音),切换到扬声器通过以下方式
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
- 当反复快速移动滑块时,滑块会出现跳跃的现象。
这是由于移动滑块时,会调用seekToTime:
,该方法用于搜索并播放指定视频帧,执行时需要一点时间,不会立马搜索并播放到指定视频帧,此时addPeriodicTimeObserverForInterval:queue:usingBlock:
回调会设置滑块的位置,出现手指已让滑块移动到某一位置,突然有一瞬间滑块回到之前的位置,然后立马又回到手指停留的位置。
解决方式:用seekToTime:toleranceBefore:toleranceAfter:completionHandler:
代替seekToTime:
,搜索并播放到指定视频帧会有completionHandler的回调,获得该回调后再设置滑块的位置。具体处理细节详见项目。
什么是AVPlayer
- AVPlayer存在于AVFoundation框架中,它是一个视频播放器,用来播放视频,但也可以用来播放音乐,播放音乐时不需要实现界面。换句话说,只要掌握了视频播放,音频播放自然就掌握了。
- AVPlayerItem:和媒体资源存在对应关系,管理媒体资源的信息和状态。它的初始化需要URL或AVAsset。
- AVPlayer:播放器,控制资源的播放和暂停,AVPlayerItem是它的属性,它的初始化需要URL或AVPlayerItem。
+ (instancetype)playerWithURL:(NSURL *)URL;
+ (instancetype)playerWithPlayerItem:(nullable AVPlayerItem *)item;
- AVPlayerLayer:播放器图层,用于展示视频内容,AVPlayer是它的属性,它的初始化需要AVPlayer。如果是播放音频,则不需要创建AVPlayerLayer。
+ (AVPlayerLayer *)playerLayerWithPlayer:(nullable AVPlayer *)player
- AVPlayerItem、AVPlayer、AVPlayerLayer三者关系,做个类比:
AVPlayerItem是光盘,AVPlayer是dvd影碟机,AVPlayerLayer是电视机屏幕。
视频播放功能实现
1.通过网络链接播放视频资源
//url有中文时需要URL编码
NSURL *url = [NSURL URLWithString:[self.str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = CGRectMake(0, 50, self.view.frame.size.width, 200);
[self.view.layer addSublayer:playerLayer];
2.常用操作
- 播放和暂停
[player play];
[player pause];
- 替换播放资源
[player replaceCurrentItemWithPlayerItem:videoItem];
3.监听播放进度
- 使用
addPeriodicTimeObserverForInterval:queue:usingBlock:
监听播放器的进度,常用于指示播放进度,获取播放时长等信息。
1)Interval参数表示回调的间隔时间,block是每到一个间隔时间执行一次。
例如Interval传CMTimeMake(1,10),1表示当前有1帧,10表示每秒10帧,1/10=0.1,即player在播放中时每0.1秒执行一次block,包括开始播放、暂停播放也会回调。
2)方法返回一个观察者对象,当不再播放时,要移除该观察者。
添加观察者
self.timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 10) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
float current = CMTimeGetSeconds(time);
float total = CMTimeGetSeconds(weakSelf.player.currentItem.duration);
weakSelf.playTime = [NSString stringWithFormat:@"%.f",current];
weakSelf.playDuration = [NSString stringWithFormat:@"%.2f",total];
if (weakSelf.slider.isTracking == NO) {
weakSelf.slider.value = current / total;
}
}];
移除观察者
if (self.timeObserve) {
[self.player removeTimeObserver:self.timeObserve];
}
4.移动滑块播放指定时刻的视频帧
- 使用
seekToTime:
或seekToTime:completionHandler:
或seekToTime:toleranceBefore:toleranceAfter:completionHandler:
播放指定时刻的视频内容。
精确搜索某一时刻的视频帧可能会导致额外的解码延迟,seekToTime:
默认不是精确搜索,而是有一个小范围的误差。
seekToTime:toleranceBefore:toleranceAfter:completionHandler:
的搜索的范围是[time-toleranceBefore, time+toleranceAfter],当toleranceBefore和toleranceAfter设置为kCMTimePositiveInfinity时,执行效果等同于seekToTime:completionHandler:
[self.player seekToTime:goalTime toleranceBefore:kCMTimePositiveInfinity toleranceAfter:kCMTimePositiveInfinity completionHandler:^(BOOL finished) {
}];
带你用AVPlayer实现音频和视频播放的更多相关文章
- iOS开发——高级篇——远程音频、视频播放
一.远程音频播放(<AVFoundation/AVFoundation.h>) #import <AVFoundation/AVFoundation.h> /** 播放器 */ ...
- iOS AvPlayer AvAudioPlayer音频的后台播放问题
iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,Av ...
- 那些H5用到的技术(2)——音频和视频播放
前言audio标签Web Audio API自动播放的问题背景音乐的实现立即播放的问题SoundJSvideo标签播放样式的问题格式的问题总结 前言 正常情况,除了非常简陋的小功能H5,音乐播放是必不 ...
- 一种高灵敏度自带DSP降噪算法的音频采集解决方案
背景调研 随着AI渗透到各行各业,人们对语音的需求也越来越大,最近一两年,各种AI音频设备如雨后春笋般冒出.各种智能AI设备的推出,意味者市场对低成本的音频采集设备越来越多.针对这种情况,我们开发 ...
- HTML5音频,视频播放
1.此方法可支持多种浏览器 <audio controls="controls"> <source src="1.mp3" ></ ...
- HTML5音频视频-视频播放
- iOS: ios视频播放(MPMediaPlayerController,AVPlayer,AVPlayerViewcontroller、ffmpeg-AVPlayer)
介绍: 和音频播放一样,ios也提供个很多的API.如mediaPlayer.framework下的MPMediaPlayerController.AVFounditon.framework下的AVP ...
- C# Winform 中如何实现音乐播放和视频播放
C# Winform 中如何实现音乐播放和视频播放 namespace WindowsFormsApplication1 { public partial class Form2 : Form { ...
- 音频 API 一览
iOS 和 OS X 平台都有一系列操作音频的 API,其中涵盖了从低到高的全部层级.随着时间的推移.平台的增长以及改变,不同 API 的数量可以说有着非常巨大的变化.本文对当前可以使用的 API 以 ...
随机推荐
- Abp Vnext3 vue-admin-template(二用户退出)
先修改用户退出,中午有点困先改简单的 退出代码在src\layout\components\Navbar.vue代码如下,讲流程这里不需要修改 methods: { toggleSideBar() { ...
- Nginx:无处不在的Nginx的八个应用场景与配置
--- 阅读时间约 15 分钟 --- Nginx概述 众所周知,互联网已经离不开 WEB服务器 ,技术领域中 WEB服务器 不止 Nginx 一个,其他还有很多如 Apache . ...
- MySQL日志管理、备份、恢复
目录: 一.MySQL 日志管理 二.数据库备份的重要性与分类 三.常见的备份方法 四.MySQL完全备份 五.数据库完全备份分类 六.MySQL增量备份 七.MySQL数据库增量恢复 八.MySQL ...
- linux中花括弧大括号用法
{1,3,5} == 1 3 5 {1..5} == 1 2 3 4 5 {a..e} == a b c d e {A..z} {1..50..2} {1..50..3} {1 ...
- Prometheus 2.21.0 新特性
Prometheus 2.21.0 现在(2020.09.11)已经发布,在上个月的 2.20.0 之后又进行了很多的修复和改进. 这个版本使用了 Go 1.15 进行编译,不赞成在TLS证书验证中使 ...
- 【noip1998】题解:2的幂次方
思路:设递归函数dfs(x)用于输出x的幂次方 最容易的思路:0不输出,1输出为2(0),2输出2,剩下的递归执行. 每一次递归:例如7,拆分为4+3,先拆出最大的是2的次方的数出来,输出4,再把3分 ...
- 支付宝openssl_sign(): supplied key param cannot be coerced into a private key in
先说一下,生成rsa 私钥 公钥的方法,以ubuntu 为例sudo apt-get install openssl # 先装上这个库genrsa -out rsa_private_key.pem 1 ...
- Java面向对象系列(2)- 回顾方法的定义
方法的定义 修饰符 返回类型 break:跳出switch,结束循环和return的区别 方法名:注意规范,见名知意 参数列表:(参数类型,参数名) 异常抛出 package oop.demo01; ...
- P2150-[NOI2015]寿司晚宴【dp】
正题 题目链接:https://www.luogu.com.cn/problem/P2150 题目大意 将\(2\sim n\)选出一些分成两个集合,要求这两个集合中没有一对数不是互质的.求方案数对\ ...
- Unity——可复用背包工具
Unity可复用背包工具 Demo展示 设计思路 游戏中有非常多的背包样式,比如玩家道具背包,商城,装备栏,技能栏等:每个形式的背包都单独写一份逻辑会非常繁琐,所以需要有一套好用的背包工具: 这些背包 ...