Polyv Help Center

Help Center

8 Triple Screen

Updated: 2023-04-17 15:27:58

8.1 Overview

Triple screen is a dual-window playback mode that supports synchronized playback of PPT or PDF documents with video. It uses one large and one small playback window, with flexible layout, allowing free switching of the main screen playback content. It supports setting playback time points for each page of PPT or PDF documents to achieve automatic page turning, supports clicking on courseware in the courseware directory to jump to playback progress, and supports downloading to the local device for offline playback. This provides possibilities for richer teaching scenarios for customers.

8.2 Quick Integration

8.2.1 SDK Version

To use the triple screen feature for on-demand playback, upgrade PolyvVodSDK to version 2.6.5 or above. Set the Podfile as follows:

pod 'PolyvVodSDK', '~> 2.6.5'

8.2.2 Open Source Code

Secondly, most of the code is provided in the PolyvOpenSourceModule/PPT folder of the demo project. Update the demo code to version 2.6.5 or above, then drag the code from this folder into your project. The file directory under this folder is as follows:

└── PPT ├── Controller │ ├── PLVPPTBaseViewController.h │ ├── PLVPPTBaseViewController.m │ ├── PLVPPTBaseViewControllerInternal.h │ ├── PLVPPTVideoViewController.h │ ├── PLVPPTVideoViewController.m │ ├── PLVPPTViewController.h │ └── PLVPPTViewController.m └── View ├── PLVFloatingView.h ├── PLVFloatingView.m ├── PLVPPTActionView.h ├── PLVPPTActionView.m ├── PLVPPTActionViewCell.h ├── PLVPPTActionViewCell.m ├── PLVPPTControllerSkinView.h ├── PLVPPTControllerSkinView.m ├── PLVPPTFailView.h ├── PLVPPTFailView.m ├── PLVPPTLoadFailAlertView.h ├── PLVPPTLoadFailAlertView.m ├── PLVPPTSkinProgressView.h └── PLVPPTSkinProgressView.m

8.2.3 Demo Example

In the demo project under the Classes path, we provide the triple screen playback page PLVPPTSimpleDetailController. You can use this page for triple screen playback. The usage code is as follows:

PLVPPTSimpleDetailController *vctrl = [[PLVPPTSimpleDetailController alloc] init];
vctrl.vid = @"准备播放的视频 vid";
vctrl.isOffline = NO;
[self.navigationController pushViewController:vctrl animated:YES];

The property isOffline defaults to NO, meaning it calls the API to obtain video resources. If there is no network, playback is not possible even if the local cache exists. If set to YES, it retrieves video resources locally. If there is no network, playback is possible as long as the local cache exists.

8.2.4 Project Configuration

Since the image links for PPT documents use the HTTP protocol, you need to add the following Key-Value in the App Transport Security Settings / Exception Domains section of the project's Info.plist file:

<key>doc.polyv.net</key>
  <dict>
    <key>NSExceptionAllowsInsecureHTTPLoads</key>
    <true/>
  </dict>

The effect is shown in the following figure:

Triple Screen_Figure1

8.3 Video Player

8.3.1 Triple Screen Switch

The video player PLVVodPlayerViewController in the on-demand SDK adds a Boolean property enablePPT, indicating whether to enable the PPT function. The default is NO, meaning the PPT will not be displayed regardless of whether the video has a PPT. It can be set in the method -player of PLVPPTVideoViewController.m. The code in the demo is as follows:

- (PLVVodSkinPlayerController *)player {
    if (!_player){
        _player = [[PLVVodSkinPlayerController alloc] init];
        _player.enablePPT = YES;
        _player.enableBackgroundPlayback = YES;
        _player.autoplay = YES;
        _player.enableAd = YES;
    }
    return _player;
}

In addition to setting enablePPT, you can also configure other player properties here, such as whether to allow background playback enableBackgroundPlayback, whether to auto-play autoplay, whether to enable ads enableAd, etc. For more parameters, refer to the on-demand documentation 4 Video Playback - 4.5 Player Configuration.

8.3.2 Player Skin

The player skin PLVVodPlayerSkin provided in the demo's open-source component PolyvOpenSourceModule adds a [Toggle Triple Screen Small Window] button and a [Courseware] button when in fullscreen mode. Clicking [Toggle Triple Screen Small Window] opens or closes the small window. Clicking the [Courseware] button pops up the courseware directory list in fullscreen mode. The code for the new buttons in the open-source component's player skin is as follows:

/// 竖屏播放器皮肤
@interface PLVVodShrinkscreenView : UIView

@property (weak, nonatomic) IBOutlet UIButton *subScreenButton; // 关闭三分屏按钮

@end
/// 全屏播放器皮肤
@interface PLVVodFullscreenView : UIView

@property (weak, nonatomic) IBOutlet UIButton *subScreenButton; // 关闭三分屏按钮
@property (weak, nonatomic) IBOutlet UIButton *pptCatalogButton; // 显示课件目录按钮

@end

The display and hiding of the buttons are controlled in PLVVodPlayerSkin.m. These two buttons are only displayed when enablePPT is YES and the audio/video being played contains a PPT or PDF document.

8.3.3 Playback Progress Callback

PLVVodSkinPlayerController adds a player callback. The code is as follows:

@interface PLVVodSkinPlayerController : PLVVodPlayerViewController

// 播放进度回调
@property (nonatomic, copy) void (^playbackTimeHandler)(NSTimeInterval currentPlaybackTime);

@end

The triple screen function will use this callback to synchronize document and video playback. The code example in PLVPPTBaseViewController is as follows:

__weak typeof(self) weakSelf = self;
self.videoController.player.playbackTimeHandler = ^(NSTimeInterval currentPlaybackTime) {
      [weakSelf.pptController playAtCurrentSecond:(int)currentPlaybackTime];
};

Here, self.videoController.player is an instance of PLVVodSkinPlayerController, and weakSelf.pptController is the PPT player mentioned below.

8.3.4 Player Container

PLVPPTVideoViewController is the view container for the player, used to configure the video player, control the player skin, and handle video playback business logic code. The code example in PLVPPTBaseViewController is as follows:

#import "PLVPPTBaseViewController.h"
#import "PLVPPTVideoViewController.h"
#import <PLVVodSDK/PLVVodSDK.h>

@interface PLVPPTBaseViewController ()<
PLVPPTVideoViewControllerProtocol
>

@property (nonatomic, strong) UIView *mainView; // 大屏视图
@property (nonatomic, strong) PLVPPTVideoViewController *videoController;

@end

@implementation PLVPPTBaseViewController

#pragma mark - Life Cycle
  
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.mainView];
    [self.mainView addSubview:self.videoController.view]; // 添加播放器视图到大屏视图
}

- (void)dealloc{
    _videoController.delegate = nil;
}

#pragma mark - Getter & Setter

- (PLVPPTVideoViewController *)videoController {
    if (!_videoController){
        _videoController = [[PLVPPTVideoViewController alloc] init];
        _videoController.delegate = self;
    }
    return _videoController;
}

#pragma mark - PLVPPTVideoViewControllerProtocol

- (void)videoWithVid:(NSString *)vid title:(NSString *)title hasPPT:(BOOL)hasPPT localPlay:(BOOL)localPlay {
// 视频播放回调,获取到视频资源后调用
// vid:当前播放视频的 vid
// title:当前播放视频的标题
// hasPPT:当前播放视频是否包含文档
// localPlay:播放资源是否为本地缓存,YES 为是,NO 为否
}

- (PLVVodPlaybackMode)currenPlaybackMode {
// 当前播放音视频模式:
// PLVVodPlaybackModeDefault
// PLVVodPlaybackModeVideo
// PLVVodPlaybackModeAudio
}

@end

The response events for the new buttons mentioned in section "8.3.2 Player Skin" can also be set in PLVPPTBaseViewController.m:

- (PLVPPTVideoViewController *)videoController {
    if (!_videoController){
        _videoController = [[PLVPPTVideoViewController alloc] init];
        _videoController.delegate = self;
        
        __weak typeof(self) weakSelf = self;
        _videoController.closeSubscreenButtonActionHandler = ^{
            // 打开/关闭小屏
        };
        _videoController.pptCatalogButtonActionHandler = ^{
            // 打开课件列表
        };
    }
    return _videoController;
}

8.4 PPT Player

The open-source component PolyvOpenSourceModule in the demo provides the PPT player PLVPPTViewController for playing PPT or PDF documents, and supports customizing the document page turning time points in the background to achieve synchronized document and video playback.

8.4.1 PPT Loading

A simple usage example of the PPT player is as follows:

self.pptController = [[PLVPPTViewController alloc] init];
self.pptController.ppt = ppt;

The property ppt is a PLVVodPPT model, representing a document data model. Use the following method of PLVVodPPT to obtain online PPT document data (for offline data retrieval, see 8.7):

// 获取在线数据
+ (void)requestPPTWithVid:(NSString *)vid completion:(void (^)(PLVVodPPT * _Nullable ppt, NSError * _Nullable error))completion;

The code example for PLVPPTBaseViewController.m is as follows:

- (void)getPPTJson {
    [PLVVodPPT requestPPTWithVid:self.vid completion:^(PLVVodPPT * _Nullable ppt, NSError * _Nullable error) {
        if (error == nil && ppt) {
            // 获取 ppt 数据成功
        } else {
            // 获取 ppt 数据失败
        }
    }];
}

8.4.2 PPT Page Turning

The PPT player provides the following two methods for document page turning:

@interface PLVPPTViewController : UIViewController

 /**
 将文档切换到特定播放时间点的特定页
 @param second 当前视频播放时间点,单位:秒
 */
- (void)playAtCurrentSecond:(NSInteger)second;

/**
 将文档切换到特定页
 @param index 文档的第 index 页
 */
- (void)playPPTAtIndex:(NSInteger)index;

@end

In PLVPPTBaseViewController, the method -playAtCurrentSecond: is called in the video playback progress callback to achieve synchronization with video playback. The method -playPPTAtIndex: is called when manually selecting a specific document page to play.

8.4.3 PPT Player Skin

The PPT player PLVPPTViewController provides a simple skin, including a text display "No courseware available" when loading fails, a loading control during loading, and a download progress control when downloading courseware. These skins can be controlled through the following four methods:

@interface PLVPPTViewController (PLVPPTSkin)

/**
 开始加载 ppt
 */
- (void)startLoading;

 /**
 加载 ppt 失败
 */
- (void)loadPPTFail;

/**
 开始下载 ppt
 */
- (void)startDownloading;

/**
 下载 ppt 进度变化
 @param progress ppt 下载进度
 */
- (void)setDownloadProgress:(CGFloat)progress;

@end

When the PPT is successfully loaded/downloaded, i.e., when the PPT property is assigned a value (non-nil), these controls are automatically hidden without needing to call any interface.

8.5 Triple Screen Small Window

The open-source component PolyvOpenSourceModule in the demo provides a custom subclass PLVFloatingView of UIView as the (floating) small window during triple screen playback.

The small window size is fixed, defined by the class method +viewSize:

+ (CGSize)viewSize {
    return CGSizeMake(125, 70);
}

It provides the protocol PLVFloatingViewProtocol and the delegate method -tapAtFloatingView: for responding to window click events:

@protocol PLVFloatingViewProtocol <NSObject>

- (void)tapAtFloatingView:(PLVFloatingView *)floatingView;

@end

The triple screen small window PLVFloatingView supports changing the window position via gesture dragging. To fix the position, simply comment out the following lines of code in the PLVFloatingView.m file:

@implementation PLVFloatingView
  
  - (instancetype)init {
    self = [super init];
    if (self) {
      
      ……
        
      // 如果想固定窗口,注释掉下面这两行代码  
      UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGestureRecognizer:)];
      [self addGestureRecognizer:panGestureRecognizer];
    }
    return self;
}

@end

8.6 Triple Screen Playback Page

The open-source component PolyvOpenSourceModule in the demo provides PLVPPTBaseViewController as the triple screen playback page.

PLVPPTBaseViewController provides the external properties vid, isOffline, and playbackMode:

@interface PLVPPTBaseViewController : UIViewController

/**  
 播放视频的 vid
 */
@property (nonatomic, copy) NSString *vid;

/**
  是否离线播放,默认为 NO
 YES: 从本地获取视频资源,没有网络时只要本地有缓存就可以播放
 NO: 调用接口获取视频资源,没有网络时即使本地有缓存也无法播放
 */
@property (nonatomic, assign) BOOL isOffline;

/**
  播放模式:默认、视频、音频三种
 在线播放时会自动设置播放模式
 离线时需根据本地资源类型手动设置播放模式
 */
@property (nonatomic, assign) PLVVodPlaybackMode playbackMode;

@end

The PLVPPTSimpleDetailController in the demo is a subclass of PLVPPTBaseViewController. The business logic code for triple screen, etc., is encapsulated in the parent class. The code example for video playback using PLVPPTSimpleDetailController is as follows:

PLVPPTSimpleDetailController *vctrl = [[PLVPPTSimpleDetailController alloc] init];
vctrl.vid = vid;
[self.navigationController pushViewController:vctrl animated:YES];

PLVPPTBaseViewController also provides the following empty methods for subclasses to override:

// 获取课件异常时,会执行这个方法,子类需要时可覆写
- (void)getPPTFail;

// ppt 的值更新时,获得 ppt 模型,或者置 nil 会执行这个方法,子类需要时可覆写
- (void)getPPTSuccess;

// 横竖屏切换时会执行这个方法,子类需要时可覆写
- (void)interfaceOrientationDidChange;

The file PLVPPTBaseViewControllerInternal.h defines other properties and methods visible to subclasses.

8.7 Downloader

The downloader PLVVodDownloadManager after SDK 2.6.5 supports bundled downloading of videos and documents in triple screen mode. The calling method remains unchanged:

PLVVodVideo *video;
[[PLVVodDownloadManager sharedManager] downloadVideo:video];

The video model PLVVodVideo adds the properties hasPPT and ppt_link. PLVVodDownloadManager will determine whether to download the PPT document based on this property when downloading the video, and obtain the document's download link from the property ppt_link.

The downloader PLVVodDownloadManager adds the PPT download interface -downloadPPTWithVideo:completion::

/**
 下载PPT 文件
 @param video PLVVodVideo 视频对象
 */
- (void)downloadPPTWithVideo:(PLVVodVideo *)video completion:(void(^)(PLVVodDownloadInfo *info))completion;

You can use this interface to download the PPT corresponding to a specific video individually.

After a successful download, use the method -requestCachePPTWithVid:completion: provided by the class PLVVodPPT to obtain offline PPT document data:

+ (void)requestCachePPTWithVid:(NSString *)vid completion:(void (^)(PLVVodPPT * _Nullable ppt, NSError * _Nullable error))completion;

PLVPPTBaseViewController.m also provides examples of PPT download progress callbacks and download status change callbacks. The example code is as follows:

@implementation PLVPPTBaseViewController (PPT)
  
- (void)downloadPPT {
    PLVVodVideo *video = self.video;
    [[PLVVodDownloadManager sharedManager] downloadPPTWithVideo:video completion:^(PLVVodDownloadInfo *info) {
        [self handlePPTDownload:info];
    }];
}

- (void)handlePPTDownload:(PLVVodDownloadInfo *)info {
    __weak typeof(self) weakSelf = self;
    PLVVodDownloadInfo *downloadInfo = info;
    downloadInfo.progressDidChangeBlock = ^(PLVVodDownloadInfo *info) {
        NSLog(@"下载进度:%f", info.progress);
    };
    
    downloadInfo.stateDidChangeBlock = ^(PLVVodDownloadInfo *info) {
        if (info.state == PLVVodDownloadStateSuccess) {
          NSLog(@"下载成功");
        } else if (info.state == PLVVodDownloadStateFailed) {
          NSLog(@"下载失败");
        }
    };
}

@end
联系客服,在线咨询