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. -------------------- ...
随机推荐
- Android网络连接之HttpURLConnection和HttpClient
1.概念 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源.在 JDK 的 java.net 包中 ...
- android pbap client 蓝牙
一. 简介: 此功能具体使用的是bluetoothV2.1之后的Phone Book Access Profile功能,简称PBAP .目前MTK Android中只实现了server端的功能,并没 ...
- Catch That Cow 分类: POJ 2015-06-29 19:06 10人阅读 评论(0) 收藏
Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 58072 Accepted: 18061 ...
- Design T-Shirt 分类: HDU 2015-06-26 11:58 7人阅读 评论(0) 收藏
Design T-Shirt Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- C++的几种强制类型转换
有时我们希望显式地将对象强制类型转换成另外一种类型.例如,如果想在下面的代码中执行浮点数除法: int i, j; double slope = i / j; 就要使用某种方法将i和/或j显式地转换成 ...
- Codeforces Round #368 (Div. 2) A
Description Small, but very brave, mouse Brain was not accepted to summer school of young villains. ...
- Redis安装及配置(Linux)
ubuntu 16.04安装redis-server apt-get install redis-server 启动.停止.重启.重新加载.查看状态 /etc/init.d/redis-server ...
- Duilib创建窗口双击标题栏禁止窗口最大化
使用Duilib创建窗口并禁止窗口最大化 第一步: XXXFrame.Create(NULL, _T("XXXFrame"), UI_WNDSTYLE_EX_FRAME, WS_E ...
- oracle分组统计某列逗号隔开数据
所有版本的oracle都可以使用select wm_concat(name) as name from user; 但如果是oracle11g,使用select listagg(name, ',') ...
- 高通安卓调试LCD几方面总结
来公司上班现在已经整整一个月了,蔽人不才,能力有限,学习进度缓慢,不过也是有一点点的收获与心得,在这里写出来与大家分享,养成良好的记录习惯也免得后忘记. 不啰嗦了,开入正题.来公司一个月左右的时间,主 ...