• 关于我在uni-app练手中遇到的坑


    目录

    页面层级结构的加载和回退

    filePath编码

    对象的深度克隆

    弹幕的加载

    ​编辑 

    uni-app内置浏览器加载视频失败

    后台报错 java.io.IOException: 你的主机中的软件中止了一个已建立的连接

     安卓里遍历uni-list-item错误

     手机自带浏览器无法加载视频

    乱码问题

    video中initial-time失效

    手动设置视频初始时间

    video的@progress失效

    视频播放结束后,不能直接设置历史记录为结束时间

    mybatis中关联查询

    代码


           

    前几周一直在用uni-app练手,于是乎写了一个视频播放器,从一开始粗糙版,到加入了数据库后的简易版。

            其中记录一下坑。

            代码的话已经提交到github,可能后续还会维护下去,看自己有什么好的想法吧。

            

    页面层级结构的加载和回退

    如图所示,在在加载数据后,进入第二层,第三层目录后,如何回退到父级目录。

    这里就考虑一个数据接口,栈,先进后出。

    页面中定义一个parentDir: [],

    filePath编码

    如果是运行在安卓手机中当app,则window.encodeURI是无效的,所以需要使用

    this.nowFilePath = encodeURIComponent(this.nowFilePath);

    对象的深度克隆

    将一个object对象push到栈中时,加入的仅仅是这个对象的引用,改变了对象引用,栈里面的指向也会改变,所以需要深度克隆。

    弹幕的加载

    在页面上可以看到danmuList是一个数组,从后台请求这个视频的弹幕信息,而如果没有这个v-if的话,弹幕是不会展示的。

    因为页面video组件已经加载完成,此时即使加载了弹幕数据,也压根无用。

     所以才需要在获取数据后展示video组件,如此加载弹幕。

    uni-app内置浏览器加载视频失败

    官网有说明,所以如果是调试,可以运行到chrome等浏览器

    后台报错 java.io.IOException: 你的主机中的软件中止了一个已建立的连接

            此问题尚未真正解决 

    这种有两种情况,第一种是视频的编码不符合video的编码格式。

    HTML

    所以如果不符合上述三种格式的,就需要使用代码转变格式。

    com.lw.familysystem.video.VideoUtils#encode

    第二中情况是视频流的跨域问题,

    com.lw.familysystem.video.VideoService#playVideo

    直接在此方法中加入允许跨域请求,

    response.addHeader("Access-Contro1-A11ow-0rigin","*");

    后记:其实还是会经常出现这个问题,但是不影响播放。

     安卓里遍历uni-list-item错误

    1. <uni-list-item v-for="(item,index) in directories.childDirList" :key="item.filePath" :title="item.name"
    2. note="目录"
    3. thumb="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/460d46d0-4fcc-11eb-8ff1-d5dcf8779628.png"
    4. thumb-size="lg" rightText="点击进入" clickable link @click="toNext(item,index)">uni-list-item>

    在chrome中上述代码没问题,但是运行到手机中,就会出现,

    TypeError: Invalid attempt to destructure non-iterable instance.

    In order to be iterable, non-array objects must have a [Symbol.iterator]() method. at view.umd.min.js:1

     手机自带浏览器无法加载视频

    这个问题暂时还没解决,换了手机里的chrome浏览器后,访问地址能加载视频。 

    乱码问题

    路径变成了ascii码,统一编码。

    其实最好路径不要用中文,就不会有乱码。

     上述使用的是tag  V0.0.2中代码遇到的坑。

    video中initial-time失效

    猜测应该是只有当video第一次初始化,然后加载视频时有用,而我获取视频是在onLoad中加载视频,而video组件出现是在onShow中。

    onLoad中请求后台视频数据时,video可能已经在页面加载,而此时还没有设置url,导致视频会出现加载失败,此时initial-time自然无效。

    当onLoad中请求了视频数据后,给video设置了url后,虽然能播放后台数据,但此时initial-time已经没有效果了。

    经验证,上述猜测错误,真正原因是在playVideo方法中,将response的返回状态码设置为200,而不是206。

    返回206是客户端表明自己只需要目标URL上的部分资源的时候返回的,比如video组件只需要先知道视频的长度,而不需要全部加载视频。

    而200则让完全加载视频信息等。

    1. //返回码需要为206,而不是200
    2. response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);

    手动设置视频初始时间

    不可能每次都调整initial-time,所以需要手动设置,就需要使用到uni.createVideoContext创建的对象了。

    所以就需要用到 videoContext.seek()方法了,

    1. getVideoHistoryM() {
    2. var param = {
    3. loginName: this.loginName,
    4. videoId: this.videos[this.nowPlayIndex].videoId
    5. }
    6. getVideoHistory(param).then(res => {
    7. if (res?.result_code == "0") {
    8. if (res.data) {
    9. var history = res.data;
    10. this.startTime = history.playTime;
    11. this.videoContext.seek(this.startTime); //跳转到指定秒
    12. }
    13. }
    14. });
    15. },

    video的@progress失效

    视频播放完后,一轮循环已经结束,再自动从头开始播放第一集的时候,此时并不会再进入@progress中的方法,所以就需要在@loadedmetadata 中的方法里判断下。

    1. loadedMetaData(e) {//视频加载完毕
    2. const {
    3. duration
    4. } = e.detail
    5. // 记录视频总时间
    6. this.duration = duration
    7. if(!this.autoPlaying){
    8. if(!this.firstVideo){//非第一个视频,自动播放
    9. this.play();
    10. }
    11. }
    12. this.videoContext.playbackRate(1.5);
    13. },
    14. onProgressVideo(e){
    15. const {buffered} = e.detail;
    16. console.log(buffered)
    17. if(buffered>4){//视频加载了百分之 就自动播放
    18. if(!this.firstVideo){//非第一个视频,自动播放
    19. this.play();
    20. }
    21. }
    22. },

    视频播放结束后,不能直接设置历史记录为结束时间

    比如,有个视频,时长18秒,再timeUpdate方法中监测到播放结束时,需要保存历史记录,那么此时不能保存为18秒,否则,下一刻再次点击这个视频时,就自动定位到18秒,然后跳转到下一个视频了,就永远也看不了这个视频了。

    //播放结束后保存历史记录

    this.currentPlayTime = 0;

    this.savePlayHistoryM()

    所以直接将当前时间重置,那么下次就是重头开始播放了。

    mybatis中关联查询

    left join 了多个表,需要将连接表的内容放入组合的vo中。如下所示,返回的Vo中内联了两个vo。

    1. @Data
    2. public class VideoPlayHistoryVo extends VideoPlayHistory {
    3. private String createTimeFmt;
    4. private String updateTimeFmt;
    5. private VideoPhysicsInfoVo videoPhysicsInfoVo;
    6. private VideoInfoVo videoInfoVo;
    7. }

    在xml中也需要编写内联的,association的property值要和VideoPlayHistoryVo中的内联名字相同。

    1. <resultMap id="videoHistoryVoResultMap" type="com.lw.familysystem.vo.VideoPlayHistoryVo">
    2. <id property="historyId" column="history_id"/>
    3. <result property="videoId" column="video_id"/>
    4. <result property="accountName" column="account_name"/>
    5. <result property="playTime" column="play_time"/>
    6. <result property="playTimeVis" column="play_time_vis"/>
    7. <result property="createTimeFmt" column="create_time_fmt"/>
    8. <result property="updateTimeFmt" column="update_time_fmt"/>
    9. <result property="createTime" column="create_time"/>
    10. <result property="updateTime" column="update_time"/>
    11. <association property="videoPhysicsInfoVo" javaType="VideoPhysicsInfoVo">
    12. <id property="videoId" column="video_id"/>
    13. <result property="videoName" column="video_name"/>
    14. <result property="infoId" column="info_id"/>
    15. <result property="orderNo" column="order_no"/>
    16. <result property="quarterInfo" column="quarter_info"/>
    17. <result property="relativePath" column="relative_path"/>
    18. <result property="createTimeFmt" column="create_time_fmt"/>
    19. <result property="updateTimeFmt" column="update_time_fmt"/>
    20. <result property="createTime" column="create_time"/>
    21. <result property="updateTime" column="update_time"/>
    22. association>
    23. <association property="videoInfoVo" javaType="VideoInfoVo">
    24. <id property="infoId" column="info_id"/>
    25. <result property="videoName" column="info_name"/>
    26. <result property="videoType" column="video_type"/>
    27. <result property="orderNo" column="order_no"/>
    28. <result property="categoryId" column="category_id"/>
    29. <result property="relativePath" column="relative_path"/>
    30. <result property="createTimeFmt" column="create_time_fmt"/>
    31. <result property="updateTimeFmt" column="update_time_fmt"/>
    32. <result property="createTime" column="create_time"/>
    33. <result property="updateTime" column="update_time"/>
    34. association>
    35. resultMap>

    在页面上就如下这样使用,例子可以看mine.vue

    1. <uni-list-item v-for="(history,index) in histories" :key="index" :title="history.videoPhysicsInfoVo.videoName"
    2. :note="history.videoInfoVo.videoName"
    3. :rightText="''+history.playTimeVis" clickable link
    4. @click="toPlayVideoPage(history.videoPhysicsInfoVo.infoId,history.videoPhysicsInfoVo.videoId)">
    5. uni-list-item>

            上述问题是 tag V0.0.3遇到的问题

    代码

    后端

    前端

  • 相关阅读:
    Mycat中间件,分布式数据库中间件的佼佼者,带你从实战出发轻松掌握
    HNU-计算机网络-讨论课1
    海缆探测仪TSS350(三)
    Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):4、Maven项目转换与pom.xml配置
    J2EE--通用分页(后台)
    不同服务器节点之间 如何实现高效可靠的文件同步?
    ffmpeg基础三:H264,从MP4文件获取(av_bsf_get_by_name(“h264_mp4toannexb“))和从TS流获取保存H264
    LeetCode——二分查找(Java)
    懒人福利:只需一行代码,导入所有的 Python 库
    Elasticsearch灾备同步方案功能验证(三)
  • 原文地址:https://blog.csdn.net/lw18751836671/article/details/128000911