带你用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 以 ...
随机推荐
- 教你搞懂Jenkins安装部署!
前言:请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i Jenkins介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用 ...
- ms sql 带自增列 带外键约束 数据导入导出
1,生成建表脚本 选中要导的表,点右键-编写表脚本为-create到 ,生成建表脚本 2,建表(在新库),但不建外键关系 不要选中生成外键的那部分代码,只选择建表的代码 3,导数据,用SQL STU ...
- RocketMQ详解(一)原理概览
专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...
- k8s 部署elasticsearch报 max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
1.由于登不上云的节点 不采用修改节点配置的方式 修改部署的stateful 加上 initContainers 它和 containers 同一层级的 initContainers: - name: ...
- mybatis零碎
< < 小于号 > > 大于号 & & 和 ' ' 单 ...
- C# Redis学习系列二:Redis基本设置
上一篇:C# Redis学习系列一:Redis的认识.下载.安装.使用 一.redis 设置密码 使用下载好的 redis-cli.exe 指令: 1.设置密码: config set require ...
- 手机端wap站网页播放腾讯视频代码
<div class="detail-con clear"> <div id="mod_player_wrap" class="mo ...
- EcShop调用显示指定分类下的子分类方法
ECSHOP首页默认的只有全部分类,还有循环大类以及下面小类的代码,貌似没有可以调用显示指定大类下的子分类代码.于是就有这个文章的产生了,下面由夏日博客来总结下网站建设过程中ECSHOP此类问题的网络 ...
- Jmeter扩展组件开发(8) - 函数助手扩展开发demo
前提条件 1.pom文件引用ApacheJMeter_functions包 <dependency> <groupId>org.apache.jmeter</groupI ...
- 多个ssh key 配置多个网址
多个 ssh key 配置多个网站 一.生成ssh key ssh-keygen -t rsa -C "你的邮箱" -f ~/.ssh/id_rsa_one ssh-keygen ...