iOS 音视频录制之播放视频,AVPlayer可播放本地视频和在线视频

article/2025/10/2 14:45:02

文章目录


在开发中,单纯使用AVPlayer类是无法显示视频的,要将视频层添加至AVPlayerLayer中,这样才能将视频显示出来,所以先在ViewController的@interface中添加以下属性

@property (nonatomic ,strong) AVPlayer *player;
@property (nonatomic ,strong) AVPlayerItem *playerItem;
@property (nonatomic ,weak) IBOutlet PlayerView *playerView;

其中playerView继承自UIView,不过重写了set和get方法,用于将player添加至playerView的AVPlayerLayer中,这样才能顺利将视频显示出来

在PlayerView.h中声明一个AVPlayer对象,由于默认的layer是CALayer,而AVPlayer只能添加至AVPlayerLayer中,所以我们改变一下layerClass,这样PlayerView的默认layer就变了,之后我们可以把在viewController中初始化的AVPlayer对象赋给AVPlayerLayer的player属性。

PlayerView.h @property (nonatomic ,strong) AVPlayer *player;PlayerView.m
+ (Class)layerClass {return [AVPlayerLayer class];
}- (AVPlayer *)player {return [(AVPlayerLayer *)[self layer] player];
}- (void)setPlayer:(AVPlayer *)player {[(AVPlayerLayer *)[self layer] setPlayer:player];
}

然后在viewDidLoad中执行初始化:

NSURL *videoUrl = [NSURL URLWithString:@"http://flv.bn.netease.com/videolib3/1707/03/bGYNX4211/SD/movie_index.m3u8"];
self.playerItem = [AVPlayerItem playerItemWithURL:videoUrl];
[self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];// 监听status属性
[self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];// 监听loadedTimeRanges属性
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotificationobject:self.playerItem];

先将在线视频链接存放在videoUrl中,然后初始化playerItem,playerItem是管理资源的对象(A player item manages the presentation state of an asset with which it is associated. A player item contains player item tracks—instances of AVPlayerItemTrack—that correspond to the tracks in the asset.)
在这里插入图片描述
然后监听playerItem的status和loadedTimeRange属性,status有三种状态:

AVPlayerStatusUnknown,

AVPlayerStatusReadyToPlay,

AVPlayerStatusFailed

当status等于AVPlayerStatusReadyToPlay时代表视频已经可以播放了,我们就可以调用play方法播放了。

loadedTimeRange属性代表已经缓冲的进度,监听此属性可以在UI中更新缓冲进度,也是很有用的一个属性。

最后添加一个通知,用于监听视频是否已经播放完毕,然后实现KVO的方法:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {AVPlayerItem *playerItem = (AVPlayerItem *)object;if ([keyPath isEqualToString:@"status"]) {if ([playerItem status] == AVPlayerStatusReadyToPlay) {NSLog(@"AVPlayerStatusReadyToPlay");self.stateButton.enabled = YES;CMTime duration = self.playerItem.duration;// 获取视频总长度CGFloat totalSecond = playerItem.duration.value / playerItem.duration.timescale;// 转换成秒_totalTime = [self convertTime:totalSecond];// 转换成播放时间[self customVideoSlider:duration];// 自定义UISlider外观NSLog(@"movie total duration:%f",CMTimeGetSeconds(duration));[self monitoringPlayback:self.playerItem];// 监听播放状态} else if ([playerItem status] == AVPlayerStatusFailed) {NSLog(@"AVPlayerStatusFailed");}} else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {NSTimeInterval timeInterval = [self availableDuration];// 计算缓冲进度NSLog(@"Time Interval:%f",timeInterval);CMTime duration = self.playerItem.duration;CGFloat totalDuration = CMTimeGetSeconds(duration);[self.videoProgress setProgress:timeInterval / totalDuration animated:YES];}
}- (NSTimeInterval)availableDuration {NSArray *loadedTimeRanges = [[self.playerView.player currentItem] loadedTimeRanges];CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域float startSeconds = CMTimeGetSeconds(timeRange.start);float durationSeconds = CMTimeGetSeconds(timeRange.duration);NSTimeInterval result = startSeconds + durationSeconds;// 计算缓冲总进度return result;
}- (NSString *)convertTime:(CGFloat)second{NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];NSDateFormatter *formatter = [[NSDateFormatter alloc] init];if (second/3600 >= 1) {[formatter setDateFormat:@"HH:mm:ss"];} else {[formatter setDateFormat:@"mm:ss"];}NSString *showtimeNew = [formatter stringFromDate:d];return showtimeNew;
}

此方法主要对status和loadedTimeRanges属性做出响应,status状态变为AVPlayerStatusReadyToPlay时,说明视频已经可以播放了,这时我们可以获取一些视频的信息,包含视频长度等,把播放按钮设备enabled,点击就可以调用play方法播放视频了。在AVPlayerStatusReadyToPlay的底部还有个monitoringPlayback方法

- (void)monitoringPlayback:(AVPlayerItem *)playerItem {self.playbackTimeObserver = [self.playerView.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {CGFloat currentSecond = playerItem.currentTime.value/playerItem.currentTime.timescale;// 计算当前在第几秒[self updateVideoSlider:currentSecond];NSString *timeString = [self convertTime:currentSecond];self.timeLabel.text = [NSString stringWithFormat:@"%@/%@",timeString,_totalTime];}];
}

monitoringPlayback用于监听每秒的状态,- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;此方法就是关键,interval参数为响应的间隔时间,这里设为每秒都响应,queue是队列,传NULL代表在主线程执行。可以更新一个UI,比如进度条的当前时间等。

作为播放器,除了播放,暂停等功能外。还有一个必不可少的功能,那就是显示当前播放进度,还有缓冲的区域,我的思路是这样,用UIProgressView显示缓冲的可播放区域,用UISlider显示当前正在播放的进度,当然这里要对UISlider做一些自定义,代码如下:

- (void)customVideoSlider:(CMTime)duration {self.videoSlider.maximumValue = CMTimeGetSeconds(duration);UIGraphicsBeginImageContextWithOptions((CGSize){ 1, 1 }, NO, 0.0f);UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();UIGraphicsEndImageContext();[self.videoSlider setMinimumTrackImage:transparentImage forState:UIControlStateNormal];[self.videoSlider setMaximumTrackImage:transparentImage forState:UIControlStateNormal];
}

在这里插入图片描述
把UISlider添加至UIProgressView上面,运行起来的效果就变成了这样:
在这里插入图片描述
在这里插入图片描述
参考:https://www.cnblogs.com/mzds/p/3711867.html
Demo


http://chatgpt.dhexx.cn/article/YVaL6Y88.shtml

相关文章

【iOS】视频播放之AVPlayer

【iOS】视频播放之AVPlayer iOS平台使用播放视频,可用的选项一般有这四个,他们各自的作用和功能如下: 使用环境优点缺点AVPlayerViewControllerAVKit简单易用不可定制MPMoviePlayerControllerMediaPlayer简单易用不可定制IJKPlayerIJKMedi…

【iOS】AVPlayer 播放音视频

1、常见的音视频播放器 iOS开发中不可避免地会遇到音视频播放方面的需求。 常用的音频播放器有 AVAudioPlayer、AVPlayer 等。不同的是,AVAudioPlayer 只支持本地音频的播放,而 AVPlayer 既支持本地音频播放,也支持网络音频播放。 常用的视…

【iOS】AVPlayer 视频播放

视频播放器的类别 iOS开发中不可避免地会遇到音视频播放方面的需求。 常用的音频播放器有 AVAudioPlayer、AVPlayer 等。不同的是,AVAudioPlayer 只支持本地音频的播放,而 AVPlayer 既支持本地音频播放,也支持网络音频播放。 常用的视频播放…

iOS音视频播放-AVPlayer简单使用

按公司需求需要对音频文件进行后台播放,借此机会对音频播放做了个总结.主要针对 AVPlayer 进行详细说明. iOS 各播放器比较 名称使用环境优点确点System Sound ServicesAVFoundationC语言的底层写法,节省内存支持的格式有限,音量无法通过音量键控制&…

iOS音视频播放指南(二)

1. 让你的App支持画中画 画中画指可以让视频在小窗中播放,可以一边看视频一边刷知乎 你可以使用AVPlayerViewController或者AVPictureInPictureController来实现画中画播放。 其中AVPictureInPictureController支持你自定义一些播放控件 在支持画中画播放之前,确保你按照iOS音视…

iOS音视频播放指南(一)

1. 简介 苹果目前提供两个框架用来处理音视频播放 1.AVFoundation AVFoundation用于播放、处理音视频。可以通过结构图看到AVFoundation位于UIKit之下,很好理解AVFoundation并不提供用户界面,你可以自己自己构建用户界面来控制媒体的播放处理等功能。 但是苹果更推荐使用AVKit来…

iOS视频播放的基本方法

本文总结了iOS中最常见的视频播放方法,不同的方法都各具特点,我希望能够总结它们的不同,方便在开发中选择合适的技术方案。 Apple为我们提供了多种方法来实现视频播放,包括MPMoviePlayerController,MPMoviePlayerView…

【计算机系统1】4 Nim游戏

目录 目的与要求 内容与方法 步骤与过程 程序总体设计 核心数据结构及算法流程 核心代码 调试过程 界面展示子程序DISPLAY(嵌套:球数展示子程序PUTBALL) 游戏子程序GAME(嵌套:单人每轮子程序PLAY) 结论或体…

java nim游戏_LeetCode 292. Nim游戏

题目描述: 你和你的朋友,两个人一起玩 Nim游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。 你们是聪明人,每一步都是最优解。 编写一个函数,来判断你…

Nim游戏、3的幂、4的幂

🍅 Java学习路线:Java学习路线 🍅 简介:Java领域优质创作者🏆、CSDN哪吒公众号作者✌ 、Java架构师奋斗者💪 🍅 百日刷题计划:第 12 / 100 天。 🍅 扫描主页左侧二维码&a…

【数论】博弈论 —— nim游戏

知识点 一 . nim游戏的数学定义 Nim游戏是博弈论中最经典的模型,它又有着十分简单的规则和无比优美的结论 。 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于“Impartial Combinatorial Games”(以下简称ICG&#…

【模板题】几种常见的Nim游戏(博弈论)

一、AcWing 891. Nim游戏 【题目描述】 给定 n n n堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。 问如果两人都采用最优…

Kafka 为什么能那么快 | Kafka高效读写数据的原因

点击上方“服务端思维”,选择“设为星标” 回复”669“获取独家整理的精选资料集 回复”加群“加入全国服务端高端社群「后端圈」 无论 kafka 作为 MQ 也好,作为存储层也罢,无非就是两个功能(好简单的样子)&#xff0c…

【人人都懂密码学】一篇最易懂的Java密码学入门教程

密码与我们的生活息息相关,远到国家机密,近到个人账户,我们每天都在跟密码打交道: 那么,密码从何而来?生活中常见的加密是怎么实现的?怎么保证个人信息安全?本文将从这几方面进行浅谈…

Kafka必须掌握的核心技术--为什么吞吐量大、速度快?

点击上方“服务端思维”,选择“设为星标” 回复”669“获取独家整理的精选资料集 回复”加群“加入全国服务端高端社群「后端圈」 Kafka是大数据领域无处不在的消息中间件,目前广泛使用在企业内部的实时数据管道,并帮助企业构建自己的流计算应…

哪些软件问题也可导致硬盘录像机死机

硬盘录像机死机除了一些硬件上的问题之外,也有不少是由软件引起的。如: 1、病毒感染 病毒是计算机操作的大患,几乎人人恶之。病毒可以使计算机工作效率急剧下降,造成频繁死机、数据丢失、系统崩溃,甚至损坏主板、硬盘、…

导致硬盘录像机卡死的十大原因分析

硬盘录像机卡死除了一些技术上的问题之外,也有不少是由软件引起的。如: 1、病毒感染 病毒是硬盘录像机操作的大患,几乎人人恶之。病毒可以使硬盘录像机工作效率急剧下降,造成频繁死机、数据丢失、系统崩溃,甚至损坏主板…

谈项目管理和软件测试过程

谈项目管理和软件测试过程(一) 1. 软件测试在公司的组织保障是基础 1.1 研发部组织结构介绍 以华友公司研发部的组织结构为例,测试部门属于研发部副总裁直接管理,见如下结构图 公司研发部的组织结构图 …

NoSQL初探之人人都爱Redis:(1)Redis简介与简单安装

一、NoSQL的风生水起 1.1 后Web2.0时代的发展要求 随着互联网Web2.0网站的兴起,传统的关系数据库在应付Web2.0网站,特别是超大规模和高并发的SNS类型的Web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题: (1…

软件公司面试总结

文章目录 面试1面试2面试3面试4面试5面试6 面试1 1、你先做个简单的自我介绍吧 我叫张三,2015年在重庆邮电大学毕业。我读的专业是电子信息。工作已经快5年了。 我上家公司的主营业务是在柬埔寨做移动支付钱包。 最近做的一个项目是聚合支付的项目,主要…