476 lines
16 KiB
Objective-C
476 lines
16 KiB
Objective-C
//
|
||
// QXGiftPlayer.m
|
||
// QXLive
|
||
//
|
||
// Created by 启星 on 2025/5/8.
|
||
//
|
||
|
||
#import "QXGiftPlayerManager.h"
|
||
#import "QXEffectSvgaView.h"
|
||
#import "QXFileManager.h"
|
||
#import "FMDB.h"
|
||
static NSString *TABLENAME = @"qxGitfPlayTable";
|
||
static NSString *ID = @"id";
|
||
static NSString *PLAY_IMAGE = @"play_image";
|
||
@interface QXGiftPlayerManager()
|
||
@property (nonatomic,strong) FMDatabase *fmdb;
|
||
@property (nonatomic,strong) UIView *bgEffectView;
|
||
// 礼物、坐骑【全屏位置】特效
|
||
@property (nonatomic,strong) QXEffectContentView *fullEffectView;
|
||
|
||
// 坐骑【公屏信息流位置】特效
|
||
@property (nonatomic,strong) QXEffectContentView *chatEffectView;
|
||
|
||
@end
|
||
|
||
@implementation QXGiftPlayerManager
|
||
+ (instancetype)shareManager{
|
||
static QXGiftPlayerManager *manager;
|
||
static dispatch_once_t onceToken;
|
||
dispatch_once(&onceToken, ^{
|
||
manager = [[QXGiftPlayerManager alloc] init];
|
||
// [manager creatDatabase];
|
||
});
|
||
return manager;
|
||
}
|
||
//获得存放数据库文件的沙盒地址
|
||
//- (NSString *)databaseFilePath
|
||
//{
|
||
// NSArray *filePath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||
// NSString *documentPath = [filePath objectAtIndex:0];
|
||
// NSString *dbFilePath = [documentPath stringByAppendingPathComponent:@"qx_gift.db"];
|
||
// return dbFilePath;
|
||
//}
|
||
//
|
||
////创建数据库
|
||
//- (void)creatDatabase
|
||
//{
|
||
// _fmdb = [FMDatabase databaseWithPath:[self databaseFilePath]];
|
||
// //为数据库设置缓存,提高查询效率
|
||
// [_fmdb setShouldCacheStatements:YES];
|
||
// [_fmdb open];
|
||
// NSString *sqlCreateTable = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS '%@' ('%@' INTEGER PRIMARY KEY AUTOINCREMENT, '%@' TEXT)",TABLENAME,ID,PLAY_IMAGE];
|
||
// BOOL res = [_fmdb executeUpdate:sqlCreateTable];
|
||
// NSLog(@"%@",res?@"数据库创建成功":@"数据库创建失败");
|
||
// [_fmdb close];
|
||
//}
|
||
//
|
||
//-(void)insertGiftWithPlayImage:(NSString*)giftImage{
|
||
// if ([_fmdb open]) {
|
||
// NSString *insertSql1= [NSString stringWithFormat:
|
||
// @"INSERT INTO '%@' ('%@') VALUES ('%@');",
|
||
// TABLENAME, PLAY_IMAGE, giftImage];
|
||
// BOOL res = [_fmdb executeUpdate:insertSql1];
|
||
// NSLog(@"%@",res?@"礼物添加成功":@"礼物添加失败");
|
||
// [_fmdb close];
|
||
// }
|
||
//}
|
||
//- (BOOL)deleteRecordWithId:(NSInteger)recordId {
|
||
// if ([_fmdb open]) {
|
||
// NSString *deleteSQL = [NSString stringWithFormat:
|
||
// @"DELETE FROM %@ WHERE id = ('%ld');",
|
||
// TABLENAME, recordId];
|
||
// BOOL success = [_fmdb executeUpdate:deleteSQL];
|
||
// if (!success) {
|
||
// NSLog(@"删除失败: %@", [_fmdb lastErrorMessage]);
|
||
// }else{
|
||
// NSLog(@"删除成功");
|
||
// }
|
||
// [_fmdb close];
|
||
// return success;
|
||
// }
|
||
// return NO;
|
||
//}
|
||
//
|
||
//-(BOOL)deleFirstImage{
|
||
// if ([_fmdb open]) {
|
||
// NSString *querySQL= [NSString stringWithFormat:
|
||
// @"SELECT id FROM '%@' ORDER BY id ASC LIMIT 1",
|
||
// TABLENAME];
|
||
// FMResultSet *resultSet = [_fmdb executeQuery:querySQL];
|
||
// [_fmdb close];
|
||
// if ([resultSet next]) {
|
||
// NSInteger recordId = [resultSet intForColumn:@"id"];
|
||
// return [self deleteRecordWithId:recordId];
|
||
// }
|
||
// }
|
||
// return NO;
|
||
//}
|
||
//
|
||
//-(NSString*)readFirstImage{
|
||
// if ([_fmdb open]) {
|
||
// NSString *querySQL= [NSString stringWithFormat:
|
||
// @"SELECT id FROM '%@' ORDER BY id ASC LIMIT 1",
|
||
// TABLENAME];
|
||
// FMResultSet *resultSet = [_fmdb executeQuery:querySQL];
|
||
// [_fmdb close];
|
||
// if ([resultSet next]) {
|
||
// NSString *playImage = [resultSet stringForColumn:PLAY_IMAGE];
|
||
// return playImage;
|
||
// }
|
||
// }
|
||
// return nil;
|
||
//}
|
||
|
||
- (UIView *)defaultBgEffectView {
|
||
return self.bgEffectView;
|
||
}
|
||
|
||
/// 礼物、坐骑【全屏位置】特效
|
||
- (QXEffectContentView *)defaultFullEffectView {
|
||
return self.fullEffectView;
|
||
}
|
||
|
||
/// 坐骑【公屏信息流位置】特效
|
||
- (QXEffectContentView *)defaultChatEffectView {
|
||
return self.chatEffectView;
|
||
}
|
||
|
||
- (void)displayFullEffectView:(NSString *)gift {
|
||
// [self insertGiftWithPlayImage:gift];
|
||
[self.fullEffectView displayEffectView:gift];
|
||
}
|
||
- (void)displayFullEffectViewWithMorePlayImages:(NSArray *)playImages{
|
||
[self.fullEffectView displayEffectViewWithMorePlayImages:playImages];
|
||
}
|
||
|
||
- (void)displayChatEffectView:(NSString *)gift {
|
||
[self.chatEffectView displayEffectView:gift];
|
||
}
|
||
/// 关闭打开动效
|
||
- (void)openOrCloseEffectViewWith:(BOOL)isShow {
|
||
[self.fullEffectView openOrCloseEffectViewWith:isShow];
|
||
[self.chatEffectView openOrCloseEffectViewWith:isShow];
|
||
}
|
||
|
||
|
||
/// 销毁
|
||
- (void)destroyEffectSvga {
|
||
[self.fullEffectView destroyEffectView];
|
||
[self.chatEffectView destroyEffectView];
|
||
|
||
[self.fullEffectView removeFromSuperview];
|
||
[self.chatEffectView removeFromSuperview];
|
||
[self.bgEffectView removeFromSuperview];
|
||
|
||
_fullEffectView = nil;
|
||
_chatEffectView = nil;
|
||
_bgEffectView = nil;
|
||
}
|
||
-(void)stopPlay{
|
||
[self.fullEffectView stopPlay];
|
||
[self.chatEffectView stopPlay];
|
||
}
|
||
-(void)startPlay{
|
||
[self.fullEffectView startPlay];
|
||
[self.chatEffectView startPlay];
|
||
}
|
||
- (UIView *)bgEffectView {
|
||
if (!_bgEffectView) {
|
||
_bgEffectView = [[UIView alloc] init];
|
||
_bgEffectView.userInteractionEnabled = NO;
|
||
|
||
[_bgEffectView addSubview:self.fullEffectView];
|
||
[_bgEffectView addSubview:self.chatEffectView];
|
||
}
|
||
return _bgEffectView;
|
||
}
|
||
- (QXEffectContentView *)fullEffectView {
|
||
if (!_fullEffectView) {
|
||
_fullEffectView = [[QXEffectContentView alloc] initWithFrame:CGRectZero];
|
||
_fullEffectView.queue = dispatch_queue_create("qx_room_full_svga_message.com", NULL);
|
||
}
|
||
return _fullEffectView;
|
||
}
|
||
|
||
|
||
- (QXEffectContentView *)chatEffectView {
|
||
if (!_chatEffectView) {
|
||
_chatEffectView = [[QXEffectContentView alloc] initWithFrame:CGRectZero];
|
||
[_chatEffectView.playerMp4View mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||
// make.centerX.centerY.equalTo(_chatEffectView);
|
||
// make.width.mas_equalTo(ScaleWidth(375));
|
||
// make.height.mas_equalTo(ScaleWidth(375));
|
||
make.edges.equalTo(_chatEffectView);
|
||
}];
|
||
_chatEffectView.queue = dispatch_queue_create("qx_room_chat_svga_message.com", NULL);
|
||
}
|
||
return _chatEffectView;
|
||
}
|
||
|
||
@end
|
||
|
||
@interface QXEffectContentView ()<HWDMP4PlayDelegate>
|
||
@property (nonatomic,strong) QXEffectSvgaView *svagView;
|
||
@property (nonatomic,strong) QXGiftModel *playModel;
|
||
|
||
@property (nonatomic, assign) BOOL isLoadEffect; ///< 是否正在加载
|
||
@property (nonatomic, strong) NSRecursiveLock *lock;
|
||
@property (nonatomic, strong) NSMutableArray *giftArray;
|
||
@end
|
||
|
||
@implementation QXEffectContentView
|
||
|
||
- (instancetype)initWithFrame:(CGRect)frame {
|
||
self = [super initWithFrame:frame];
|
||
if (self) {
|
||
self.userInteractionEnabled = NO;
|
||
self.isLoadEffect = NO;
|
||
[self addSubview:self.svagView];
|
||
[self addSubview:self.playerMp4View];
|
||
|
||
[self.svagView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.edges.equalTo(self);
|
||
}];
|
||
[self.playerMp4View mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.edges.equalTo(self);
|
||
}];
|
||
}
|
||
return self;
|
||
}
|
||
/// 礼物特效进来 gift为礼物实体类
|
||
- (void)displayEffectView:(NSString *)play_image {
|
||
dispatch_async(self.queue, ^{
|
||
/// 如果play_image不存在return
|
||
if (![play_image isExist]) {
|
||
return;
|
||
}
|
||
/// 将play_image链接转为小写
|
||
NSString *pathExtension = [play_image pathExtension].lowercaseString;
|
||
/// 判定礼物的后缀是否为svga或者mp4如果非这两种 则return
|
||
if (!([pathExtension isEqualToString:@"svga"] || [pathExtension isEqualToString:@"mp4"])) {
|
||
return;
|
||
}
|
||
/// 锁住list
|
||
[self.lock lock];
|
||
/// 添加礼物进list
|
||
[self.giftArray addObject:play_image];
|
||
NSLog(@"当前礼物有---%ld个",self.giftArray.count);
|
||
/// 解锁
|
||
[self.lock unlock];
|
||
|
||
/// 如果没有在加载则开始加载
|
||
if (self.isLoadEffect == NO) {
|
||
/// 更改加载状态标记
|
||
self.isLoadEffect = YES;
|
||
[self loadStartSVGAPlayer];
|
||
}
|
||
});
|
||
}
|
||
/// 礼物特效进来 gift为礼物实体类
|
||
- (void)displayEffectViewWithMorePlayImages:(NSArray *)playImages {
|
||
dispatch_async(self.queue, ^{
|
||
/// 如果play_image不存在return
|
||
if (playImages.count == 0) {
|
||
return;
|
||
}
|
||
/// 锁住list
|
||
[self.lock lock];
|
||
/// 添加礼物进list
|
||
[self.giftArray addObjectsFromArray:playImages];
|
||
NSLog(@"当前礼物有---%ld个",self.giftArray.count);
|
||
/// 解锁
|
||
[self.lock unlock];
|
||
|
||
/// 如果没有在加载则开始加载
|
||
if (self.isLoadEffect == NO) {
|
||
/// 更改加载状态标记
|
||
self.isLoadEffect = YES;
|
||
[self loadStartSVGAPlayer];
|
||
}
|
||
});
|
||
}
|
||
-(void)previewEffectWith:(NSString *)play_image{
|
||
self.isOnece = YES;
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
if ([play_image hasSuffix:@"mp4"]) {
|
||
__weak typeof(self)weakSelf = self;
|
||
/// mp4格式下载播放
|
||
[[QXRequset shareInstance] downloadVideoPlayerWithUrl:play_image completion:^(BOOL result, NSString * _Nonnull fileName) {
|
||
NSString *videoPath = [QXFileManager getGiftVideoPath:fileName];
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
weakSelf.playerMp4View.hidden = NO;
|
||
weakSelf.svagView.hidden = YES;
|
||
});
|
||
[weakSelf.playerMp4View stopHWDMP4];
|
||
[weakSelf.playerMp4View playHWDMP4:videoPath delegate:self];
|
||
}];
|
||
}else if ([play_image hasSuffix:@"svg"] || [play_image hasSuffix:@"svga"]) {
|
||
__weak typeof(self)weakSelf = self;
|
||
/// svga下载播放
|
||
[[QXRequset shareInstance] downloadVideoPlayerWithUrl:play_image completion:^(BOOL result, NSString * _Nonnull fileName) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
weakSelf.playerMp4View.hidden = YES;
|
||
weakSelf.svagView.hidden = NO;
|
||
});
|
||
NSString *filePath = [QXFileManager getGiftVideoPath:fileName];
|
||
[weakSelf.svagView loadSVGAPlayerWith:filePath];
|
||
}];
|
||
}
|
||
});
|
||
}
|
||
|
||
- (void)openOrCloseEffectViewWith:(BOOL)isShow {
|
||
_isShow = isShow;
|
||
[self removeSvgaQueueData];
|
||
|
||
[self.svagView stopEffectSvgaPlay];
|
||
// [self.playerView stop];
|
||
[self.playerMp4View stopHWDMP4];
|
||
// [self.alphaVideoView stop];
|
||
self.playerMp4View.hidden = YES;
|
||
[self setHidden:!isShow];
|
||
}
|
||
-(void)stopPlay{
|
||
// [self removeSvgaQueueData];
|
||
self.isLoadEffect = NO;
|
||
[self.svagView stopEffectSvgaPlay];
|
||
// [self.playerView stop];
|
||
[self.playerMp4View stopHWDMP4];
|
||
// [self.alphaVideoView stop];
|
||
self.playerMp4View.hidden = YES;
|
||
self.svagView.hidden = YES;
|
||
}
|
||
|
||
-(void)startPlay{
|
||
[self loadStartSVGAPlayer];
|
||
}
|
||
-(void)viewDidFinishPlayMP4:(NSInteger)totalFrameCount view:(VAPView *)container{
|
||
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
self.playerMp4View.hidden = YES;
|
||
});
|
||
if (self.isOnece) {
|
||
return;
|
||
}
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[self loadStartSVGAPlayer];
|
||
});
|
||
}
|
||
-(void)viewDidFailPlayMP4:(NSError *)error{
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
self.playerMp4View.hidden = YES;
|
||
});
|
||
if (self.isOnece) {
|
||
return;
|
||
}
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[self loadStartSVGAPlayer];
|
||
});
|
||
}
|
||
- (void)loadStartSVGAPlayer {
|
||
if (!_isShow) {
|
||
/// isshow 为是否开启特效 如果未开启则return
|
||
return;
|
||
}
|
||
NSString *play_image = nil;
|
||
/// list加锁
|
||
[self.lock lock];
|
||
/// 如果list长度大于0
|
||
if (self.giftArray.count > 0) {
|
||
/// gift的实体类则赋值,取list中的第一个数据
|
||
play_image = self.giftArray.firstObject;
|
||
/// 移除list的第一条数据
|
||
[self.giftArray removeObjectAtIndex:0];
|
||
self.isLoadEffect = YES;
|
||
}else {
|
||
self.isLoadEffect = NO;
|
||
}
|
||
/// 解锁
|
||
[self.lock unlock];
|
||
if (self.isLoadEffect && [play_image isExist]) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
if ([play_image hasSuffix:@"mp4"]) {
|
||
__weak typeof(self)weakSelf = self;
|
||
/// mp4格式下载播放
|
||
[[QXRequset shareInstance] downloadVideoPlayerWithUrl:play_image completion:^(BOOL result, NSString * _Nonnull fileName) {
|
||
NSString *videoPath = [QXFileManager getGiftVideoPath:fileName];
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
weakSelf.playerMp4View.hidden = NO;
|
||
weakSelf.svagView.hidden = YES;
|
||
});
|
||
[weakSelf.playerMp4View stopHWDMP4];
|
||
[weakSelf.playerMp4View playHWDMP4:videoPath delegate:self];
|
||
}];
|
||
}else if ([play_image hasSuffix:@"svg"] || [play_image hasSuffix:@"svga"]) {
|
||
__weak typeof(self)weakSelf = self;
|
||
/// svga下载播放
|
||
[[QXRequset shareInstance] downloadVideoPlayerWithUrl:play_image completion:^(BOOL result, NSString * _Nonnull fileName) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
weakSelf.playerMp4View.hidden = YES;
|
||
weakSelf.svagView.hidden = NO;
|
||
});
|
||
NSString *filePath = [QXFileManager getGiftVideoPath:fileName];
|
||
[weakSelf.svagView loadSVGAPlayerWith:filePath];
|
||
}];
|
||
}else {
|
||
[self.lock lock];
|
||
self.isLoadEffect = NO;
|
||
[self.lock unlock];
|
||
[self loadStartSVGAPlayer];
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
- (void)loadEndSvgaPlayer {
|
||
dispatch_async(self.queue, ^{
|
||
[self loadStartSVGAPlayer];
|
||
});
|
||
}
|
||
- (void)destroyEffectView {
|
||
[self removeSvgaQueueData];
|
||
|
||
[self.svagView destroySvga];
|
||
// [self.playerView destroyPlayer];
|
||
[self.playerMp4View stopHWDMP4];
|
||
|
||
[self.svagView removeFromSuperview];
|
||
[self.playerMp4View removeFromSuperview];
|
||
|
||
_svagView = nil;
|
||
// _playerView = nil;
|
||
_playModel = nil;
|
||
_playerMp4View = nil;
|
||
// _alphaVideoView = nil;
|
||
}
|
||
- (void)removeSvgaQueueData {
|
||
[self.lock lock];
|
||
[self.giftArray removeAllObjects];
|
||
self.isLoadEffect = NO;
|
||
[self.lock unlock];
|
||
}
|
||
-(NSMutableArray *)giftArray{
|
||
if (!_giftArray) {
|
||
_giftArray = [NSMutableArray array];
|
||
}
|
||
return _giftArray;
|
||
}
|
||
|
||
- (QXEffectSvgaView *)svagView {
|
||
if (!_svagView) {
|
||
_svagView = [[QXEffectSvgaView alloc] initWithFrame:CGRectZero isAutoPlay:YES];
|
||
__weak typeof(self)weakSelf = self;
|
||
_svagView.didFinishedDisplay = ^(QXEffectSvgaView * _Nonnull svgaView) {
|
||
[svgaView destroySvga];
|
||
if (weakSelf.isOnece) {
|
||
return;
|
||
}
|
||
[weakSelf loadEndSvgaPlayer];
|
||
};
|
||
}
|
||
return _svagView;
|
||
}
|
||
-(VAPView *)playerMp4View{
|
||
if (!_playerMp4View) {
|
||
_playerMp4View = [[VAPView alloc] initWithFrame:CGRectZero];
|
||
_playerMp4View.hwd_enterBackgroundOP = HWDMP4EBOperationTypeStop;
|
||
_playerMp4View.contentMode = UIViewContentModeScaleAspectFit;
|
||
_playerMp4View.userInteractionEnabled = NO;
|
||
_playerMp4View.backgroundColor = [UIColor clearColor];
|
||
// _playerMp4View.hwd_Delegate = self;
|
||
}
|
||
return _playerMp4View;
|
||
}
|
||
@end
|