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. -------------------- ...
随机推荐
- Web SQL
HTML5本地存储——Web SQL Database 基于 HTML5 中的 Web SQL Database 来构建应用程序 前端HTML5几种存储方式的总结 <!DOCTYPE HTML& ...
- declare和typeset DEMO
declare=typeset,用法完成相同. declare不指定变量:显示所有变量的值. -r选项,把指定变量定义为只读变量: [xiluhua@vm-xiluhua][~]$ declare - ...
- vim查找/替换字符串
1.:s 命令来替换字符串. :s/vivian/sky/ 替换当前行第一个 vivian 为 sky :s/vivian/sky/g 替换当前行所有 vivian 为 sky :n,$s/vivia ...
- 阅读推荐——深入浅出Mesos
深入浅出Mesos(一):为软件定义数据中心而生的操作系统http://www.infoq.com/cn/articles/analyse-mesos-part-01 深入浅出Mesos(二):Mes ...
- 手机端上传未知图片大小,js设置宽高比例
<style rel="stylesheet" type="text/css"> .lunboimg{ width: 100%; height: a ...
- android 系统相册调用,各版本的区别总结
请求系统相册有三个Action: (注意以下 图库(缩略图) 和 图片(原图) 的区别) ACTION_OPEN_DOCUMENT 仅限4.4或以上使用 默认打开原图 ACTION_ ...
- cookie与localstorage和sessionstorage的区别比较
保存位置: 三者均保存在浏览器端,且同源的. 与服务器的关系: cookie 数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递. sessionStorage ...
- c#中的委托和事件(转)
引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...
- JAVA基础知识之多线程——控制线程
join线程 在某个线程中调用其他线程的join()方法,就会使当前线程进入阻塞状态,直到被join线程执行完为止.join方法类似于wait, 通常会在主线程中调用别的线程的join方法,这样可以保 ...
- linq的创建 和 数据的增删改查
1.linq创建之前,一定要在sql做好数据表的主外键关系. 2.linq文件是以.dbml结尾,一般一个数据库的名字就是一个linq的名字 3,以实例来演示增删改查 数据库的名字为linq,里面有两 ...