快速进阶
所有文档

          音视频处理 MCP

          快速进阶

          正确释放播放器

          保证App稳定、高效的运行,正确释放播放器非常重要。

          目前主流的交互基本是这样的:

          1. 用户点击视频列表中的某一个视频,将播放UIpushUINavigationController上;
          2. 播放UI开始加载视频并播放;
          3. 用户点击后退按钮退出播放,播放UIUINavigationController pop 掉。

            这里重点关注第3步,介绍释放播放器的时机、流程:

            • 当用户点击后退按钮时,只调用播放器的stop方法;

              - (IBAction)onBackButton:(id)sender {
                  [self.player stop];
              }
            • 等待播放器发送BDCloudMediaPlayerPlaybackDidFinishNotification通知后,再将播放UIUINavigationController pop 掉。

              // 注册通知
              - (void)setupNotifications {
                  [[NSNotificationCenter defaultCenter] addObserver:self
                  	                                             selector:@selector(onPlayerFinish:)
                  	                                                 name:BDCloudMediaPlayerPlaybackDidFinishNotification
                  	                                               object:nil];
                  	}
              
                  	// 等到Finish通知后再pop
              - (void)onPlayerFinish:(NSNotification*)notification {
                  	    // 如果同时有多个播放器实例的话,最好判断下通知里的object是否跟持有的是同一个。
                  	    if (notification.object != self.player) {
                  	        return;
                  	    }
                      
                  	    // pop UI
                  	    [self.navigationController popViewControllerAnimated:YES];
                  	}

            这样的流程可以保证在退出播放UI时,播放器内部本次播放相关资源也已释放完毕,有利于复用播放器实例,发起下一次播放。

          进度条相关

          视频播放器进度条上包括下列3个信息:

          • 视频总时长duration
          • 当前播放时间currentPlaybackTime
          • 当前缓冲时间playableDuration

          在收到BDCloudMediaPlayerPlaybackIsPreparedToPlayNotification通知后,可以获取duration确定进度条的maximumValue(直播视频可能获取到的值为零)。并启动一个每秒触发一次的NSTimer,来实时获取currentPlaybackTimeplayableDuration,更新进度条。

          注意: iOS系统没有提供带缓冲进度的进度条,需要用户自行实现。

          播放下一个视频

          正在播放视频时,如果想放弃当前的播放,并立即在当前播放UI播放另一个视频时,可以按照下面的方式来操作:

          - (IBAction)onPlayNext:(id)sender {
              // 停止当前视频的播放。
              [self.player stop];
              
              // reset播放器到初始状态。
              [self.player reset];
              
              // 开始下一个视频的初始化和播放流程。
              self.player.contentString = @"<next url>";
              self.player.shouldAutoplay = YES;
              [self.player prepareToPlay];
          }

          APM接入

          APM SDK 提供数据监控、发送、后台报表处理与展示能力。实时性强,能够及时上报用户在点播、直播中的卡顿、网速等信息,方便运营方及时调整策略和调度。

          SDK不直接依赖APM SDK,在运行时动态检查App是否接入了APM SDK

          多码率切换

          多码率快速切换

          当播放的是HLS多码率视频时,播放器支持在播放过程中实时切换码率。具体操作步骤如下:

          1. 在收到BDCloudMediaPlayerPlaybackIsPreparedToPlayNotification通知后,调用获取多码率列表的接口;
          2. 将多码率列表显示在播放UI上供用户选择码率;

            以上两步代码示例:

           - (void)onPlayerPrepared:(NSNotification*)notification {
               // 如果同时有多个播放器实例的话,最好判断下通知里的object是否跟持有的是同一个。
               if (notification.object != self.player) {
                   return;
               }
               
               // 获取多码率列表。
               NSArray<BDCloudMediaPlayerBitrateItem*>* items = [self.player getSupportedBitrates];
               
               // 将码率列表显示在UI上。
               [self showBitrateList:items];
           }
          1. 用户选择码率时,调用setBitrateIndex:方法设置码率索引:
           - (IBAction)onChangeBitrate:(id)sender {
               NSInteger index = <bitrateIndex>;
               [self.player setBitrateIndex:index];
           }

          多码率无缝切换

          播放器不仅支持HLS的多码率快速切换,同时也支持HLS,MP4等主流媒体格式的无缝切换功能。具体操作如下:

          Master playlist 的HLS格式多码率无缝切换

          1. 设置输入格式
           - (void)setMediaInputType:(NSInteger)inputType {
               [self.player setMediaItemsInputType:inputType];
           }
          1. 在收到BDCloudMediaPlayerPlaybackIsPreparedToPlayNotification通知后,调用获取多码率列表的接口,显示到UI。
           - (void)onPlayerPrepared:(NSNotification*)notification {
               // 如果同时有多个播放器实例的话,最好判断下通知里的object是否跟持有的是同一个。
               if (notification.object != self.player) {
                   return;
               }
               
               // 获取多码率列表。
               NSArray* bitrates = [self.player getMediaItems];
               
               // 获取当前码率索引
               int index = (int)[self.player mediaItemIndex];
               
               // 将码率列表显示在UI上。
               [self.actions updateBitrateList:bitrates index:index];
           }
          1. 用户根据对应索引切换到指定码率。
           - (void)changeBitrate:(NSInteger)index {
               [self.player setMediaItemIndex:index];
           }
          1. 当收到BDCloudMediaPlayerMediaChangeStartNotification 通知表示视频开始切换。
          2. 当收到BDCloudMediaPlayerMediaChangeEndNotification 通知表示切换结束,同时可以取BDCloudMediaPlayerMediaChangeEndResultUserInfoKey 的值判断切换是否成功。此时播放器缓冲播放完成后即会切换到新的码率显示。
          3. 当收到BDCloudMediaPlayerNaturalSizeChangedNotification 通知表示视频分辨率发生变化。

          MP4等非嵌套码率的无缝切换

          1. 设置输入格式
           - (void)setMediaInputType:(NSInteger)inputType {
               [self.player setMediaItemsInputType:inputType];
           }
          1. 设置多码率视频链接(注意这里和HLS的区别)
           - (void)setMediaInputList:(NSArray *)inputList {
               [self.player setMediaItems:inputList];
           }
          1. 在收到BDCloudMediaPlayerPlaybackIsPreparedToPlayNotification通知后,调用获取多码率列表的接口,显示到UI。
           - (void)onPlayerPrepared:(NSNotification*)notification {
               // 如果同时有多个播放器实例的话,最好判断下通知里的object是否跟持有的是同一个。
               if (notification.object != self.player) {
                   return;
               }
               
               // 获取多码率列表。
               NSArray* bitrates = [self.player getMediaItems];
               
               // 获取当前码率索引
               int index = (int)[self.player mediaItemIndex];
               
               // 将码率列表显示在UI上。
               [self.actions updateBitrateList:bitrates index:index];
           }
          1. 用户根据对应索引切换到指定码率。
           - (void)changeBitrate:(NSInteger)index {
               [self.player setMediaItemIndex:index];
           }
          1. 当收到BDCloudMediaPlayerMediaChangeStartNotification 通知表示视频开始切换。
          2. 当收到BDCloudMediaPlayerMediaChangeEndNotification 通知表示切换结束,同时可以取BDCloudMediaPlayerMediaChangeEndResultUserInfoKey 的值判断切换是否成功。此时播放器缓冲播放完成后即会切换到新的码率显示。
          3. 当收到BDCloudMediaPlayerNaturalSizeChangedNotification 通知表示视频分辨率发生变化。

          播放HLS加密视频

          百度媒体云MCT服务支持转码成HLS加密视频。

          不同的加密方式,播放时的方法略有不同:

          • PlayerBinding加密模式 按普通视频播放即可。
          • 自定义PlayerId、PlayerKey模式

            播放之前需要先设置playerIdplayerKey

            (void)play {
                // 先设置`playerId`和`playerKey`。
                [self.player setPlayerID:@"<playerId>" key:@"<playerKey>"];
                
                // 再播放视频。
                self.player.contentString = @"<url>";
                self.player.shouldAutoplay = YES;
                [self.player prepareToPlay];
            }
          • Token模式

            播放之前需要先设置token

             (void)play {
                 // 先设置`token`。
                 [self.player setToken:@"<token>"];
                 
                 // 再播放视频。
                 self.player.contentString = @"<url>";
                 self.player.shouldAutoplay = YES;
                 [self.player prepareToPlay];
             }    

          设置HTTP请求的Header

          如果需要设置常见的一些HTTP Header字段,例如User-Agent,可以使用接口setOptionValue

          NSString* value = @"User-Agent: <your user agent>";
          [player setOptionValue:value
                          forKey:@"headers"
                      ofCategory:BDCloudMediaPlayerOptionCategoryFormat];

          说明:

          如果需要设置多个HTTP Header字段,需要按照HTTP规范,将多个字段使用\r\n 连接起来。

          下载HLS视频

          SDK 除了提供视频播放功能之外,还支持 HLS 视频的下载。类BDCloudMediaDownload提供下载相关接口。

          普通HLS视频的下载

          下面介绍下载的基本流程:

          1. 实现BDCloudMediaDownloadDelegate来响应下载任务的状态变化回调
              // 任务开始
              - (void)taskStart:(BDCloudMediaDownloadTask*)task {
              }
          
              // 任务的进度汇报
              - (void)task:(BDCloudMediaDownloadTask*)task progress:(float)progress {
                  NSLog(@"任务%@, 下载进度 %.2f", task, progress);
              }
          
              // 任务完成,error为nil表示下载成功。
              - (void)taskEnd:(BDCloudMediaDownloadTask*)task error:(NSError*)error {
                  if (!error) {
                      NSLog(@"下载成功!");
                      // 获取离线视频的本地路径,拿到之后就可以离线播放。
                      NSString* path = [task.item.path stringByAppendingPathComponent task.item.index];
                  }
              }
          1. 创建下载器

            下载器初始化时,需要传入用户名,用于在本地区分不同登录用户的下载存储(如果App没有账号系统,可以传一个固定值)。

              self.downloader = [[BDCloudMediaDownload alloc] initWithUser:@"<user>" delegate:self];
          1. 创建下载任务、开始下载

            创建下载任务后,任务会进入到执行队列中,队列的最大并发数是4个。当超出最大并发数时,新创建的任务会处于等待执行的状态。

              NSError* error;
              BDCloudMediaDownloadTask* task = [self.downloader downloadTaskWithURL:@"<url>" title:@"<title>" error:&error];

          注意:

          • 传入的url必须以httphttps开头,以.m3u8结尾。
          • 如果传入的url曾经下载成功,并且也没有调用过 removeMediaItem接口对视频数据进行清理,创建下载任务将会失败,error的code会被赋值为BDCloudMediaDownloadErrorCodeAlreadyExists

          加密HLS视频的下载

          加密HLS视频的下载与普通的HLS视频下载相比,多出设置认证信息的过程,只需要实现代理方法task:needAuthentication:

          - (void)task:(BDCloudMediaDownloadTask*)task needAuthentication:(NSMutableDictionary*)parameters {
              // 当下载的视频是PlayerID, PlayerKey加密方式时,需要在parameters里设置playerId
              [parameters setObject:@"<playerId>" forKey:@"playerId"];
              
              // 当下载的视频是token加密方式时,需要在parameters里设置token
              [parameters setObject:@"<token>" forKey:@"token"];
          }

          任务的暂停和恢复

          下载任务支持暂停和恢复:

          • 暂停时,下载到本地的数据不会丢失;
          • 恢复时,会从上次下载的位置继续下载。
          // 暂停任务
          [self.downloader suspendTask:task];
          
          // 恢复任务
          [self.downloader resumeTask:task];

          断点续传

          当App重新打开要继续上次未完成的下载时,需要先调用resumeUncompletedTasks方法(SDK内部会根据保存的任务状态,自动创建未完成的任务并加入下载队列)返回未完成的下载任务。

          self.downloader = [[BDCloudMediaDownload alloc] initWithUser:@"<user>" delegate:self];
          
          // 获取上次未下载完成的任务。
          self.tasks = [self.downloader resumeUncompletedTasks];

          注意:

          • 缩略图的规则和获取需要配置MCT转码模板后转码才可使用。

          下载并显示缩略图

          • SDK 除了提供视频播放功能之外,还支持下载并显示缩略图。BDCloudSpriteManager提供缩略图相关接口。
          // 1. 初始化雪碧图渲染配置并设置必要属性。
          BDCloudSpriteRenderConfiguration *renderConfig = [BDCloudSpriteRenderConfiguration defaultConfiguration];
          renderConfig.row = <雪碧图中缩略图的行数>;
          renderConfig.column = <雪碧图中缩略图的列数> ;
          renderConfig.thumbnailDuration = <每个缩略图的时间间隔>;
          
          // 2. 初始化雪碧图下载配置并设置必要属性。
          BDCloudSpriteDownloadConfiguration *downloadConfig = [BDCloudSpriteDownloadConfiguration defaultConfiguration];
          downloadConfig.imageList = <雪碧图的URL列表>;
          downloadConfig.maxThreadNum = <下载开启的做大线程数>;
          downloadConfig.path = <下载地址>;
          
          // 3. 初始化雪碧图渲染控制类,并添加显示的画布。
          BDCloudSpriteManager *manager = [BDCloudSpriteManager initWithRenderConfig:renderConfig downloadConfig:downloadConfig];
          manager.renderView.frame = <画布frame>;
          [self.view addSubView:manager.renderView]
          [manager startDownload:nil];
          
          // 4. 用户收到下载成功回调后,根据时间戳显示缩略图。
          [manager renderTime:<显示时间戳>]; 

          注意:

          • 当前网络视频加速只支持mp4格式。

          网络视频加速

          SDK 除了提供视频播放功能之外,还支持网络视频加速。BDCloudMediaSourceManager提供网络视频加速播放。包含以下功能:

          • 视频预下载。
          • 边播边存。
          // 1. 预下载视频。
          [[BDCloudMediaSourceManager sharedInstance] download:url size:downloadSize complete:^(BOOL succ, NSError *error) {
              NSLog(@"pre download succ = %d, error = %@",error);            
          }];
          
          // 2. 开启边播边存
          [BDCloudMediaSourceManager sharedInstance].autoWriteCache = YES;
          
          // 3. 播放器设置网络代理。
          self.player.proxy = [BDCloudMediaSourceManager sharedInstance];
          
          // 4. 预下载完成后开始播放。
          [self.player prepareToPlay]

          VR视频播放

          SDK 除了提供基础的视频播放功能之外,还支持VR视频播放。BDCloudVRRender提供VR视频播放。

          // 1. 配置VR播放基础信息
          // 1.1 默认信息创建实例。
          self.vrConfig = [BDCloudVRConfiguration defaultConfig];
          // 1.2 配置VR资源类型。
          [self.vrConfig setProjectionMode:<projectionMode>];
          // 1.3 配置渲染模式。
          [self.vrConfig setDisplayMode:<displayMode>];
          // 1.4 配置交互模式。
          [self.vrConfig setInteractiveMode:<interactiveMode>];
          // 1.6 配置捏合手势。
          [self.vrConfig setPinchEnabled:<pinchEnabled>];
          
          // 2. 接受到解码信息通知,配置解码信息后初始化VR渲染控制类开始VR渲染。
          - (void)onPlayerVideoDecoderOpen:(NSNotification *)notification {
              if (notification.object != _player) {
                  return;
              }
              if (self.vrConfig) {
                  // 2.1 配置解码信息
                  [self.vrConfig setProviderBDCloudMediaPlayerView:_player.view
                                         viaHardwareAccelerate:[_player viaHardwareAccelerate]];
                  // 2.2 配置渲染父视图
                  [self.vrConfig setRenderOn:self.player.view];
                  // 2.3 初始化VR渲染控制类
                  self.vrManager = [BDCloudVRRenderControl renderWithConfig:self.vrConfig];
                  // 2.4 开始VR渲染。
                  [self.vrManager resume];
              }
          }
          上一篇
          快速开始
          下一篇
          接口速查