iOS - AVPlayer 音视频播放

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 内嵌模式时调用的方法
        }
时间: 2024-10-09 23:26:00

iOS - AVPlayer 音视频播放的相关文章

iOS AVKit音视频播放全面详解

公司项目中经常要用到音视频处理,也需要去定制一些东西,然后整理这些音视频处理就显得尤为重要!方便自己和广大朋友学习收藏! 以下参考连接特别重要: 苹果官方:AVKit API 苹果官方:AVFoundation API 苹果官方:AVFoundation 专题(开发指引.视频.文章.代码) 苹果官方:AVFoundation Programming Guide iOS 教你使用MP.AVPlayer.AVPlayerVC构建一个完整的视频播放器 iOS - AVPlayer 音视频播放 基于 A

IOS开发之音视频播放

/* 以前一直在纠结,为什么博客园不能够上传代码,把赤裸裸的代码以字符串的形式显示在鄙人的页面上实在是可不舒服 ,好了 ,现在可以一试了 */ 关于视屏播放,可以说只要是个初学者,一直在好奇的事情,就是因为那些爱奇艺,搜狐,腾讯的视频播放器不但要下下来,还要收费,所以我一直觉得关于视频播放是不是有版权或者是他们的播放器做的很高大上,但是在我们IOS之中,学完这个视频播放,也许你会认为很简单: 首先是先讲讲关于视频播放在IOS9之后有了很大的改变 弃用MPMoviePlayerViewContro

Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:blackerteam 或 webrtcorgcn). 回顾:Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上) 连接网络摄像头 正如上文所提,我们选用一款简单的D-Link DCS-7010L网络摄像头.关键原因在于它支持RTSP协议,因此服务

iOS AVPlayer 后台播放问题自动停止问题 防止应用被后台挂起方法

iOS AVPlayer 后台播放问题自动停止问题 防止应用被后台挂起方法 2016-09-08 16:16 1597人阅读 评论(0) 收藏 举报  分类: iOS 开发笔记(37)  版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 1.创建播放器时创建AVAudioSession [objc] view plain copy AVAudioSession *session = [AVAudioSessionsharedInstance]; [session setCa

iOS AvPlayer AvAudioPlayer音频的后台播放问题

王桂敏 iOS AvPlayer AvAudioPlayer音频的后台播放问题 iOS 4开始引入的multitask,我们可以实现像ipod程序那样在后台播放音频了.如果音频操作是用苹果官方的AVFoundation.framework实现,像用AvAudioPlayer,AvPlayer播放的话,要实现完美的后台音频播放,依据app的功能需要,可能需要实现几个关键的功能. 首先,播放音频之前先要设置AVAudioSession模式,通常只用来播放的App可以设为AVAudioSessionC

Pyqt 音视频播放器

在寻找如何使用Pyqt做一个播放器时首先找到的是openCV2 openCV2 貌似太强大了,各种关于图像处理的事情它都能完成,如 读取摄像头.图像识别.人脸识别.  图像灰度处理 . 播放视频等,强大的让你想不到! openCV2 播放视频也很简单: 1 #coding=utf-8 2 3 import cv2.cv as cv 4 filename = "cn.avi" 5 win_name = "video player" 6 capture = cv.Cap

Android IOS WebRTC 音视频开发总结(六八)-- Google: What&#39;s next for WebRTC

本文主要从用户,公司和技术角度分析美女视频直播这个行业,文章最早发表在我们的微信公众号上,支持原创,详见这里, 欢迎关注微信公众号blackerteam,更多详见www.rtc.help Justion和Sarah是google webrtc项目的主要负责人,下面的图片是根据他们分享的内容进行整理的,涉及webrtc进展.优化等方方面面.整理这些资料的过程中我们发现他们对待webrtc还是挺用心的,为webrtc的完善做了很多的工作,谢谢他们! 原始视频时长53分13秒,全英文的,所以我们考虑做

转:?Android IOS WebRTC 音视频开发总结 (系列文章集合)

随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:blackerteam 或 webrtcorgcn). callstats是一家做实时通讯性能测阅读全文 posted @ 2016-07-22 08:24

Android IOS WebRTC 音视频开发总结(六)

前段时间在搞IOS的音视频版本,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面总结一下开发过程中的一些经验: 1. IOS WebRTC音视频编译和下载: 有过android WEBRTC编译下载经验再去弄IOS,你会发现简单多了,再有问题,可以参考:http://www.cnblogs.com/ProbeStar/p/3411510.html  记住有MAC和IOS两个版本,要指定好你想要哪个版本. 2. 正确区分armv7 armv7s i386平台: 编译的时