iOS AI视频互动课的实现

前言

今年疫情原因,学校好长时间都不开学,本来在线教育就很火,这下更是火山爆发,线上教育APP多如牛毛,成长更是惊人。
成人的教育视频依然是常规视频,没有太大变化,可是主打低龄儿童市场的视频教学,为了让小朋友感兴趣,确是玩出了很多花样,比如 斑马AI课,小火花思维等主打视频互动课,比如 洪恩识字 直接是个游戏。
视频互动课 直接颠覆了我对视频交互的认知,在看到它之前,我接触过的视频交互,也紧紧是 在视频上发个弹幕,抖音点个赞。视频互动课在我们开发者看,就是跳出视频进行一些操作,完成在回到视频。给常人或小朋友们的感觉是 我在和视频中的人物在交互。一般套路是播放一个动画,动画中的人物需要做一些事情,需要小朋友们帮助,小朋友们需要完成一些小游戏,在小游戏中学习了知识,或是播放一段音乐,让小朋友跟着唱跳。这个产品设计真的太棒了。小朋友真的粘性超高,父母也乐意,终于能消停会了,还能学习。每天看一节视频课在加上课后练习的游戏和别的互动也就20分钟至半个小时。对小朋友眼睛损伤并不大。我来看下视频互动课的录制


banmaGIF.gif
IMG_1494.PNG

首先看到 视频下的进度条上有4个 时间点图标,代表着 这4个事件。可见在视频开始时或之前 就已经知道了时间点的位置。而每节课的时间点是不一样的,所以我们设计进度条上的图标,是根据时间点的数据而确定位置的。

接下来 仿着视频互动课 ,自己试着实现

使用的播放器 是ZFPlayer
先创建 节点数据模型

@interface ZBGameModel : NSObject
@property (nonatomic,assign)NSInteger seconds;//游戏时间
@property (nonatomic,assign)NSInteger gameId;//游戏id
@property (nonatomic,assign)NSInteger gameType;//游戏类型 1为游戏  
@end

给模型赋值对应的时间和类型

   ZBGameModel *model1=[[ZBGameModel alloc]init];
    model1.gameId=1001;
    model1.gameType=1;
    model1.seconds=100;
    
    ZBGameModel *model2=[[ZBGameModel alloc]init];
    model2.gameId=1002;
    model2.gameType=1;
    model2.seconds=221;
    
    ZBGameModel *model3=[[ZBGameModel alloc]init];
    model3.gameId=1003;
    model3.gameType=1;
    model3.seconds=303;
    
    ZBGameModel *model4=[[ZBGameModel alloc]init];
    model4.gameId=1004;
    model4.gameType=2;
    model4.seconds=318;

    [self.timeArray addObject:model1];
    [self.timeArray addObject:model2];
    [self.timeArray addObject:model3];
    [self.timeArray addObject:model4];

根据上图我们可以看到 对号标志 代表游戏,最后一个音乐标志代表儿歌时间。可是这个图标,我们怎么算位置坐标呢。
下面就要靠计算了,
(进度条的总长度/视频的总时间)* 对应的时间点 - 图标的宽度的一半
得到的就是 每个图标的位置了

  ///当播放器准备开始播放时候调用
    self.player.playerReadyToPlay = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, NSURL * _Nonnull assetURL) {
         @strongify(self)
        [self.timeArray enumerateObjectsUsingBlock:^(ZBGameModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
            UIImageView *icon=[[UIImageView alloc]init];
            if (model.gameType==1) {
                icon.image=[UIImage imageNamed:@"gift_icon_0"];
            }else{
                icon.image=[UIImage imageNamed:@"douyin"];
            }
            icon.backgroundColor=[UIColor whiteColor];
            [self.controlView.landScapeControlView.slider addSubview:icon];
           [icon mas_makeConstraints:^(MASConstraintMaker *make) {
                make.top.equalTo(@(0));
                make.width.equalTo(@(14));
                make.height.equalTo(@(14));
                //7为宽的一半
                make.left.equalTo(@(model.seconds*(self.controlView.landScapeControlView.slider.frame.size.width/self.playerManager.totalTime)-7));
            }];
        }];
    };
ED11C40C-9B24-4799-9C31-3197AB0F0FA8.png

因为只是 demo,我并没自定义 视频控制层和视频互动课一样,大家应该能看到,图标和原图基本一致
图标指示UI 层面的,那么 到了游戏图标的时间我们怎么能够进入游戏 呢
创建一个 游戏队列类 把我们刚才的 数据传进去

 self.gameQueue=[[ZBGameQueue alloc]init];
 self.gameQueue.delegate=self;
 [self.gameQueue loadGameList:self.timeArray];

里面是这样的,把模型数据存在字典里,以节点时间为key

- (void)loadGameList:(NSArray *)gameList{
    if (gameList.count<=0) {
        return;
    }
   for (int i = 0; i < gameList.count; i ++) {
       ZBGameModel *gameModel = gameList[i];
       [self.cacheDict setObject:gameModel forKey:@(gameModel.seconds).stringValue];
   }
}

在视频时间回调内 游戏时间 和 视频时间进行匹配,找到对应的时间点,证明可以进入游戏了

__block NSInteger tempTime;
    self.player.playerPlayTimeChanged = ^(id<ZFPlayerMediaPlayback>  _Nonnull asset, NSTimeInterval currentTime, NSTimeInterval duration) {
        @strongify(self)
        //因为此回调是0.1秒一次,所以做了此判断,
        tempTime=currentTime;
        if (self.currentTime!=tempTime) {
            NSLog(@"tempTime:%ld",tempTime);
            //游戏列队 和 视频时间对比
            [self.gameQueue startQueueWithCurrentTime:tempTime];
        }
        self.currentTime=tempTime;
    };
- (void)startQueueWithCurrentTime:(NSInteger)currentTime{
    if ([self.cacheDict.allKeys containsObject:@(currentTime).stringValue]) {
        ZBGameModel *gameModel =[self.cacheDict objectForKey:@(currentTime).stringValue];
        if ([self.delegate respondsToSelector:@selector(gameQueueGetGameModel:)]) {
            [self.delegate gameQueueGetGameModel:gameModel];
        }
     }
}

看到这,如果之前看过我写的 历史弹幕绑定视频时间的朋友,应该了解。逻辑都一样。
之后就是 代理触发,我们就可以进入游戏了

#pragma mark - ZBGameQueueDelegate
- (void)gameQueueGetGameModel:(ZBGameModel *)gameModel{
    if (gameModel.gameType==1) { //1为游戏
        [self.playerManager pause];//暂停视频
         NSLog(@"进入游戏");
        GameViewController *gameVC=[[GameViewController alloc]init];
        gameVC.delegate=self;
        UIViewController *vc=[self.controlView.landScapeControlView findeCurrentViewController];
        [vc presentViewController:gameVC animated:YES completion:nil];
    }else{
        //其他不跳转 比如儿歌时间
    }
}

游戏部分,我只是随便写了一点,三个游戏节点,都是一个。一节课 视频里3-4个游戏,加上课后练习的游戏10个 起码有了。一期有10多节课,每个年龄段的课还不一样,游戏也不一样。游戏的量这么大,感觉用原生开发不太可能。
最后在游戏结束时 给一个回调,游戏结束继续播放视频

#pragma mark - GameViewControllerDelegate
- (void)gameComplete{
    [self.playerManager play];
}

经过上面的处理,服务下发的或传进来的任何时间点,任何数量的数据,我们的UI图标 和 事件都能准确的触发

我们来个看下整体效果

banma zb GIF.gif

最后奉上本文Demo
结尾:水平有限,代码也很烂,一直在努力学习中,大家多多包涵。如果你喜欢这个轮子,请给个star,这是对作者最大的鼓励和支持,拜谢!!!假如你有更好的想法或方案请留言!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容