随着公司业务的发展,公司的播放器功能也越来越复杂,另外播放器作为通用功能,还需要支持不同业务线的播放器的定制,因此想着我们是不是可以借鉴前端开发一些插件化思想,把我们播放器的每个功能都当做一个插件,各个业务根据自己的喜好去定制不同的插件:
- 下载
- 分享
- 字幕
- 弹幕
- 清晰度
- 速率
- ……
对于播放器来说只需要维护通用的播放器的一些状态,比如播放的开始播放,暂停,结束,缓存进度,播放进度等。
因此希望通过下面这个Demo,模拟器了一下如何使用原生的方式模拟一下插件的开发思想。
一.整个代码的结构如下
主要包含CCPlayer
, CCPlayerBuilder
,CCPlayerPlugin
, CCPlayerConfig
这四个主要文件,接下来我们一个个介绍,这几个类分别做了哪些事情,提供了哪些方法?
二. 接下来我们详细介绍一下每个类扮演什么角色
1. CCPlayer
这个是一个通用的管理配置和插件的地方
@class CCPlayerBuilder;
@interface CCPlayer : NSObject
/** 单例 */
+ (id)sharedInstance;
/** 添加构造器 */
- (void)addPlayerBuilder:(CCPlayerBuilder *)builder;
/** 开启插件 */
- (void)startPlugins;
/** 停止插件 */
- (void)stopPlugins;
/** 获取所有插件 */
- (NSMutableSet *)getPlugins;
/** 移除所有插件 */
- (void)removeAllPlugin;
@end
复制代码
2. CCPlayerBuilder
这个一个专门管理插件的地方,同时承接插件的代理回调
@interface CCPlayerBuilder : NSObject
@property (nonatomic, weak) id<CCPlayerPluginListenerDelegate> pluginListener;
/** 获取所有插件 */
- (NSMutableSet *)getPlugins;
/** 移除所有插件 */
- (void)removeAllPlugin;
/** 根据tag获取插件 */
- (CCPlayerPlugin *)getPluginWithTag:(NSString *)tag;
/** 添加插件 */
- (void)addPlugin:(CCPlayerPlugin *)plugin;
/// 移除插件
/// @param tag 插件名称
- (void)removePluginWithTag:(NSString *)tag;
/** 移除插件 */
- (void)removePlugin:(CCPlayerPlugin *)plugin;
/** 是否包含某个插件 */
- (BOOL)isContainPlugin:(CCPlayerPlugin *)plugin;
@end
复制代码
3. CCPlayerPlugin
- 定义插件的生命周期
- 插件的优先级
- 插件的配置
#import <Foundation/Foundation.h>
#import "CCPlayerPluginConfig.h"
NS_ASSUME_NONNULL_BEGIN
/** 设置优先级 */
typedef NS_OPTIONS(NSUInteger, CCPlayerPluginPriority) {
CCPlayerPluginPriorityHigh,
CCPlayerPluginPriorityMiddle,
CCPlayerPluginPriorityLow
};
#pragma mark - CCPlayerPluginListenerDelegate
@protocol CCPlayerPluginProtocol;
// 添加时间监听代理
@protocol CCPlayerPluginListenerDelegate <NSObject>
@optional
- (void)onInit:(id<CCPlayerPluginProtocol>)plugin;
- (void)onStart:(id<CCPlayerPluginProtocol>)plugin;
- (void)onStop:(id<CCPlayerPluginProtocol>)plugin;
- (void)onDestroy:(id<CCPlayerPluginProtocol>)plugin;
/** 插件的优先级 */
- (void)onPriority:(id<CCPlayerPluginProtocol>)plugin;
@end
#pragma mark - CCPlayerPluginProtocol
@protocol CCPlayerPluginProtocol <NSObject>
@required
/** 开始 */
- (void)start;
/** 结束 */
- (void)stop;
/** 销毁 */
- (void)destroy;
/** 添加监听 */
- (void)setupPluginListener:(id<CCPlayerPluginListenerDelegate>)pluginListener;
/** 获取插件tag */
- (NSString *)getTag;
/** 插件的优先级 */
- (CCPlayerPluginPriority)pluginPriority;
@end
#pragma mark - CCPlayerPlugin
@interface CCPlayerPlugin : NSObject <CCPlayerPluginProtocol>
/** 插件配置类 */
@property (nonatomic, strong) CCPlayerPluginConfig *pluginConfig;
@end
复制代码
4. CCPlayerConfig
这个类做一些通用的配置
三、如何写插件?
为了能够让大家更好的理解这几个类是怎么联系的,写了两个简单的插件,下载插件和分享插件
1. 分享插件
- 分享的配置
@interface CCPlayerShareConfig : NSObject
+ (CCPlayerShareConfig *)defaultConfig;
/** 应用id */
@property (nonatomic, copy) NSString *appId;
/** 引用密码 */
@property (nonatomic, copy) NSString *appSecret;
@end
复制代码
- 分享插件
具体的插件的实现,可以下载代码,看细节
@protocol CCPlayerSharePluginDelegate <NSObject>
/** 分享平台 */
- (void)sharePlatform:(NSString *)platform;
- (void)shareError:(NSString *)error;
@end
@interface CCPlayerSharePlugin : CCPlayerPlugin
/** 添加分享平台 */
- (void)addPlatform:(NSArray *)platforms;
@property (nonatomic, assign) id<CCPlayerSharePluginDelegate> delegate;
@property (nonatomic, strong) CCPlayerShareConfig *config;
@end
复制代码
2. 下载插件
- 下载配置
@interface CCPlayerDownloadConfig : CCPlayerPluginConfig
+ (CCPlayerDownloadConfig *)defaultConfig;
/** 下载URL */
@property (nonatomic, copy) NSString *videoUrl;
/** 保存地址 */
@property (nonatomic, copy) NSString *saveFilePath;
@end
复制代码
- 下载插件
@protocol CCPlayerDownloadPluginDelegate<NSObject>
/** 开始下载 */
- (void)startDownLoadWithUrl:(NSString *)url;
/** 下载中 */
- (void)downloadWithProgress:(float)process;
/** 开始完成 */
- (void)finishDownloadLoadWithUrl:(NSString *)url;
@end
@interface CCPlayerDownloadPlugin : CCPlayerPlugin
@property (nonatomic, strong) CCPlayerDownloadConfig *config;
@property (nonatomic, weak) id<CCPlayerDownloadPluginDelegate> delegate;
@end
复制代码
四、如何使用?
#import "ViewController.h"
#import "CCPlayer.h"
#import "CCPlayerBuilder.h"
#import "CCPlayerSharePlugin.h"
#import "CCPlayerDownloadPlugin.h"
@interface ViewController ()<CCPlayerPluginListenerDelegate, CCPlayerSharePluginDelegate, CCPlayerDownloadPluginDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
// 测试插件
CCPlayer *player = [CCPlayer sharedInstance];
CCPlayerBuilder *playerBuilder = [[CCPlayerBuilder alloc] init];
playerBuilder.pluginListener = self; // pluginListener 回调 plugin 的相关事件
CCPlayerSharePlugin *sharePlugin = [[CCPlayerSharePlugin alloc] init];
sharePlugin.delegate = self;
[playerBuilder addPlugin:sharePlugin];
// 配置下载插件
CCPlayerDownloadPlugin *downloadPlugin = [[CCPlayerDownloadPlugin alloc] init];
CCPlayerDownloadConfig *config = [[CCPlayerDownloadConfig alloc] init];
config.videoUrl = @"http://www.baidu.com";
config.saveFilePath = @"/usr/download/video";
downloadPlugin.config = config;
downloadPlugin.delegate = self;
[playerBuilder addPlugin:downloadPlugin];
[player addPlayerBuilder:playerBuilder];
[sharePlugin start];
[downloadPlugin start];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(100 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 移除插件
[playerBuilder removePlugin:downloadPlugin];
NSLog(@"插件%@", [player getPlugins]);
});
NSLog(@"插件个数%@", [player getPlugins]);
NSLog(@"tag获取的插件是%@", [playerBuilder getPluginWithTag:@"downloadPlugin"]);
NSLog(@"是否包含分享插件----%@", @([playerBuilder isContainPlugin:sharePlugin]));
}
#pragma mark - CCPlayerPluginListenerDelegate
- (void)onInit:(id<CCPlayerPluginProtocol>)plugin {
}
- (void)onStart:(id<CCPlayerPluginProtocol>)plugin {
NSLog(@"插件是啥%@", plugin);
}
- (void)onStop:(id<CCPlayerPluginProtocol>)plugin {
}
- (void)onDestroy:(id<CCPlayerPluginProtocol>)plugin {
}
- (void)onPriority:(id<CCPlayerPluginProtocol>)plugin {
}
#pragma mark - CCPlayerSharePluginDelegate
- (void)sharePlatform:(NSString *)platform {
NSLog(@"分享平台---%@", platform);
}
- (void)shareError:(NSString *)error {
NSLog(@"错误信息是---%@", error);
}
#pragma mark - CCPlayerDownloadPluginDelegate
- (void)startDownLoadWithUrl:(NSString *)url {
NSLog(@"开始下载--%@", url);
}
- (void)downloadWithProgress:(float)process {
NSLog(@"下载进度--%@", @(process));
}
- (void)finishDownloadLoadWithUrl:(NSString *)url {
NSLog(@"下载完成--%@", url);
}
@end
复制代码
五、由于代码比较简单,具体实现细节可查看
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END