iOS 视频播放 - AVPlayer
iOS实现视频播放,原生代码播放视频更多的使用AVPlayer和AVPlayerViewController进行播放。
其中,
- AVPlayer不能单独进行播放,仅使用AVPLayer的话,还需要将其添加到AVPlayerLayer上进行播放,不含播放控制控件,需要自定义添加;
- AVPlayerViewController也是在AVPlayer的基础上集成的播放控件。包含完整的播放,暂停,进度拖动等控制控件。
所需库
- 使用AVPlayer和AVPlayerViewController需要添加库文件:AVKit.framework
- 获取时间(CMTimeGetSeconds)等等需要添加库文件:CoreMedia.framework
引用头文件
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
实现播放(代码)
1. AVPlayer
仅使用AVPlayer和AVPlayerLayer创建播放
//生成播放url
本地
NSString* localFilePath=[[NSBundle mainBundle]pathForResource:@"aaa" ofType:@"mp4"];
NSURL *videoUrl = [NSURL fileURLWithPath:localFilePath];
//网络
NSString *webVideoPath = @"http://122.144.137.20:81/2018/12/video/d63797a1912a4f529d8cffab862d8747.mp4";
NSURL *videoUrl = [NSURL URLWithString:webVideoPath];//创建播放单元
AVPlayerItem* item = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:videoUrl]]; //通过url生成
//创建播放器
AVPlayer* player = [AVPlayer playerWithPlayerItem:item]; //使用播放单元生成相应的播放器
或者
AVPlayer* player = [AVPlayer playerWithURL:videoUrl]; //直接使用播放URL生成
//切换播放内容时
[player replaceCurrentItemWithPlayerItem:item];
//创建播放层,将playerLayer添加到view上即可播放
AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
2. AVPlayerViewController
AVPlayerViewController 在生成播放器player的基础上,进行下一步调用:
AVPlayerViewController* playerVC = [[AVPlayerViewController alloc] init];
//设置播放器
playerVC.player = player;
//设置播放范围
playerVC.view.frame = CGRectMake(0, 0, 700, 300);/** 设置所播放视频的适配显示范围 * AVLayerVideoGravityResizeAspectFill : 显示尺寸适配,保证适配内容不变形的情况下铺满显示区域,画面可能会有截断* AVLayerVideoGravityResizeAspect : 保证视频不变形,画面全部显示,可能不能铺满显示区域* AVLayerVideoGravityResize : 保证视频铺满显示区域,画面全部显示,但视频内容可能会有变形*/
playerVC.videoGravity = AVLayerVideoGravityResizeAspectFill;
//显示播放开始,播放进度条等控件
playerVC.showsPlaybackControls = YES;
通过[self presentViewController:playerVC animated:YES completion:nil];进行调用
播放相关监听
- status属性
播放单元playerItem可以通过添加status属性的监听来获取视频加载的状态。
/** 观察status属性, 一共有三种属性* AVPlayerStatusReadyToPlay : 可以播放* AVPlayerItemStatusFailed : 加载失败* AVPlayerItemStatusUnknown : 未知错误*/
[self.playerItem addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionNew) context:nil];
- loadedTimeRanges属性
播放单元playerItem还可以添加loadedTimeRanges属性。
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
以上两种属性均在如下代码中返回监听结果:(这里的代码直接引用了简书作者的代码)
作者:梧雨北辰
链接:https://www.jianshu.com/p/b304694af77a
- (void)observeValueForKeyPath:(NSString *)keyPathofObject:(id)objectchange:(NSDictionary *)changecontext:(void *)context {AVPlayerItem *playerItem = (AVPlayerItem *)object;if ([keyPath isEqualToString:@"status"]) {//获取playerItem的status属性最新的状态AVPlayerStatus status = [[change objectForKey:@"new"] intValue];switch (status) {case AVPlayerStatusReadyToPlay:{//获取视频长度CMTime duration = playerItem.duration; //更新显示:视频总时长(自定义方法显示时间的格式)self.totalNeedPlayTimeLabel.text = [self formatTimeWithTimeInterVal:CMTimeGetSeconds(duration)];//开启滑块的滑动功能self.sliderView.enabled = YES;//关闭加载Loading提示[self showaAtivityInDicatorView:NO];//开始播放视频[self.player play];break;}case AVPlayerStatusFailed:{//视频加载失败,点击重新加载[self showaAtivityInDicatorView:NO];//关闭Loading视图self.playerInfoButton.hidden = NO; //显示错误提示按钮,点击后重新加载视频[self.playerInfoButton setTitle:@"资源加载失败,点击继续尝试加载" forState: UIControlStateNormal];break;}case AVPlayerStatusUnknown:{NSLog(@"加载遇到未知问题:AVPlayerStatusUnknown");break;}default:break;}} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {//获取视频缓冲进度数组,这些缓冲的数组可能不是连续的NSArray *loadedTimeRanges = playerItem.loadedTimeRanges;//获取最新的缓冲区间CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];//缓冲区间的开始的时间NSTimeInterval loadStartSeconds = CMTimeGetSeconds(timeRange.start);//缓冲区间的时长NSTimeInterval loadDurationSeconds = CMTimeGetSeconds(timeRange.duration);//当前视频缓冲时间总长度NSTimeInterval currentLoadTotalTime = loadStartSeconds + loadDurationSeconds;//NSLog(@"开始缓冲:%f,缓冲时长:%f,总时间:%f", loadStartSeconds, loadDurationSeconds, currentLoadTotalTime);//更新显示:当前缓冲总时长_currentLoadTimeLabel.text = [self formatTimeWithTimeInterVal:currentLoadTotalTime];//更新显示:视频的总时长_totalNeedLoadTimeLabel.text = [self formatTimeWithTimeInterVal:CMTimeGetSeconds(self.player.currentItem.duration)];//更新显示:缓冲进度条的值_progressView.progress = currentLoadTotalTime/CMTimeGetSeconds(self.player.currentItem.duration);}
}
- 监听播放进度
播放器player可以添加时间观察来管理播放进度
__weak __typeof(self) weakSelf = self;
[self.playerVC.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {//当前播放的时间NSTimeInterval currentTime = CMTimeGetSeconds(time);//视频的总时间NSTimeInterval totalTime = CMTimeGetSeconds(weakSelf.playerVC.player.currentItem.duration);if (currentTime == totalTime) {//[weakSelf dismissViewControllerAnimated:YES completion:nil]; //播放完成退出播放界面}
}];
以上为目前使用iOS视频播放功能的整理。
iOS 视频播放 - AVPlayer相关推荐
- iOS 视频播放(AVPlayer)
文章目录一.AVPlayer1.简介2.视频播放的解决方案二.AVPlayer中的MVC1.v层 :AVPlayerLayer2.m层 :AVPlayerItem3.c层 :AVPlayer三.实现简 ...
- iOS 视频播放(AVPlayer、MPMoviePlayerController、MPMoviePlayerViewController 区别)
//联系人:石虎 QQ: 1224614774昵称:嗡嘛呢叭咪哄 一.AVPlayer介绍 1.能播放本地.远程的音频.视频文件 2.基于Layer显示,得自己去编写控制面板 3.AVPlayer ...
- iOS 视频播放 AVPlayer 循环播放 闪屏
问题终于解决,选用AVPlayer,重置一下AVPlayerItem就不会出现闪屏现象,注册一个通知同样可以实现循环播放,而且AVPlayer可以自定义播放样式,给了我们更大的发挥空间,完全可以自己D ...
- [绍棠] iOS视频播放AVPlayer的视频内容拉伸设置
使用其中一个叫 videoGravity 的属性,默认设置了AVLayerVideoGravityResize,查看该属性以及相关的其他属性值发现有3种值可以设置, AVLayerVideoGravi ...
- iOS: ios视频播放(MPMediaPlayerController,AVPlayer,AVPlayerViewcontroller、ffmpeg-AVPlayer)...
介绍: 和音频播放一样,ios也提供个很多的API.如mediaPlayer.framework下的MPMediaPlayerController.AVFounditon.framework下的AVP ...
- iOS视频播放的基本方法
本文总结了iOS中最常见的视频播放方法,不同的方法都各具特点,我希望能够总结它们的不同,方便在开发中选择合适的技术方案. Apple为我们提供了多种方法来实现视频播放,包括MPMoviePlayerC ...
- iOS 视频播放器开发
需求设计 做一个小学生教育辅导视频播放器. 参考小猿搜题视频播放器 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L0GsyFSt-1675164972791)(htt ...
- 【iOS】AVPlayer 播放音视频
1.常见的音视频播放器 iOS开发中不可避免地会遇到音视频播放方面的需求. 常用的音频播放器有 AVAudioPlayer.AVPlayer 等.不同的是,AVAudioPlayer 只支持本地音频的 ...
- 视频播放–AVPlayer
视频播放–AVPlayer 能播放本地.远程的音频.视频文件 基于Layer显示,需要自己编写控制面板 #import <AVFoundation/AVFoundation.h>-(AVP ...
最新文章
- 工业界AI项目落地的繁琐过程
- 清空SQL Server数据库日志的SQL语句
- 【Dijkstra】最短路径
- Spring Boot CommandLineRunner和ApplicationRunner
- 统计MySQL中某数据库硬盘占用量大小
- 人工智能技术将重塑银行业
- mac osx vi 设置tab 四个空格
- python装饰器的顺序_python中装饰器的装饰顺序和执行顺序
- Windows XP十五周年:由爱生恨的系统霸主
- 用井字游戏理解 Minimax 算法
- 为什么短除法能求最小公倍数?
- android(微博 微信 qq) 分享和第三分认证登录的封装
- 获取高程数据并生成等高线
- HTS Sinsy音源库训练方法
- 在线教育巨头多邻国Duolingo入华一周年,中国市场马力全开
- 生活网官司难断爱帮网大众点评均称胜诉
- 【ESP32_8266_WiFi (十五)】ESP8266 OTA 操作说明
- 4.EMC整改案案例解析及分析(静电辐射发射)。
- Flutter 获取ios系统默认语言,只能获取到英文
- 博途PLC1200/1500PLC用户自定义数据类型(UDT)
热门文章
- Android源码—为什么onResume方法中不可以获取View宽高
- 压电陶瓷换能器导纳圆图公式推导及匹配
- 中国冲管注射器行业研究与投资预测报告(2022版)
- HDU 1005 — Number Sequence
- Android内存泄漏问题查找方法
- AndroidStudio实时预览listview
- 全国首个以区块链算力为特色的区块链产业园落户成都
- 我的世界手机版javaui材质包_45woool传奇世界网手机版下载-45woool传奇世界手游全部版本合集...
- win11虚拟机VM17.0无法安装win7 vmtools
- 行优先存储和列优先存储