TV 分享
TV 主要围绕
数字键切台(数字键扫台)
、上下键切台
、TV键切源功能
、频道列表
、频道锁
展开切台过程中会发送一些事件通知上来 ,例如
source.signal.change
(是否有信号通知)、tuner.channel.direct.set.finished
(数字键切台成功到通知)
TV下有哪些特定的源?
每个应用下都有自己独立的源,例如 Usb
的源是8、VGA
的源是13
所以TV一样有自己的 Atenna(天线)、Cable(有线)、Satellite(卫星) 源,后面会用 S、T、C 简称
Atenna:18、20、6
Cable:19、21、7
Satellite: 5
注意:还有一个 源为0 代表 当前是 ATv
切源问题
目前切源主要分为 1、主动切源(source.weitch)。2、底层切源(realrc.watchTV、NVT切源),会有对应 NUI_EVENT_UPDATE_UI_SOURCE
事件通告
目前有哪些入口可以进入到Tv?
1、如果当前不在 Tv 模式下,按 TV键
都能进入到 Tv 模式,会切到上次播放到Tv源(底层切源)(接口:realrc.watchTV)
2、按
setting键移到
Watch Tv下有三个 S-T-C 可以选择进入到 Tv (用户主动切源)
3、按 左键 移到source ,会切到系统中上一个源,如果上一个源是Tv源则切到Tv ,如果是
Usb则切到
Usb` (底层切源)(接口:source.getLastSource –> realrc.watchTV)
4、底层切源,其他源进入APP;在APP中退出,不是UI/中间件调用NUI接口退出。
切台的方式有哪些?
- 上下键切台,ch+\ch- 切台,
- 频道列表切台
- 串口切台
- 码流切台
- 数字键切台
数字键切台不同地区差异
中美数字键切台搜台:
中美实际中可能存在ATV频道5,DTV频道5,Radio频道5,在频道列表里均显示为5。
(1)数字键加点(例如输入5.),如果当前有对应的DTV(虽然Radio也属于DTV的一种,但不切Raido频道),那么就直接切换过去。没有的话,会去搜索对应DTV频道号对应频点的台,搜到了就保存且切换过去,没有就不切换。
(2)数字键不加点(例如输入5),如果有对应的ATV就直接切换过去。如果没有对应的ATV,也会去搜索对应频道号对应频点是否有台,搜到了就保存且切换过去,没有就不切换。
因为中美Cable只支持ATV,因此在Cable信源下,输入的频道号只支持整数。Antenna信源下既有DTV又有ATV,跳DTV必须输入点号,例如10.跳DTV10频道
其他地区切台
除中美外的DVB只支持整数切台,且不支持搜台。其他地区整数和小数切台(例如5、5.1、5.)和搜台。
1.切源优化
当初在Tv页的时候会处理一些外部传入到Tv页源到参数,让Tv页做切源,这样会造成黑屏时间会太久
如何解决频繁黑屏问题?
由于频繁出现黑屏现象,于是在
切Tv源
的时候 会等到Tv接口真正到切成功后才能进入到Tv页。
TV页只处理自己的内部逻辑。要等
source.switch
返回reponse
才算正真正的切源成功 ,source.switch.start
只是底层开始切源的一个通知,还不是切源成功。如果不等source.switch
的reponse
返回在到TV页 会造成 取一些数据,会取到上一个源到数据,这样打开频道列表到数据,option的数据会造成错乱,(当然在取频道列表时,接口有判断如果当前源美誉跟listTye没有对应数据是没有的。
如何处理TV键?
用TV键从非Tv切源的时候是根据 realrc.watchTV
这个接口 来做切源,这个接口底层做好配置,能帮我们切到上一个TV源,一样要等这个接口的 reponse
才能到Tv页,因为只要开做切源到动作,都会有 source.switch.start
通知。
如果当前是Tv源则会调出 selectChannelList 窗口 (如下图) 选择 Atenna 、 Cable和Satellite ,如果选择当前源会先判断当前源是有安装,有的话不做操作,没有的话,会做切源动作。如果非当前源则调用 source.switch
。进入到 Setting 页面 按Tv键等于按 EXIT 退出 Setting 页。
打开 selectChannelList
窗口 会默认选择当前源的那项,当前源会从进入到Tv后就开始保存当前源,每切换一次TV源都会更新当前源。(也就是调用 epgControlInit
方法)
2.接口优化
当初进入到Tv源到时候要调用各种接口,后面根中间件他们讨论,把源相关的和当前源是否有安装,以及当前台的信息,这样能减少Rpc请求,也可以提高进入到Tv页后到响应速度。
如何对TV节目进行状态管理?
- 对当前源进行缓存 (在切源对时候在 事件控制器缓存当前源)
- 对当前节目信息(chahnelInfo)缓存 (放在vuex)
- 对当前的节目类型(listType)缓存 (vuex)(比如 Fav1 skipChannels)
1 | ...mapGetters([ |
因为在TV页经常要用到 chahnelInfo 和 listType ,避免重复调用,所以在更改这两个的地方要统一更新他们的值,
切台优化
主要是针对快切优化,避免调用不必要对接口造成切台卡顿,
上下键切台主要走 channelList 这个类,它负责频道的增删改查,以及对频道缓存。
整体的流程图如下
- 以及一些事件要重新获取频道列表(比如重新扫台,或者码流机切换码流、skip or delete等) ,
skip or delete是否可以不更新频道列表通过标志位?
Code Better
- 主要是对弹窗显示进行优化,弹窗显示对优先级放在 computed 处理
1 | isPopDataShow() { |
为什么要这样处理弹窗显示放在 computed 处理?
1、因为调用接口时,或者底层有新的通知都要去改变弹窗显示值,然后这些弹窗值又互相依赖,所以统一放在 computed 处理再好不过了。
2、如果出现弹窗值显示出现问题,直接找这个变量里的依赖值,能够快速定位到问题所在。
3、在代码层面上,能够更简洁明了,弹窗到相互依赖性,方便其他人介入维护,避免有其他条件加入时造成其他问题。
2. 请求接口尽量用 Promise 的形式
为什么选择 promise?
- 扁平化是Promise为我们呈现的一个非常凸显的理念。
- 批量异步操作 ,可以保证字三个请求都完成下再做其他操作,
- Promise也很好地解决了回调地狱的问题,
- 这样可以让函数具有链行,让代码看起来更舒服和可读性。
可以调用封装好的onRequestByPromise
方法
1 | let promise = new Promise(fn_a) |
频道列表优化
频道列表主要的功能有 Add Favorites、Remove Fav、Clear Fav、Copy Channel、Move to 、Add Skip、 recover、Select Channel Range、Reorder Channels、Swap Channels、Rename CHannel 、Delete Channel、 每一个功能都有对应的自己四色键。
还有Quick Jump 、左右键翻页,左右键切 listType、searchChannels
- 进入到频道列表要对应到找到当前节目信息到位置
1 | this.startIndex = this.getNowChannelInfo.searchIndex - 7 > 0 ? this.getNowChannelInfo.searchIndex - 7 : 1 |
因为ui一页要展示 8 个,如果大于等于7个时高亮到位置要在保持在蒂7个位子,所以要提前取前面的7个。
更新四色键主要根根据
fetchColorKey(chInfo)
方法 主要根据listType来显示 四色键到类型频道列表做完一些操作 主要根据
backLocalChannelFocus
回到当前焦点 没有的话会到顶部backFirstPageList
回到顶部方法按上下键找到对应的焦点 ,包括上下翻页时焦点,在快速按上下键时,会在请求新的channelList 做个 isWaitBackData(假死的操作)判断
等数据返回了才能继续到下一个焦点,这也是当初经常出现失焦到问题所在。
在第二个和第个焦点位置转角时会取对应的数据(在数组第15个位置取数据时要包括上面的6个数据,假设最开始请求是1开始,那么下次请求要从10开始,因为下次新的数据要有旧的数据后6个 )。因为目前的数据没有做缓存,都是单页16个覆盖,所以必然会造成数据重复请求,这也是后续优化的点,怎么把当前的已经请求过的频道数据缓存起来,避免重复请求?
- 如何把提前加载的数据负值给旧的列表显示的数据的时候,也就是焦点再数组里的 第二个,和 倒二个计算 ,因为页面里的最后一个或者第一个这时要有新的数据。
整个列表的移动靠transform: 'translateY(-' + translateUl * 0.62 + 'rem)'
,来控制数据的上下移动
Quick Jump的逻辑跟我们刚打开频道列表的交互是一样的,都要去计算请求的位置(目前quick jump 的请求开始位置是中间件返回的,当然也可以有我们自己计算得出,根据当前跳转的节目的位置去计算)
add Fav 目前的做法是添加完后重新获取当前的列表,(这里可以做的优化可以自己模拟当前是有Fav1、或者fav2)
add Skip 、Delete 目前的做法是add 完之后会重新以当前节目的位置重新获取列表,如果是当前台被skipped 后焦点会回到顶部。(此时要新TV缓存的频道列表里的数据,因为这时 中间件的获取节目列表的searchIndex发生变更,不更新的话会造成获取节目列表数据错乱)
这个isSkiped 和 deleted 的 标志位是否可以在节目列表里体现,而不是在数据库里删除这个数据也是后续要考虑到的事情,显不显示,和能不能切到当前台由我们前端控制是否可行?
左右键翻页主要根据
channelPageSwitch
方法
左右件翻页,主要根据当前焦点在数组中的位置,翻页时是否需要请求新的数据,然后焦点要落在当前视图上的位置
总结
在项目里 我们尽量用常用的组件通信方法
少用 $parent 或者 $children 这样的方式去去数据,让我们在项目里的的数据保持单一性
1 |
|
vuex的正确使用
vuex 里不要用这 this.$store.state
这样的方式去取值或者负值,这样会照成对当前的数据的可控性。
要取值就放到 computed
要设置值就放到 methods
1 | ...mapMutations(['SET_LIST_TYPE', 'SET_NOW_CHANNEL_INFO']), |
很多时候我们都是偷懒,不想去多写两行代码。
bus事件挂载里一定要在组件销毁时卸载它,否则会造成内存泄漏,最后面会卡死
- 后面会写个插件当组件挂载了某个bus事件,在组件销毁时自动卸载 这个bus事件。
三个月的过程
- 本文作者: Littleki
- 本文链接: https:/littleki.gitee.io/2020/08/12/分享会/SCBC-TV-SHARE/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!