OTT开发总结 2.0版本

发布于 2022-05-07  323 次阅读


OTT开发总结

插件使用

npm install vue-awesome-mui

npm i vue-tv-focusable

聚焦插件

常用指令

this.$tv.requestFocus(Element,bool); // Element;
必填 bool非必填。默认为true指定移动到某个聚焦节点,获取节点Element可以用refs或者 e.target

 this.$tv.formAutofocus=false;// 不可以输入
控制选中的表单是否可以输入,默认为true

this.$tv.findFocusType  = 0;
聚焦查找方式,1是就近查找,0是直线查找

@up @down @left @right @onFocus @onBlur @longPress @click
监控按键,其中click同事可对应pc端的点击事件

$tv.resetFocusClassName()   重置 focusClassName   
$tv.resetFindFocusType()    重置 findFocusType    
$tv.resetKEYS()  重置 KEYS
....
$tv.reset() 重置所有

初始配置
 // 初始化配置
    // 全局配置可在mian.js中,也可以放在APP.vue中
  const vm = new Vue();
  // 1.init初始化(init的所有配置项可以在最后面的表格中查看)
  vm.$tv.init({
    focusClassName: "on-focus", // 聚焦元素的className (默认focus)
     KEYS: {
      KEY_LEFT: [37, 21], 
      KEY_UP: [38, 19], 
      KEY_RIGHT: [39, 22], 
      KEY_DOWN: [40, 20],
      KEY_ENTER: [40, 20]
     }, // 自定义键值
     longPressTime: 800, // 长按响应时间(单位:毫秒),默认500ms
     distanceToCenter: false // 是焦点始终在可是范围的中间部分, 默认false
  });

// 2.独立配置初始化
  vm.$tv.KEYS=  {
      KEY_LEFT: [37, 21], 
      KEY_UP: [38, 19], 
      KEY_RIGHT: [39, 22], 
      KEY_DOWN: [40, 20],
      KEY_ENTER: [40, 20]
   };  
   vm.$tv.longPressTime= 800;  //延迟事件为800毫秒

//3.聚焦滑动效果
    //滚动时间,默认200
    // this.$tv.smoothTime = 300;
    this.$tv.smoothTime = 0;//设置为0的话就是不要动画
    //动画流畅度smoothTime(数值越小动画越流畅,
    //但是越耗性能)默认是20,
    //当smoothTime设置为40时,spacingTime=20和spacingTime=1的效果是不一样的
    this.$tv.spacingTime = 40;

//4.限制滚动区域(图一)
    //一般在弹窗或者横向移动图(如:选集)的时候可以用到,一般都是三个属性连用
      //只有upbox里面的内容可以聚焦
                  this.$tv.limitingEl = document.querySelector(".upbox");
      //限制页面的滚动的盒子
                  this.$tv.scrollEl = this.$tv.getElementByPath(
                    '//div[@class = "upbox"]'
                  );
     //强制聚焦到某个内容(当前弹窗中的可聚焦内容)
                  this.$tv.requestFocus(this.$refs.update);
                }, 600);
  //值得注意的是,当聚焦弹窗关闭之后,或者需要切换页面的时候,需要重置limitingEl和scrollEl,否则将会出现无法聚焦和无法滚动等bug
    //重制
      this.$tv.resetScrollEl();
      this.$tv.limitingEl = null;//或者    this.$tv.resetLimitingEl();

1651905417303

​ ( 图1 )

//5、滚动到边界自动移动的距离(图2)这里在做横向滚动框(如选集)和做横向页面(如搜索页)的时候会用到
this.$tv.offsetDistance = 50 // 到达边缘的时候距离边缘50像素
this.$tv.offsetDistance = 250 // 到达边缘的时候距离边缘250像素
//修改后记得在失焦或者离开页面的时候重置,默认是50
this.$tv.resetOffsetDistance();

在这里插入图片描述

img(图2)

init所有可配置项

初始化配置init

init(…)

name 描述 默认值 是否必须
focusableClassName 可聚焦的classname,(设置了focusable的时候不需要设置此项) 空字符串 no
focusClassName 指定焦点元素类名。默认为“焦点” “focus” focus no
initDis 差值 20 no
findFocusType 移动类型,1:就近查找 0:直线 查找 1 no
KEYS 上下左右的键值 { KEY_LEFT: [37, 21], KEY_UP: [38, 19], KEY_RIGHT: [39, 22], KEY_DOWN: [40, 20], KEY_ENTER:[13, 23] } no
offsetDistance 边缘距离 50 no
longPressTime 长按响应时间 500 no
distanceToCenter 焦点是否在滚动区域保持剧中显示 false no
limitingEl 整个界面,只有limitingEl内的焦点可以聚焦 null no
formAutofocus 表单控件是否可以输入或者编辑 true

技术难点、踩坑记录

1.监控安卓返回键

1、安装 npm install vue-awesome-mui

2、src>main.js应用

import Mui from "vue-awesome-mui";
Vue.use(Mui);

3、实现返回跳转,还在改善,有可能返回键关闭弹窗的逻辑,暂未与考虑

src>router>index.js

注意:返回键是安卓调试专有,在电脑端调试会报错,所以在电脑上调试时候需要把返回键监控注释掉

//导航守卫+监听返回键
router.beforeEach((to, from, next) => {
  var quit = false; //是否退出
  mui.back = function () {
    //按下物理返回键
    if (!quit) {
      // 如果是退出
      if (to.name == "Home" || to.name == "About") {
        // 如果是主页
        mui.toast("再按一次退出应用"); //两秒之内再按一次退出app
        quit = true;
        setTimeout(function () {
          quit = false;
        }, 2000);
      } else {
        //不是主页
        if (to.matched[0].instances.default.showmask) {
          to.matched[0].instances.default.showmask = false;
        } else {
          history.go(-1); // 返回上一页
        }
      }
    } else {
      plus.runtime.quit(); //退出app
    }
  };
  next();
});

2.监控上下左右、聚焦、确认等等,

安装npm i vue-tv-focusable

插件网站

https://slailcp.github.io/?type=vue-tv-focusable#%E7%9B%91%E5%90%AC%E8%BF%94%E5%9B%9E%E9%94%AE%E9%97%AE%E9%A2%98

https://blog.csdn.net/sllailcp/article/details/109044265

比较详细的插件使用地址

https://slailcp.github.io/?type=vue-tv-focusable

基础使用

在main.js中添加

/*+++++++++添加下面两行+++++++++*/
import focusable from "vue-tv-focusable";
Vue.use(focusable);
/*+++++++++添加结束+++++++++*/

聚焦简介

设置聚焦盒子

<div v-focusable>可获取焦点的元素</div>
<div>不可获取焦点的元素</div>
//当盒子选中聚焦时候,会自动加上一个focus类的
<div v-focusable></div> →  <div v-focusable class="focus"></div>

.focus默认格式,当然你也可以自己改

.focus {
    transform: scale(1.1);
    border: 2px solid red;
    box-shadow: 0 0 20px red;
}

取消当前盒子的聚焦

   e.target.removeAttribute("focused"); //去除当前选中的节点
 e.target.removeClass("focus");

3.关于TV-app的分辨率问题

电视的分辨率是1280720的话,电视浏览网页的分辨率则是960 540,目前我测试过两种智能电视都是这样的!!所以导致根本显示不全。

解決方法目前研出来两种,第一种是,让UI直接修改图片尺寸,自己按照960*540的方式布局

第二种进行屏幕缩放,挺方便的但是将来可能会遇到bug,

在App.vue中created步骤时候,执行缩放命令

    document.body.style.zoom = 0.75;//可以根据具体的电视屏幕来调节

在这之前可以进行机型判断,这样可以实现响应式布局的要求

为了确保安全,可以在index.html里加一个meta标签

  <!-- <meta content="width=device-width, initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport"> -->
  <!-- user-scalable=no" 禁止用户缩放 -->

4.关于通过聚焦判断图片的显示与隐藏

要是每次通过js判断该节点是否含有class标签focus来进行v-show的显示与隐藏会比较麻烦,目前建议通过css来进行节点的显示与影藏

    .focus {
      transform: scale(1);
      border: 0px solid red;
      box-shadow: 0 0 0px red;
    }

    img {
      // position: absolute;
    }

    .box img:nth-child(1) {
      display: inline-block;
    }

    .box img:nth-child(2) {
      display: none;
    }

    .focus img:nth-child(1) {
      display: none !important;
      // display: none;
      // display: ;
    }

    .focus img:nth-child(2) {
      display: inline-block !important;

    }

5.关于H5播放器的封装制作

详情请看文档http://www.croft.vip/544-2/

6.关于当贝支付

准备工作

和安卓SDK一样,去后台创建一个应用,拿到 dbkey 和 appidkey

URL跳转

url地址: https://pay.dangbei.com/openapi/createOrder.php

参数:

参数名 类型 说明
order string 接入方生成的订单号
pid string 接入方的商品id,同一个商品使用同一个id
pname string 商品名称
pdesc string 商品描述
appidkey string 支付后台拿到的appidkey
return_url string 支付成功想要跳回的页面,需要urlencode,自动续费签约不会跳转;关闭交易或者支付失败也会跳转到这个页面,注意取err_msg参数判断状态,ok:支付成功;cancel:取消交易;fail:支付失败
is_contract string 是否是自动自费,默认0为普通扣款,1为自动续费,会跳转到微信签约页面。
total_fee string 商品价格,格式为 :1.02
extra string 附加参数
usernick string 用户昵称,用于展示自动续费签约展示昵称
t string 当前时间戳
channel string 渠道
vername string 应用的版本号
sdkversion string sdk的版本号
sign string 鉴权参数,见下方

将上述参数拼接成url,并跳转到该链接。

sign签名方法。

1. 将 入参的order,pid,appidkey,total_fee,t 这5个参数按照下方结构排列,其余入参不参与签名,如:

str = order={orderno}&pid={pid}&appidkey={appidkey}&total_fee={total_fee}&t={time}

2. 将当贝支付后台拿到的dbkey 直接拼接在上方str后面,,如

str = order={orderno}&pid={pid}&appidkey={appidkey}&total_fee={total_fee}&t={time}{dbkey}

3. 将上方的字符串进行md5加密,结果统一小写

sign= md5(order={orderno}&pid={pid}&appidkey={appidkey}&total_fee={total_fee}&t={time}{dbkey})

MD5加密方法

这里要用到前端MD5加密,js-MD5,地址https://blog.csdn.net/qq_40542728/article/details/95205530

(1)安装

npm install js-md5

(2)main.js中引入

import md5 from 'js-md5';
Vue.prototype.$md5 = md5;

(3)使用

this.$md5("加密内容")

7.关于顶部栏目聚焦难点

1651911696979

产品对顶部聚焦有很多个要求,如下

1、通过返回的type值来判断顶部的栏目标签是否生成

2、标签分为两个状态,选中和非选中

3、当标签失焦的时候,如果路由没变标签的状态页不能变(这点决定了不能用组件自带的.focus决定标签是否是选中状态)

4、在同一个路由中,从上下往标签聚焦,只能聚焦到当前页面对应的标签,当聚焦到标签栏中的标签时候,按左右可以聚焦到其他标签(这个相当于是聚焦组件的一个缺陷吧)

<!--1.2.3 利用v-if来判断是否生成聚焦盒子,用v-show结合路由名称来判断标签状态  -->

<div
          v-focusable
          @click="$router.push('/home')"
          @onFocus="$router.push('/home')"

          v-if="headList[0].status == 1"
        >
          <img
            src="../assets/head_img/xueyuan.png"
            alt=""
            v-show="$route.name != 'Home'"
          />
          <img
            src="../assets/head_img/xueyuanpre.png"
            v-show="$route.name == 'Home'"
            alt=""
          />

        </div>
<!--4.这个由于是插件缺陷,暂时没有特别好的方法实现。目前我的视线方法是:
    把每一个区块的第一个专题单独提取出来,监控它的上键@up,然后用
      this.$tv.requestFocus(
        this.$tv.getElementByPath('//div[@class="top_select_box"]/div[2]')
      );
来指定它聚焦到第几个顶部的栏目标签
-->

8、h5+app实现安卓下载apk更新功能

//首先还是要全局引mui.js
//main.js中引入
import Mui from "vue-awesome-mui";
Vue.use(Mui);
//app.vue中创建更新函数
updateFn() {
    //update_box更新框,must_update强制跟新框。根据data中的版本号和线上返回的版本号决定要不要弹出更新框,根据线上返回的状态码决定是否要强制更新
      this.update_box = false;
      this.must_update = false;

      this.downloading_box = true;

      setTimeout(() => {
        this.downloading_box = false;
        this.closeFn();
      }, 10000);

      // plus.nativeUI.confirm("发现版本更新,请问是否要下载", function (e) {
      var wt = plus.nativeUI.showWaiting;
      var url = this.version_data.url;
      var dtask = plus.downloader.createDownload(url, {}, function (d, status) {
        if (status == 200) {
          var path = d.filename;
          //调动安卓原生安装apk
          let _this = this;
          plus.runtime.install(path).then((_this.this.downloading_box = false));
        } else {
          alert("下载失败:" + status);
        }
      });
      dtask.start();
    },

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。