iOS - AVPlayer 音视频播放
前言
NS_CLASS_AVAILABLE(10_7, 4_0) @interface AVPlayer : NSObject
@available(iOS 4.0, *) public class AVPlayer : NSObject
NS_CLASS_AVAILABLE_IOS(8_0) @interface AVPlayerViewController : UIViewController
@available(iOS 8.0, *) public class AVPlayerViewController : UIViewController
AVPlayer 既可以播放音乐又可以播放视频;使用 AVPlayer 不能直接显示视频,必须要加入 AVPlayerLayer 中,并添加到其他能显示的 layer 中,AVPlayer 播放界面中不带播放控件。
- MediaPlayer 的影片是放在 UIView 里面,而 AVPlayer 是放在 AVPlayerLayer 里面,AVPlayerLayer 是 CALayer 的子类別。
- 使用 MediaPlayer 前,要记得加入 MediaPlayer.framework 及 #import <MediaPlayer/MediaPlayer.h>
- 使用 AVPlayer 前,要记得加入 AVFoundation.framework 及 #import <AVFoundation/AVFoundation.h>
MeidaPlayer 框架中的 MPMoviePlayerController 类和 MPMoviePlayerViewController 类是 iOS 中视频播放的开发相关类和方法。在 iOS8 中,iOS 开发框架中引入了一个新的视频框架 AVKit,其中提供了视频开发类 AVPlayerViewController 用于在应用中嵌入播放视频的控件。AVPlayerViewcontroller 继承自 UIViewController,一般适用于点击一个视频缩略图,modal 出一个新的界面来进行播 放的情况,AVPlayerViewcontroller 既可以播放音乐又可以播放视频,播放界面中自带播放控件。在 iOS8 中,这两个框架中的视频播放功能并无太大差异,基本都可以满足开发者的需求。iOS9 系统后,iPad Air 正式开始支持多任务与画中画的分屏功能,所谓画中画,即是用户可以将当前播放的视频缩小放在屏幕上同时进行其他应用程序的使用。这个革命性的功能将极大的方便用户的使用。于此同时,在 iOS9 中,MPMoviePlayerController 与 MPMoviePlayerViewController 类也被完全弃用,开发者使用 AVPlayerViewController 可以十分方便的实现视频播放的功能并在一些型号的 iPad 上集成画中画的功能。
实现画中画要实现以下三步:
1、确保当前调试版本在 9.0 以上。
2、在项目 TARGETS 中的 Capabilities -> Gapabilities -> Background Mode(选项开关打开)-> 勾选 Audio, AirPlay and Picture in Picture
3、设置 AVAudioSession,这两行必须设置,不然画中画不能用,如果不写模拟器中可以画中画,但是在 iPad 设备中不能。
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
播放设置:
使用 AVPlayer 播放:
添加库文件:AVFoundation.framework
包含头文件:#import <AVFoundation/AVFoundation.h>
使用 AVPlayerViewController 播放:
添加库文件:AVKit.framework
AVFoundation.framework 包含头文件:#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
1、本地/网络音视频播放
1.1 使用 AVPlayer 播放
Objective-C
添加库文件:AVFoundation.framework
包含头文件:#import <AVFoundation/AVFoundation.h>
直接由 URL 创建
// 加载本地音乐
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"蓝莲花" ofType:@"mp3"]]; // 加载本地视频
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"步步高手机" ofType:@"mp4"]]; // 加载网络视频
NSURL *movieUrl = [NSURL URLWithString:@"http://w2.dwstatic.com/1/5/1525/127352-100-1434554639.mp4"]; // 创建 AVPlayer 播放器
AVPlayer *player = [AVPlayer playerWithURL:movieUrl]; // 将 AVPlayer 添加到 AVPlayerLayer 上
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; // 设置播放页面大小
playerLayer.frame = CGRectMake(10, 30, self.view.bounds.size.width - 20, 200); // 设置画面缩放模式
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; // 在视图上添加播放器
[self.view.layer addSublayer:playerLayer]; // 开始播放
[player play];
由 AVPlayerItem 创建
// 加载本地音乐
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"蓝莲花" ofType:@"mp3"]]; // 加载本地视频
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"步步高手机" ofType:@"mp4"]]; // 加载网络视频
NSURL *movieUrl = [NSURL URLWithString:@"http://w2.dwstatic.com/1/5/1525/127352-100-1434554639.mp4"]; AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:movieUrl]; // 创建 AVPlayer 播放器
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem]; // 将 AVPlayer 添加到 AVPlayerLayer 上
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; // 设置播放页面大小
playerLayer.frame = CGRectMake(10, 30, self.view.bounds.size.width - 20, 200); // 设置画面缩放模式
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; // 在视图上添加播放器
[self.view.layer addSublayer:playerLayer]; // 开始播放
[player play];
Swift
添加库文件:AVFoundation.framework
包含头文件:import AVFoundation
直接由 URL 创建
// 加载本地音乐
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("蓝莲花", ofType: "mp3")!) // 加载本地视频
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("步步高手机", ofType: "mp4")!) // 加载网络视频
let movieUrl:NSURL = NSURL(string: "http://w2.dwstatic.com/1/5/1525/127352-100-1434554639.mp4")! // 创建 AVPlayer 播放器
let player:AVPlayer = AVPlayer(URL: movieUrl) // 将 AVPlayer 添加到 AVPlayerLayer 上
let playerLayer:AVPlayerLayer = AVPlayerLayer(player: player) // 设置播放页面大小
playerLayer.frame = CGRectMake(10, 30, self.view.bounds.size.width - 20, 200) // 设置画面缩放模式
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect // 在视图上添加播放器
self.view.layer.addSublayer(playerLayer) // 开始播放
player.play()
由 AVPlayerItem 创建
// 加载本地音乐
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("蓝莲花", ofType: "mp3")!) // 加载本地视频
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("步步高手机", ofType: "mp4")!) // 加载网络视频
let movieUrl:NSURL = NSURL(string: "http://w2.dwstatic.com/1/5/1525/127352-100-1434554639.mp4")! let playerItem:AVPlayerItem = AVPlayerItem(URL: movieUrl) // 创建 AVPlayer 播放器
let player:AVPlayer = AVPlayer(playerItem: playerItem) // 将 AVPlayer 添加到 AVPlayerLayer 上
let playerLayer:AVPlayerLayer = AVPlayerLayer(player: player) // 设置播放页面大小
playerLayer.frame = CGRectMake(10, 30, self.view.bounds.size.width - 20, 200) // 设置画面缩放模式
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect // 在视图上添加播放器
self.view.layer.addSublayer(playerLayer) // 开始播放
player.play()
1.2 使用 AVPlayerViewController 播放
Objective-C
添加库文件:AVKit.framework
AVFoundation.framework 包含头文件:#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
弹出显示页面直接开始播放
// 加载本地音乐
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"蓝莲花" ofType:@"mp3"]]; // 加载本地视频
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"步步高手机" ofType:@"mp4"]]; // 加载网络视频
NSURL *movieUrl = [NSURL URLWithString:@"http://w2.dwstatic.com/1/5/1525/127352-100-1434554639.mp4"]; // 创建播放控制器
AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init]; playerViewController.player = [AVPlayer playerWithURL:movieUrl]; // 弹出播放页面
[self presentViewController:playerViewController animated:YES completion:^{ // 开始播放
[playerViewController.player play];
}];
手动播放
// 加载本地视频
NSURL *movieUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"步步高手机" ofType:@"mp4"]]; // 创建播放控制器
AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
playerViewController.player = [AVPlayer playerWithURL:movieUrl]; // 弹出播放页面,需要点击播放按钮开始播放
[self presentViewController:playerViewController animated:YES completion:nil];
Swift
添加库文件:AVKit.framework
import AVFoundation 包含头文件:import AVKit
AVFoundation.framework
弹出显示页面直接开始播放
// 加载本地音乐
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("蓝莲花", ofType: "mp3")!) // 加载本地视频
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("步步高手机", ofType: "mp4")!) // 加载网络视频
let movieUrl:NSURL = NSURL(string: "http://w2.dwstatic.com/1/5/1525/127352-100-1434554639.mp4")! // 创建播放控制器
let playerViewController:AVPlayerViewController = AVPlayerViewController() playerViewController.player = AVPlayer(URL: movieUrl) // 弹出播放页面
self.presentViewController(playerViewController, animated: true) { // 开始播放
playerViewController.player?.play()
}
手动播放
// 加载本地视频
let movieUrl:NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("步步高手机", ofType: "mp4")!) // 创建播放控制器
let playerViewController:AVPlayerViewController = AVPlayerViewController() playerViewController.player = AVPlayer(URL: movieUrl) // 弹出播放页面,需要点击播放按钮开始播放
self.presentViewController(playerViewController, animated: true, completion:nil)
2、本地/网络音视频播放设置
2.1 使用 AVPlayer 播放
Objective-C
// 在视图上添加播放器
/*
必须添加到 layer 上
*/
avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
[self.view.layer addSublayer:avPlayerLayer]; // 设置播放页面大小
avPlayerLayer.frame = CGRectMake(10, 30, self.view.bounds.size.width - 20, 200); // 设置画面缩放模式
/*
AVLayerVideoGravityResizeAspect 适应屏幕大小,保持宽高比,默认
AVLayerVideoGravityResizeAspectFill 充满屏幕,保持宽高比
AVLayerVideoGravityResize 充满屏幕,不保持宽高比
*/
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; // 获取显示在接收视图范围内的视频图像的位置和大小
CGRect videoRect = avPlayerLayer.videoRect; // 判断是否准备好显示
BOOL readyForDisplay = avPlayerLayer.isReadyForDisplay; // 获取视频准备播放状态
/*
AVPlayerItemStatusUnknown, 状态未知
AVPlayerItemStatusReadyToPlay, 准备好播放
AVPlayerItemStatusFailed 准备失败
*/
AVPlayerItemStatus status = avPlayerItem.status; // 监听准备播放状态属性
[avPlayerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil]; // 系统自带监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context { if ([keyPath isEqualToString:@"status"]) { }
} // 获取视频缓冲进度
NSArray<NSValue *> *loadedTimeRanges = avPlayerItem.loadedTimeRanges; CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue]; // 获取缓冲区域
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration); float loadedSecond = startSeconds + durationSeconds; // 计算缓冲总进度 // 监听缓冲进度属性
[avPlayerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; // 系统自带监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context { if ([keyPath isEqualToString:@"loadedTimeRanges"]) { }
} // 获取当前播放进度
/*
或用 avPlayerItem.currentTime.value/avPlayerItem.currentTime.timescale;
*/
CMTime currentTime = avPlayerItem.currentTime;
float currentSecond = CMTimeGetSeconds(currentTime); // 监听播放进度
/*
NULL 在主线程中执行,每个一秒执行一次该 Block
*/
[avPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) { }]; // 添加播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playDidEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:avPlayerItem]; // 获取视频总长度
/*
转换成秒,或用 duration.value / duration.timescale; 计算
*/
CMTime duration = avPlayerItem.duration;
float totalSecond = CMTimeGetSeconds(duration); // 跳转到指定位置
/*
10 / 1 = 10,跳转到第 10 秒的位置处
*/
[avPlayerItem seekToTime:CMTimeMake(10, 1)]; // 设置播放速率
/*
默认为 1.0 (normal speed),设为 0.0 时暂停播放。设置后立即开始播放,可放在开始播放后设置
*/
avPlayer.rate = 1.0; // 获取当前播放速率
float rate = avPlayer.rate; // 开始播放
[avPlayer play]; // 暂停播放
[avPlayer pause]; // 设置音量
/*
范围 0 - 1,默认为 1
*/
avPlayer.volume = 0;
Swift
// 在视图上添加播放器
/*
必须添加到 layer 上
*/
avPlayerLayer = AVPlayerLayer(player: avPlayer)
self.view.layer.addSublayer(avPlayerLayer) // 设置播放页面大小
avPlayerLayer.frame = CGRectMake(10, 30, self.view.bounds.size.width - 20, 200) // 设置画面缩放模式
/*
AVLayerVideoGravityResizeAspect 适应屏幕大小,保持宽高比,默认
AVLayerVideoGravityResizeAspectFill 充满屏幕,保持宽高比
AVLayerVideoGravityResize 充满屏幕,不保持宽高比
*/
avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill // 获取显示在接收视图范围内的视频图像的位置和大小
let videoRect:CGRect = avPlayerLayer.videoRect // 判断是否准备好显示
let readyForDisplay:Bool = avPlayerLayer.readyForDisplay // 获取视频准备播放状态
/*
case Unknown 状态未知
case ReadyToPlay 准备好播放
case Failed 准备失败
*/
let status:AVPlayerItemStatus = avPlayerItem.status // 监听准备播放状态属性
avPlayerItem.addObserver(self, forKeyPath: "status", options: .New, context: nil) // 系统自带监听方法
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?,
change: [String : AnyObject]?,
context: UnsafeMutablePointer<Void>) { if keyPath == "status" { }
} // 获取视频缓冲进度
let loadedTimeRanges:[NSValue] = avPlayerItem.loadedTimeRanges let timeRange:CMTimeRange = loadedTimeRanges.first!.CMTimeRangeValue // 获取缓冲区域
let startSeconds = CMTimeGetSeconds(timeRange.start)
let durationSeconds = CMTimeGetSeconds(timeRange.duration) let loadedSecond:Double = startSeconds + durationSeconds // 计算缓冲总进度 // 监听缓冲进度属性
avPlayerItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .New, context: nil) // 系统自带监听方法
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?,
change: [String : AnyObject]?,
context: UnsafeMutablePointer<Void>) { if keyPath == "loadedTimeRanges" { }
} // 获取当前播放进度
/*
或用 avPlayerItem.currentTime.value/avPlayerItem.currentTime.timescale;
*/
let currentTime:CMTime = self.avPlayerItem.currentTime()
let currentSecond = CMTimeGetSeconds(currentTime) // 监听播放进度
/*
nil 在主线程中执行,每个一秒执行一次该 Block
*/
avPlayer.addPeriodicTimeObserverForInterval(CMTimeMake(1, 1), queue: nil) { (time:CMTime) in } // 添加播放完成通知
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(AvPlayer.playDidEnd(_:)),
name: AVPlayerItemDidPlayToEndTimeNotification,
object: avPlayerItem) // 获取视频总长度
/*
转换成秒,或用 duration.value / duration.timescale; 计算
*/
let duration:CMTime = avPlayerItem.duration
let totalSecond:Double = CMTimeGetSeconds(duration) // 跳转到指定位置
/*
10 / 1 = 10,跳转到第 10 秒的位置处
*/
avPlayerItem.seekToTime(CMTimeMake(10, 1)) // 设置播放速率
/*
默认为 1.0 (normal speed),设为 0.0 时暂停播放。设置后立即开始播放,可放在开始播放后设置
*/
avPlayer.rate = 1.0 // 获取当前播放速率
let rate:Float = avPlayer.rate // 开始播放
avPlayer.play() // 暂停播放
avPlayer.pause() // 设置音量
/*
范围 0 - 1,默认为 1
*/
avPlayer.volume = 0
2.2 使用 AVPlayerViewController 播放
Objective-C
// 显示播放页面
[self presentViewController:avPlayerVC animated:YES completion:nil]; // 设置画面缩放模式
/*
AVLayerVideoGravityResizeAspect 适应屏幕大小,保持宽高比,默认
AVLayerVideoGravityResizeAspectFill 充满屏幕,保持宽高比
AVLayerVideoGravityResize 充满屏幕,不保持宽高比
*/
avPlayerVC.videoGravity = AVLayerVideoGravityResizeAspect; // 获取显示在接收视图范围内的视频图像的位置和大小
CGRect videoBounds = avPlayerVC.videoBounds; // 获取播放控件所在的视图
/*
播放控件与播放内容界面之间的叠加视图
*/
UIView *contentOverlayView = avPlayerVC.contentOverlayView; // 设置是否显示播放控件
/*
Default is YES
*/
avPlayerVC.showsPlaybackControls = YES; // 设置是否允许画中画播放
/*
Default is YES
*/
avPlayerVC.allowsPictureInPicturePlayback = YES; // 判断是否准备好显示
BOOL readyForDisplay = avPlayerVC.isReadyForDisplay; // 设置画中画播放代理,需遵守协议 <AVPlayerViewControllerDelegate>
avPlayerVC.delegate = self; // 实现画中画播放
/*
这两行必须设置,不然画中画不能用,如果不写模拟器中可以画中画,但是在设备中不能
*/
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil]; // 获取视频准备播放状态
/*
AVPlayerItemStatusUnknown, 状态未知
AVPlayerItemStatusReadyToPlay, 准备好播放
AVPlayerItemStatusFailed 准备失败
*/
AVPlayerItemStatus status = avPlayerVC.player.currentItem.status; // 监听准备播放状态属性
[avPlayerVC.player.currentItem addObserver:self
forKeyPath:@"status"
options:NSKeyValueObservingOptionNew
context:nil]; // 系统自带监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context { if ([keyPath isEqualToString:@"status"]) { }
} // 获取视频缓冲进度
NSArray<NSValue *> *loadedTimeRanges = avPlayerVC.player.currentItem.loadedTimeRanges; CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue]; // 获取缓冲区域
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration); float loadedSecond = startSeconds + durationSeconds; // 计算缓冲总进度 // 监听缓冲进度属性
[avPlayerVC.player.currentItem addObserver:self
forKeyPath:@"loadedTimeRanges"
options:NSKeyValueObservingOptionNew
context:nil]; // 系统自带监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context { if ([keyPath isEqualToString:@"loadedTimeRanges"]) { }
} // 获取当前播放进度
/*
或用 avPlayerItem.currentTime.value/avPlayerItem.currentTime.timescale;
*/
CMTime currentTime = avPlayerVC.player.currentItem.currentTime;
float currentSecond = CMTimeGetSeconds(currentTime); // 监听播放进度
/*
NULL 在主线程中执行,每个一秒执行一次该 Block
*/
[avPlayerVC.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) { }]; // 添加播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playDidEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:avPlayerVC.player.currentItem]; // 获取视频总长度
/*
转换成秒,或用 duration.value / duration.timescale; 计算
*/
CMTime duration = avPlayerVC.player.currentItem.duration;
float totalSecond = CMTimeGetSeconds(duration); // 跳转到指定位置
/*
10 / 1 = 10,跳转到第 10 秒的位置处
*/
[avPlayerVC.player.currentItem seekToTime:CMTimeMake(10, 1)]; // 设置播放速率
/*
默认为 1.0 (normal speed),设为 0.0 时暂停播放。设置后立即开始播放,可放在开始播放后设置
*/
avPlayerVC.player.rate = 1.0; // 获取当前播放速率
float rate = avPlayerVC.player.rate; // 开始播放
[avPlayerVC.player play]; // 暂停播放
[avPlayerVC.player pause]; // 设置音量
/*
范围 0 - 1,默认为 1
*/
avPlayerVC.player.volume = 0;
Swift
// 显示播放页面
self.presentViewController(avPlayerVC, animated: true, completion:nil) // 设置画面缩放模式
/*
AVLayerVideoGravityResizeAspect 适应屏幕大小,保持宽高比,默认
AVLayerVideoGravityResizeAspectFill 充满屏幕,保持宽高比
AVLayerVideoGravityResize 充满屏幕,不保持宽高比
*/
avPlayerVC.videoGravity = AVLayerVideoGravityResizeAspect // 获取显示在接收视图范围内的视频图像的位置和大小
let videoBounds:CGRect = avPlayerVC.videoBounds // 获取播放控件所在的视图
/*
播放控件与播放内容界面之间的叠加视图
*/
let contentOverlayView:UIView = avPlayerVC.contentOverlayView! // 设置是否显示播放控件
/*
Default is YES
*/
avPlayerVC.showsPlaybackControls = true // 设置是否允许画中画播放
/*
Default is YES
*/
avPlayerVC.allowsPictureInPicturePlayback = true // 判断是否准备好显示
let readyForDisplay:Bool = avPlayerVC.readyForDisplay // 设置画中画播放代理,需遵守协议 <AVPlayerViewControllerDelegate>
avPlayerVC.delegate = self // 实现画中画播放
/*
这两行必须设置,不然画中画不能用,如果不写模拟器中可以画中画,但是在设备中不能
*/
let audioSession:AVAudioSession = AVAudioSession.sharedInstance()
try! audioSession.setCategory(AVAudioSessionCategoryPlayback) // 获取视频准备播放状态
/*
AVPlayerItemStatusUnknown, 状态未知
AVPlayerItemStatusReadyToPlay, 准备好播放
AVPlayerItemStatusFailed 准备失败
*/
let status:AVPlayerItemStatus = avPlayerVC.player!.currentItem!.status // 监听准备播放状态属性
avPlayerVC.player!.currentItem!.addObserver(self, forKeyPath: "status", options: .New, context: nil) // 系统自带监听方法
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?,
change: [String : AnyObject]?,
context: UnsafeMutablePointer<Void>) { if keyPath == "status" { }
} // 获取视频缓冲进度
let loadedTimeRanges:[NSValue] = avPlayerVC.player!.currentItem!.loadedTimeRanges let timeRange:CMTimeRange = loadedTimeRanges.first!.CMTimeRangeValue // 获取缓冲区域
let startSeconds = CMTimeGetSeconds(timeRange.start)
let durationSeconds = CMTimeGetSeconds(timeRange.duration) let loadedSecond:Double = startSeconds + durationSeconds // 计算缓冲总进度 // 监听缓冲进度属性
avPlayerVC.player!.currentItem!.addObserver(self, forKeyPath: "loadedTimeRanges", options: .New, context: nil) // 系统自带监听方法
override func observeValueForKeyPath(keyPath: String?,
ofObject object: AnyObject?,
change: [String : AnyObject]?,
context: UnsafeMutablePointer<Void>) { if keyPath == "loadedTimeRanges" { }
} // 获取当前播放进度
let currentTime:CMTime = self.avPlayerVC.player!.currentItem!.currentTime()
let currentSecond = CMTimeGetSeconds(currentTime) // 监听播放进度
avPlayerVC.player?.addPeriodicTimeObserverForInterval(CMTimeMake(1, 1), queue: nil, usingBlock: { (time:CMTime) in }) // 添加播放完成通知
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(AvPlayer.playDidEnd(_:)),
name: AVPlayerItemDidPlayToEndTimeNotification,
object: avPlayerVC.player!.currentItem!) // 获取视频总长度
/*
转换成秒,或用 duration.value / duration.timescale; 计算
*/
let duration:CMTime = avPlayerVC.player!.currentItem!.duration
let totalSecond = CMTimeGetSeconds(duration) // 跳转到指定位置
/*
10 / 1 = 10,跳转到第 10 秒的位置处
*/
avPlayerVC.player!.currentItem!.seekToTime(CMTimeMake(10, 1)) // 设置播放速率
/*
默认为 1.0 (normal speed),设为 0.0 时暂停播放。设置后立即开始播放,可放在开始播放后设置
*/
avPlayerVC.player!.rate = 1.0 // 获取当前播放速率
let rate = avPlayerVC.player!.rate // 开始播放
avPlayerVC.player!.play() // 暂停播放
avPlayerVC.player!.pause() // 设置音量
/*
范围 0 - 1,默认为 1
*/
avPlayerVC.player!.volume = 0
3、AVPlayerViewControllerDelegate 画中画协议方法
Objective-C
// 将要开始画中画播放
- (void)playerViewControllerWillStartPictureInPicture:(AVPlayerViewController *)playerViewController { } // 已经开始画中画播放
- (void)playerViewControllerDidStartPictureInPicture:(AVPlayerViewController *)playerViewController { } // 画中画播放失败
- (void)playerViewController:(AVPlayerViewController *)playerViewController failedToStartPictureInPictureWithError:(NSError *)error { } // 将要结束画中画播放
- (void)playerViewControllerWillStopPictureInPicture:(AVPlayerViewController *)playerViewController { } // 已经结束画中画播放
- (void)playerViewControllerDidStopPictureInPicture:(AVPlayerViewController *)playerViewController { } // 画中画播放开始时播放控制器界面是否自动退出
- (BOOL)playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:(AVPlayerViewController *)playerViewController { // 是否在开始画中画时自动将当前的播放界面 dismiss 掉,返回 YES 则自动 dismiss,返回 NO 则不会自动 dismiss
return NO;
} // 画中画停止之前恢复用户界面
- (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler { // 用户点击还原按钮,从画中画模式还原回 App 内嵌模式时调用的方法
}
Swift
// 将要开始画中画播放
func playerViewControllerWillStartPictureInPicture(playerViewController: AVPlayerViewController) { } // 已经开始画中画播放
func playerViewControllerDidStartPictureInPicture(playerViewController: AVPlayerViewController) { } // 画中画播放失败
func playerViewController(playerViewController: AVPlayerViewController, failedToStartPictureInPictureWithError error: NSError) { } // 将要结束画中画播放
func playerViewControllerWillStopPictureInPicture(playerViewController: AVPlayerViewController) { } // 已经结束画中画播放
func playerViewControllerDidStopPictureInPicture(playerViewController: AVPlayerViewController) { } // 画中画播放开始时播放控制器界面是否自动退出
func playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart(playerViewController: AVPlayerViewController) -> Bool { // 是否在开始画中画时自动将当前的播放界面 dismiss 掉,返回 YES 则自动 dismiss,返回 NO 则不会自动 dismiss
return false
} // 画中画停止之前恢复用户界面
func playerViewController(playerViewController: AVPlayerViewController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: (Bool) -> Void) { // 用户点击还原按钮,从画中画模式还原回 App 内嵌模式时调用的方法
}
iOS - AVPlayer 音视频播放的更多相关文章
- iOS AVKit音视频播放全面详解
公司项目中经常要用到音视频处理,也需要去定制一些东西,然后整理这些音视频处理就显得尤为重要!方便自己和广大朋友学习收藏! 以下参考连接特别重要: 苹果官方:AVKit API 苹果官方:AVFound ...
- iOS 音视频播放
播放控制切换为: ijkplayer wiki: https://github.com/changsanjiang/SJVideoPlayer/wiki/Use-ijkplayer 播放控制切换为: ...
- iOS AVPlayer视频播放器
代码地址如下:http://www.demodashi.com/demo/11168.html 一.运行效果 二.实现过程 ①.创建播放器avPlayer //创建播放器 url = [url str ...
- Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
- Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
- AVAudioFoundation(2):音视频播放
本文转自:AVAudioFoundation(2):音视频播放 | www.samirchen.com 本文主要内容来自 AVFoundation Programming Guide. 要播放 AVA ...
- Android音视频之MediaPlayer音视频播放
前言: 昨天总结了视频录制,今天来学习一下视频的播放,Android的视频播放主要采用MediaPlayer类. MediaPlayer介绍 MediaPlayer类可用于控制音频/视频文件或流的播放 ...
- Pyqt 音视频播放器
在寻找如何使用Pyqt做一个播放器时首先找到的是openCV2 openCV2 貌似太强大了,各种关于图像处理的事情它都能完成,如 读取摄像头.图像识别.人脸识别. 图像灰度处理 . 播放视频等,强 ...
- Android IOS WebRTC 音视频开发总结(四六)-- 从另一个角度看国内首届WebRTC大会
文章主要从开发者角度谈国内首届WebRTC大会,支持原创,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help. -------------------- ...
随机推荐
- weblogic .NoClassDefFoundError: Could not initialize class sun.awt.X11Graphi
这个是常见问题,可以通过增加Weblogic的启动参数来解决: -Djava.awt.headless=true 你可以修改 startWebLogic.sh 文件. export JAVA_OPTI ...
- Oracle将表keep到内存
一.引言: 有时候一些基础表需要非常的频繁访问,尤其是在一些循环中,对该表中的访问速度将变的非常重要.为了提高系统的处理性能,可以考虑将一些表及索引读取并保存到内存中. 二.关于keep内存的几个参数 ...
- 一道面试题比较synchronized和读写锁
一.科普定义 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步关键字相信大家都用得比较多,在上一篇“多个线程之间共享数据的方式”中也详细列举他的应用, ...
- php连接函数implode()和分割explode()
php可以将字符串分割成数组,同时翻过了也可以将数组连接成字符串,确切的说是可以将数组元素连接成字符串,有了这两个函数我们就可以在数组与字符串之间进行自由转换了,下面看正文的例子吧. implode( ...
- Codeforces 733C:Epidemic in Monstropolis(暴力贪心)
http://codeforces.com/problemset/problem/733/C 题意:给出一个序列的怪兽体积 ai,怪兽只能吃相邻的怪兽,并且只有体积严格大于相邻的怪兽才能吃,吃完之后, ...
- [c++][语言语法]函数模板和模板函数 及参数类型的运行时判断
参考:http://blog.csdn.net/beyondhaven/article/details/4204345 参考:http://blog.csdn.net/joeblackzqq/arti ...
- [ios][swift]Swift - 常用文件目录路径获取(Home目录,文档目录,缓存目录等)
自己写的不一定是最好的! 轮子:http://www.hangge.com/blog/cache/detail_765.html
- 杭电1019-Least Common Multiple
#include<stdio.h>int gcd(int a,int b);int main(){ int n,m,a,b,i,sum;//sum是最小公倍数 scanf(&q ...
- 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind
最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...
- SlickGrid example 3: 可编辑单元
<button onclick="grid.setOptions({autoEdit:true})"> 设置自动辅助编辑下一个元素. 代码: <!DOCTYP ...