手把手教你如何轻松播放附件中的视频——面向初学者的实践指引

发布时间 2023-10-30 13:54:14作者: cybozu开发者

前言

在日常使用办公系统的过程中,经常被问到一个问题,就是附件中如果上传的是视频文件,如何在网页上播放?虽然可以下载后再在本地播放,但是有时候只是想看一下视频里其中的一段,下载后再播放就非常的浪费时间。

在这篇文章中,我们将一步一步手把手教你如何实现在办公系统中播放视频(以kintone为例)。另外,本篇会比较偏向刚刚入门 kintone 自定义开发的同学,借助这个播放视频的实例,我们会从需求分析,前期准备,代码语句的选择,查阅资料,JS方法等使用,以及日常编程中的一些小技巧予以一一讲解,希望能对初学者向熟练工过渡,起到一个启发和帮助作用。我们知道,需求来了能解决自然是好,但是更重要的是学会整个一套工作的方法,所谓知其然还要知其所以然。中级及以上程度的读者,有些部分可能过于初级,可以略过详细讲解部分,自行选择阅读。

完成后的效果大致如下图,主要功能有,进度条拖拽,倍速播放,全屏播放,浮动窗播放。

需求分析

一句话解释需求:在 kintone 中上传视频文件附件,不需要下载就可以在网页上直接播放。

作用范围:在 kinotne 中有多个地方可以上传附件,例如 app 内,space 内等等。不过一般 kintone 自定义一般只限定于 app 内,而且文章只是一个实例讲解,所以我们就不如把范围界定在 app 的详情画面内。

设计

需求知道了,有些同学马上就会进入编程阶段,但是这里还有一个非常重要的环节:设计。设计的目的是为了让我们在编程的时候更加清晰,更加有目的性,更加有针对性。以免编程的时候瞎胡乱撞,最后发现自己的代码写的乱七八糟,不知道自己在干什么。设计的过程中,我们需要考虑的问题很多,例如:    
   以何种方式实现需求?用户能不能满意?    
   有没有备用方案?以及他们的优劣对比?    
   方案的实现难度如何?在现有工数允许的时间内能不能完成?

如何播放视频?我们刚拿到这个需求肯定是什么都不知道,所以我们先来看一下附件在 app 详情画面的网页结构是怎样的吧。

我们已经准备好了一个具有附件字段的 app,打开它的详情画面,上传好一个视频文件。然后按下 F12 打开开发者工具,切换到 Elements 标签页,按下元素查看按钮,快捷键是 ctrl + shift + c,再把鼠标放在网页附件的元素上,点击一下,开发者工具的元素标签内就会显示相应的html代码。代码大致如下:

<div class="control-value-gaia value-6673173">
    <ul>
    <li class="file-image-container-gaia">
        <a
        href="https://cybozush.cybozu.cn/k/api/record/download.do/-/%E4%B8%87%E4%B9%BE.mp4?app=3156&field=6673173&detectType=true&record=57&row=3189115&id=228337&hash=dea521d143217aa329ab06e7240e79196dbe8f39&revision=5&.mp4"
        title=""
        style=""
        >视频文件.mp4</a
        ><span style="font-size: 12px"> (100 MB)</span>
    </li>
    </ul>
</div>

  

分析这段 html 代码,我们发现,最外面一层是一个 div,里面一层 ul li 是一个列表,估计是当有多个附件的时候,会显示多个 li。li 里面是一个 a 标签,这个 a 标签的 href 属性里放的是视频文件的链接,如果将来我们找到一种可以播放视频的方法时,肯定会要求我们提供这个链接的。现在的阶段我们就只要先知道这个链接在哪里就可以了。

下一步我们来考虑播放视频的位置,大小问题。一般有两种考虑,一种是附件的位置直接插一块区域,这种方法的好处是视频播放块就在原来的附件附近,非常利用用户理解这是哪个视频,问题可能在于播放块的大小,可能受限于附件这个父元素的大小,不过这可以在调整 app form 中附件的大小,应该也不会成为问题。另一种考虑是将视频播放块固定在画面中央区域,这样的好处是播放区域固定,画面中央也很便于观看,问题固定位置可能要用到 css 中的 display: fixed 或者是 absolute,这会将这一块移除文档流,这种排版方式不是很友好,不知道会不会对其他元素,或者是滚动条产生一些未知的影响。这个问题也不急着马上做出决定,等选择了播放视频的方式之后边调试边解决也不迟。

还有一个问题是视频的加载时机,现在我们的附件上只是有一个链接而已,如果加入了一个视频播放块,是需要选择一个加载时机的。也有两种考虑:一种是页面加载完成后自动加载,这样的好处是用户不需要做任何操作就可以看到视频,但是如果视频附件很多,画面上会出现很多视频播放块,比较消耗资源。另一种是在每个视频附件后面加一个按钮,点击按钮后才加载视频,这样的好处是用户可以选择自己想看的视频,应该是一个更好的选择。

我们选择点击按钮播放,应该还需要一个关闭视频块的按钮,这样用户就可以选择关闭视频块,视频有多个的时候,不至于把画面撑满弄得一团糟。

前期准备

现在大致会做成一个什么样的东西我们已经大致心里有数了,正式进入编程之前,我们还需要确认一些准备工作。我们一个一个来看。

我们心里预期,点击按钮之后,会出现一个视频播放块。但是这个视频播放块究竟是个什么我们心里一点都没有底,只是预计会有一些开源的项目会实现这种功能吧。需要一个寻找和比较的过程,这个过程中我们需要有找寻开源库的能力,文档阅读能力,以及基本调试能力。这些能力的培养需要长期的积累,这里就不展开讲了。希望初学者不要忽视这种能力的培养,日常积累是最好的办法,没有捷径。

还有一个需要注意的问题是懂得放弃,如果找不到合适的库,或者库的运用超出我们的能力,抑或是其他技术我们掌握的不过关,都是会对项目成败形成致命影响的。与其胡乱尝试浪费时间,不如寻找其他办法,例如寻找扩展脚本,找更高级程序员询问等等。

确认找到的库切实可用之后,项目的成功就有了很大的把握。这里我们就略去寻找库的方法和过程,直接告诉你这次我们选的库名叫 Plyr 。 它一款简单的轻量级的支持多种播放格式且在现代浏览器上得到稳定支持的开源软件。确认找到的库切实可用之后,项目的成功就有了很大的把握。剩下的就是一些 JS 对网页的基本操作,例如获取元素,添加元素,删除元素,修改元素等等。这些都是非常基础的操作,初学者可以在 MDN 上查阅相关资料,或者是在网上搜索相关的教程,之后我们会在代码解读部分我们遇到什么再具体讲什么。

开发

首先,我们要搞定库的引用问题,我们来到 plyr 的 github 主页,找到使用方式的介绍,有这么一段:

You can use Plyr as an ES6 module as follows:

import Plyr from 'plyr';
const player = new Plyr('#player');

这里说,你可以用 ES6 的方式使用 plyr,代码中的 import 也正好是 ES6 的语法,但是 kintone 的开发不直接支持这种用法。简单说如果你直接在你的代码中写 import ... ,然后上传到自定义 JS 代码的地方,是绝对会报错的。真的要使用这种方式,需要用到 webpack 或其他编译工具作为转换,如果你是一个资深前端开发者,我相信这些也难不倒你,但是本篇文章的目的是面对初学者,所以我们就不用这种方式了。

我们接着往下看文档,幸好还有这么一段:

       You can use our CDN (provided by Cloudflare) for the JavaScript. There's 2 versions; one with and one without polyfills. My recommendation would be to manage polyfills separately as part of your application but to make life easier you can use the polyfilled build.    

这段话的意思大致是:你还可以使用 CDN 方式。如果你不理解 CDN,也没有关系,这里你只要理解为:作者把库的可引用版本,放在了公网上。我们使用时,只需要引用这个地址,不需要把库整个下载下来放到代码里。至于上文中提到的polyfills,它是对应旧型号浏览器的兼容性问题,我们在不考虑这些问题的时候,只要引用无 polyfills 的版本就可以了。

<script src="https://cdn.plyr.io/3.7.8/plyr.js"></script>

上面这段代码是用在 html 中的,用 script 标签来引用别的文件,kintone 的自定义开发,我们只需要用到 src 属性中的内容即可。在自定义设置页面,点击通过 url 添加,把这段 url 添加进去,就相当于把库引入到开发中来了。

紧接下来的文档中,还提到了 css 的使用,同样我们也可以使用 CND 的方式,和 JS 类似,也是添加好 url 即可。这里也许有同学要问,我不用 css 行不行,或者我自己写行不行?我这里还是以初学者的观点出发回答:不太行。不用 css 整个播放块排版会乱掉,自己写 css 要控制的东西太多,初学者完全没必要去搞这些事情。真的要搞也要等基础功能做完整了,再去锦上添花比较好。总之,这里还是老老实实的用他给的 css 就行。

接下来我们就要开始写代码了,在这之前,我还有一个小建议:如果你不是对自己的的代码特别有信心,我认为还是写一小块,就实际调试一次,console log 打印一下阶段性的结果,以确保这一小段达到了自己的预期。这样的好处是,如果你写的代码有问题,可以及时发现,不至于一口气写完,最后发现自己的代码有问题,都不知道从哪里下手修改了。

现在开始正式写代码。首先,我们的代码触发的时机是【纪录详情页面显示之后】,所以我们可以到相应的事件的文档查阅规范写法。如果你不知道怎么查事件,可以先去事件列表寻找你所需要的事件,然后再看事件写法的说明。根据【纪录详情页面显示之后】的代码范例,我们知道我们所有的代码都应该在这个事件的回调函数中写出。

kintone.events.on('app.record.detail.show', function(event) {
    window.alert("记录详情页面已打开")
    return event
})

接下来,我们要先找到页面中是附件的元素,否则无从判断它是不是视频。这里需要用到 JS 中一个很基础的操作,元素的选取。元素的选取可以帮助我们拿到整个页面中,符合我们需求的元素的句柄,因为在程序的世界中,开始对某个东西操作之前,一定要拿到它的句柄,否则你不知道你要操作的是哪个东西。(如果你对句柄这个词感到陌生,那你或许听说过下面这些词:【参照】【引用】【地址】,他们的基本意思都是一样的。)

回到元素的选择,在原生 JS 中,就提供了一系列的方法让我们可以方便的选取元素,他们是以 document.getElement 开头的一系列方法,例如 document.getElementById,document.getElementsByClassName,document.getElementsByTagName 等等。这些方法的使用方法可以在 MDN 上查阅,这里就不展开讲了。他们分别是通过 id,class,tag 来选取元素的。这几个方法比较基础。另外还有两个综合性的方法,即 document.querySelector 和 document.querySelectorAll。他们唯一的区别是前者只会选取第一个符合条件的元素,后者会选取所有符合条件的元素,即你会得到一个数组结果。而这两个综合性的方法,它们的参数是一个 css 选择器,关于 css 选择器的知识,要展开的话可以讲很多,这里我们只要知道,他规定了很多规则,然后这些规则又可以互相叠加组合,从而达到选取复杂特征元素的目的。而前面几个基础性的方法,它们的参数只是一个字符串,只能选取单一特征的元素。

根据我们之前的观察,下面这段 html 代码就是一个典型的附件。

<div class="control-value-gaia value-6673173">
    <ul>
    <li class="file-image-container-gaia">
        <a
        href="https://xxx.cybozu.cn/k/api/record/download.do/-/abc.mp4?app=3156&amp;field=6673173&amp;detectType=true&amp;record=57&amp;row=3189115&amp;id=228337&amp;hash=dea521d143217aa329ab06e7240e79196dbe8f39&amp;revision=5&amp;.mp4"
        title=""
        style=""
        >视频文件.mp4</a
        ><span style="font-size: 12px"> (100 MB)</span>
    </li>
    </ul>
</div>

 分析以上代码、选择器的含义、怎么根据 url 来判断它是不是视频?如何创建?

更多精彩点击?:手把手教你如何轻松播放附件中的视频