AVFoundation是苹果在iOS和OS X系统中用于处理基于时间的媒体数据的Objective-C框架. 供使用者来开发媒体类型的应用程序。git
上图是iOS系统下媒体应用的结构层. AVKit框架用于简化媒体应用的建立过程,若是你只须要看电影,那么使用这个就能够了, UKit能够支持简单的录制功能 . 而更多功能须要低层级框架支持.下面简单介绍下AVFoundation内最主要的支撑框架和其提供的功能。github
CoreAudio : 处理全部音频事件.是由多个框架整合在一块儿的总称,为音频和MIDI内容的录制,播放和处理提供相应接口.设置能够针对音频信号进行彻底控制,并经过Audio Units来构建一些复杂的音频处理.有兴趣的能够单独了解一下这个框架。缓存
CoreMedia: 是AVFoundation所用到低层级媒体管道的一部分.提供音频样本和视频帧处理所需的低层级数据类型和接口。bash
CoreAnimation: 动画相关框架, 封装了支持OpenGL和OpenGL ES功能的ObjC各类类. AVFoundation能够利用CoreAnimation让开发者可以在视频的编辑和播放过程当中添加动画和图片效果。微信
下面我就和你们详细的分享一下,如何使用AVFoundation来实现一个好用的视频播放器。若是好用或者对你有所帮助,不要忘了关注点个赞呦!!!session
视频控制界面实现app
用于视频显示的View建立框架
视频数据下载器FBYVideoDownload建立ide
播放、暂停、横竖屏操做方法实现源码分析
监听播放进度
控制存储缓冲范围
拖动滑块,控制快进快退
定义临时文件路径
定义缓存文件夹路径
发起视频路径网路请求方法
播放结束设置
先后视频播放控制
根据实现思路分析,一步步进行编码实现:
- (FBYVideoPlayerView *)videoPlayControl{
if (!_videoPlayControl) {
_videoPlayControl = [[FBYVideoPlayerView alloc] initWithFrame:self.backgroundView.bounds];
[self.backgroundView addSubview:_videoPlayControl];
}
return _videoPlayControl;
}
复制代码
- (UIView *)videoShowView{
if (!_videoShowView) {
_videoShowView = [[UIView alloc] init];
_videoShowView.layer.masksToBounds = YES;
[self.backgroundView addSubview:_videoShowView];
}
return _videoShowView;
}
复制代码
@property(nonatomic, weak) id <FBYVideoDownloadDelegate> delegate;
//定义初始化方法 传入videoUrl参数(NSString)
- (instancetype)initWithURL:(NSString *)videoUrl withDelegate:(id)delegate;
//开始下载
- (void)start;
//暂停
- (void)suspend;
//关闭
- (void)cancel;
复制代码
//全屏
[_videoPlayControl setFullScreenButtonClick_block:^{
if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(videoPlayerDidFullScreenButtonClick)]) {
[weakSelf.delegate videoPlayerDidFullScreenButtonClick];
}
}];
//播放/暂停
[_videoPlayControl setPlayButtonClick_block:^(BOOL play) {
if (play) {
[weakSelf.player play];
}else{
[weakSelf.player pause];
}
weakSelf.playButtonState = !weakSelf.playButtonState;
}];
复制代码
self.timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
CGFloat current = CMTimeGetSeconds(time);
CGFloat total = CMTimeGetSeconds(weakSelf.currentPlayerItem.duration);
CGFloat progress = current / total;
weakSelf.videoPlayControl.currentTime = current;
weakSelf.videoPlayControl.playValue = progress;
if (weakSelf.isCanToGetLocalTime) {
weakSelf.localTime = [weakSelf getLocalTime];
}
NSInteger timeNow = [weakSelf getLocalTime];
if (timeNow - weakSelf.localTime > 1.5) {
[weakSelf.videoPlayControl videoPlayerDidBeginPlay];
weakSelf.isCanToGetLocalTime = YES;
}
}];
复制代码
[self.currentPlayerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
复制代码
[self.currentPlayerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
复制代码
[self.currentPlayerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
复制代码
- (void)playForActivity{
if (self.playButtonState) {
[self.player play];
}
self.isBufferEmpty = NO;
self.isPlaying = YES;
[self.videoPlayControl videoPlayerDidBeginPlay];
}
复制代码
//拖动滑块
[_videoPlayControl setSliderTouchEnd_block:^(CGFloat time) {
[weakSelf seekToTimePlay:time];
}];
//快进快退
[_videoPlayControl setFastFastForwardAndRewind_block:^(CGFloat time) {
[weakSelf seekToTimePlay:time];
}];
复制代码
self.videoTempPath = [NSString tempFilePathWithFileName:videoName];
复制代码
self.videoCachePath = [NSString cacheFilePathWithName:videoName];
复制代码
- (void)sendHttpRequst
{
[_fileHandle seekToEndOfFile];
NSURL *url = [NSURL URLWithString:_videoUrl];
NSMutableURLRequest *requeset = [NSMutableURLRequest requestWithURL:url];
//指定头信息 当前已下载的进度
[requeset setValue:[NSString stringWithFormat:@"bytes=%ld-", _curruentLength] forHTTPHeaderField:@"Range"];
//建立请求
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:requeset];
self.dataTask = dataTask;
//发起请求
[self.dataTask resume];
}
复制代码
- (void)playerItemDidPlayToEnd:(NSNotification *)notification{
//从新开始播放
__weak typeof(self) weak_self = self;
[self.player seekToTime:CMTimeMake(0, 1) completionHandler:^(BOOL finished) {
__strong typeof(weak_self) strong_self = weak_self;
if (!strong_self) return;
[strong_self.player play];
}];
}
复制代码
//进入后台
- (void)appDidEnterBackground{
if (self.stopWhenAppDidEnterBackground) {
[self pauseVideo];
}
}
//进入前台
- (void)appDidEnterForeground{
[self playVideo];
}
复制代码
下载demo,将demo中FBYVideoData文件夹引入项目中。
#import "FBYVideoPlayer.h"
@interface ViewController ()<FBYVideoPlayerDelegate>
@property (nonatomic ,strong) FBYVideoPlayer *videoPlayer;
@property (nonatomic ,strong) UIView *videoPlayBGView;
@property (nonatomic ,copy) NSString*videoUrl;
@end
复制代码
self.videoPlayBGView = [[UIView alloc] initWithFrame:CGRectMake(0, 90, SCREEN_WIDTH, SCREEN_WIDTH * 0.6)];
self.videoPlayBGView.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.videoPlayBGView];
复制代码
self.videoPlayer = [[FBYVideoPlayer alloc] init];
self.videoPlayer.delegate = self;
[self.videoPlayer playWithUrl:self.videoUrl showView:self.videoPlayBGView];
复制代码
self.videoPlayer = [[FBYVideoPlayer alloc] init];
self.videoPlayer.delegate = self;
[self.videoPlayer playWithUrl:self.videoUrl showView:self.videoPlayBGView];
复制代码
关注 【网罗开发】微信公众号,回复【97】即可领取。 网罗天下方法,方便你我开发,更多iOS技术干货等待领取,全部文档会持续更新,欢迎关注一块儿成长!
但愿能够帮助你们,若有问题可加QQ技术交流群: 668562416 若是哪里有什么不对或者不足的地方,还望读者多多提意见或建议
如需转载请联系我,通过受权方可转载,谢谢
本篇已同步到我的博客:FBY展菲
欢迎关注个人公众号:网罗开发