iOS 视频播放器-模块化您的控制层

链式蝉翼
• 阅读 3297

播放器的控制层有很多种, 例如在Cell上播放, 与在单一的视图上, 控制层显示的可能不一样. 有的小伙伴可能会在一个控制层中加上判断去显示不同的UI. 我在这里提供另外一种方法, 就是控制层切换器.

切换器的好处:

  • 模块化控制层
  • 控制层的复用(大家可以把写好的控制层push上来, 我集成到pod中)

图解

下图为SJVideoPlayer默认的控制层:

  • 默认的边缘控制层
  • iOS 视频播放器-模块化您的控制层
  • 默认的剪辑控制层
  • iOS 视频播放器-模块化您的控制层

在上图可以看到, 当点击边缘控制层的剪辑按钮后, 边缘控制层退出, 同时剪辑控制层出现(截屏/剪辑/GIF).

所以切换的思路就是每个控制层, 都默认实现一个入场和一个退出的方法. 在切换时, 通过调用控制层入场(new control layer)还是退出(old control layer)的方法进行切换. 不过, 这个功能需要两个前提条件

前提:

  • 基于SJVideoPlayer
  • 每个控制层需实现退出和进场方法

切换器的功能:

目前切换器的功能如下:

  • 能够 根据标识 添加/删除/切换 控制层
  • 控制层的标识可以自己扩展, 也可以通过相同的标识去替换一个原始存在的控制层
  • iOS 视频播放器-模块化您的控制层

相关类:

相关类分别是切换器(SJControlLayerSwitcher)和数据载体(SJControlLayerCarrier)
我们先预览一下代码, 看开头的的 init方法 就行:

#pragma mark - switcher 
@interface SJVideoPlayer : SJBaseVideoPlayer
/// 1. 控制层切换器
@property (nonatomic, strong, readonly) SJControlLayerSwitcher *switcher; 
// ...
@end
@implementation SJVideoPlayer
- (instancetype)init {
    self = [super init];
    if ( !self ) return nil;
    /// 2. 添加一个控制层
    [self.switcher addControlLayer:self.defaultEdgeCarrier];
    /// 3. 切换到添加的控制层
    [self.switcher switchControlLayerForIdentitfier:SJControlLayer_Edge toVideoPlayer:self];
    return self;
}
// ...
@end

/// 切换器
/// 1. 当前控制层标识
/// 2. 前一个控制层的标识
/// 3. 切换控制层
/// 4. 添加/删除/获取 控制层
#pragma mark - SJControlLayerSwitcher - 切换器
@interface SJControlLayerSwitcher : NSObject
- (instancetype)init;
/// 当前标识(控制层的标识)
@property (nonatomic, readonly) SJControlLayerIdentifier currentIdentifier;  
/// 前一个标识
@property (nonatomic, readonly) SJControlLayerIdentifier previousIdentifier; 

/// 切换控制层
/// 将当前的控制层切换为指定标识的控制层
- (void)switchControlLayerForIdentitfier:(SJControlLayerIdentifier)identifier
                           toVideoPlayer:(__kindof SJBaseVideoPlayer *)videoPlayer;
- (BOOL)switchToPreviousControlLayer; // 切换到之前的控制层

/// 添加一个控制层
- (void)addControlLayer:(SJControlLayerCarrier *)carrier;
/// 删除一个控制层
- (void)deleteControlLayerForIdentifier:(SJControlLayerIdentifier)identifier;
/// 根据标识获取一个控制层
- (nullable SJControlLayerCarrier *)controlLayerForIdentifier:(SJControlLayerIdentifier)identifier;
@end

/// 控制层数据载体
/// 1. 播放器的DataSource
/// 2. 播放器的Delegate
/// 3. 控制层退出执行的block
/// 4. 控制层入场执行的block
#pragma mark - SJControlLayerIdentifier & SJControlLayerCarrier
typedef long SJControlLayerIdentifier;

@interface SJControlLayerCarrier : NSObject
@property (nonatomic, strong, readonly) id <SJVideoPlayerControlLayerDataSource> dataSource;
@property (nonatomic, strong, readonly) id <SJVideoPlayerControlLayerDelegate> delegate;
@property (nonatomic, readonly) SJControlLayerIdentifier identifier;

@property (nonatomic, copy, readonly) void(^exitExeBlock)(SJControlLayerCarrier *carrier);
@property (nonatomic, copy, readonly) void(^restartExeBlock)(SJControlLayerCarrier *carrier);
@end

以上为切换器的源实现, 添加-删除-切换-查询 这些功能.

在init方法中, 我默认添加了一个边缘控制层, 并且通过切换器切换到了该控制层. 我写了一个 Demo在这里:
iOS 视频播放器-模块化您的控制层

尾巴

项目地址: https://github.com/changsanji...

我的邮箱: changsanjiang@gmail.com

如果您有什么建议, 望请联系我!

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
vant Popup弹框使用总结
1、基础用法通过vmodel控制弹出层是否展示<vancellislink@click"showPopup"展示弹出层</vancell<vanpopupvmodel"show"内容</vanpopupexportdefault{data(){
Wesley13 Wesley13
3年前
JS使用控制层方法传递参数
一."ghXiaomiGameBelong.do?methodghXiaomiGameBelongList\_ML&errCode2";跳转至ghXiaomiGameBelongList\_ML页面,并且将errCode2传递至此页面,页面有input框进行接收,<inputtype"hidden"value"${param.err
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Stella981 Stella981
3年前
Spring Boot Mock单元测试学习总结
单元测试的方法有很多种,比如使用Postman、SoapUI等工具测试,当然,这里的测试,主要使用的是基于RESTful风格的SpringMVC的测试,我们可以测试完整的SpringMVC流程,即从URL请求到控制器处理,再到视图渲染都可以测试。下面我主要总结下SpringBoot基于Mock的方式对控制层Controller和服务层Serivce的单元
Wesley13 Wesley13
3年前
1.1Spring Boot 环境配置和常用注解
SpringBoot常用注解:@Service:注解在类上,表示这是一个业务层bean@Controller:注解在类上,表示这是一个控制层bean@Repository:注解在类上,表示这是一个数据访问层bean@Component:注解在类上,表示通用bean,value不写默认就是类名首字母小写@Auto
Stella981 Stella981
3年前
Spring Boot demo系列(二):简单三层架构Web应用
2021.2.24更新1概述这是SpringBoot的第二个Demo,一个只有三层架构的极简Web应用,持久层使用的是MyBatis。2架构一个最简单的SpringBootWeb应用分为三层:Controller层:负责具体业务流程的控制,调用Se
Stella981 Stella981
3年前
Spring 12 种 常用注解!
1.声明bean的注解@Component组件,没有明确的角色@Service在业务逻辑层使用(service层)@Repository在数据访问层使用(dao层)@Controller在展现层使用,控制器的声明(C)2.注入bean的注解@Autowired:由Spring提供@Inj
Easter79 Easter79
3年前
Spring中@Controller、@Repository、@Service、@Component注解的作用详解
Spring中使用在类上的常用注解有@Controller、@Repository、@Service、@Component,下面分别详细介绍一下他们的作用:1、@Controller:用于标注控制层服务。2、@Repository:用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件。3、@Service:用于标注业务逻辑层服务,主要
Stella981 Stella981
3年前
Android上定义播放器控件UniversalVideoView
在Android上播放视频最简单的方法是使用SDK中内置的VideoView,然后加上MediaController来控制视频播放暂停等,但是这样有一个缺点是无法定制自己的控制UI,所以这里提供一个自定义播放控件,它可以设置多种自定义属性(如loading样式,错误视频等),并且很容易在全屏与非全屏之间切换,另外支持AndroidV2.3及以上系统.
Wesley13 Wesley13
3年前
04.视频播放器通用架构实践
04.视频播放器通用架构实践目录介绍01.视频播放器的痛点02.业务需求的目标03.该播放器框架特点04.播放器内核封装05.播放器UI层封装06.如何简单使用07.如何自定义播放器08.该案例的拓展性分享09.关于视频缓存