• 使用uni-app组件播放视频


    目录

    一、简介

     二、前后端框架

    前端框架

    后端框架

    三、视频播放

    四、nginx部署

    nginx命令

    五、后端打包

    六、代码地址


    一、简介

            想做一个简单的视频播放器,能够在局域网播放硬盘上的视频。

            如下图所示,从硬盘指定位置读取视频数据,由服务器返回视频流,在浏览器端播放。

     二、前后端框架

    前端框架

            前端使用的uni-app组件开发,打包成H5的格式,然后由Nginx部署访问前端工程。

            开发工具为HbuilderX。

    后端框架

            后端使用spring boot  2.1.6.RELEASE 搭建的整体maven工程。

    三、视频播放

            视频播放直接读取硬盘上MP4文件,然后通过HttpServletResponse返回给前端,前端使用Video的组件进行播放。

            如下是视频播放的后端代码,

    1. /**
    2. * 播放视频
    3. *
    4. * @param vo
    5. * @param response
    6. */
    7. public void playVideo(Map otherInfo, VideoInfoVo vo, HttpServletResponse response) {
    8. String accountName = otherInfo.get("accountName");
    9. try {
    10. OutputStream outputStream = response.getOutputStream();
    11. String filePath = vo.getFilePath();
    12. File file = new File(filePath);
    13. if (file.exists()) {
    14. RandomAccessFile targetFile = new RandomAccessFile(file, "r");
    15. long fileLength = targetFile.length();
    16. long range = 0;
    17. /*
    18. 解决: java.io.IOException: 你的主机中的软件中止了一个已建立的连接
    19. 获取服务器视频流时可能存在跨域问题
    20. */
    21. response.addHeader("Access-Control-Allow-Origin","*");
    22. //设置内容类型
    23. response.setHeader("Content-Type", "video/mp4");
    24. //设置此次相应返回的数据长度
    25. response.setHeader("Content-Length", String.valueOf(fileLength - range));
    26. //设置此次相应返回的数据范围
    27. response.setHeader("Content-Range", "bytes " + range + "-" + (fileLength - 1) + "/" + fileLength);
    28. //返回码需要为206,而不是200
    29. response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
    30. //设定文件读取开始位置(以字节为单位)
    31. targetFile.seek(range);
    32. byte[] cache = new byte[1024 * 300];
    33. int flag;
    34. while ((flag = targetFile.read(cache)) != -1) {
    35. try {
    36. outputStream.write(cache, 0, flag);
    37. } catch (IOException ioe) {
    38. /*
    39. 经过测试发现,前端使用video会调用三次playVideo方法,
    40. 前两次第一次应该是探测是否能连接
    41. 第二次是获取视频长度
    42. 第三次是获取视频流,在第三次时会报 远程主机强制关闭了一个连接,应该是给客户端传递数据后,客户端主动关闭了连接
    43. */
    44. }
    45. }
    46. } else {
    47. String message = "file: not exists";
    48. //解决编码问题
    49. response.setHeader("Content-Type", "application/json");
    50. outputStream.write(message.getBytes(StandardCharsets.UTF_8));
    51. }
    52. try{
    53. outputStream.flush();
    54. }catch (IOException ioe){
    55. /*
    56. 经过测试发现,前端使用video会调用三次playVideo方法,
    57. 前两次第一次应该是探测是否能连接
    58. 第二次是获取视频长度
    59. 第三次是获取视频流,在第三次时会报 远程主机强制关闭了一个连接,应该是给客户端传递数据后,客户端主动关闭了连接
    60. */
    61. }
    62. } catch (IOException e) {
    63. log.error("", e);
    64. }
    65. }

            如下是前端Video组件的使用,

    1. <video id="myVideo" ref="video1" :src="videoUrl"
    2. v-if="showVideo"
    3. @error="videoErrorCallback"
    4. @timeupdate="timeUpdate"
    5. @loadedmetadata="loadedMetaData"
    6. loop=true
    7. :initial-time="startTime"
    8. :danmu-list="danmuList" enable-danmu danmu-btn controls
    9. style="width: 100%;">video>
    1. onLoad(e) {
    2. // e.vId = "1337781752"
    3. this.videoId = e.vId;
    4. this.videoUrl = getVideoUrl(this.videoId);
    5. this.videoUrl += "/"+this.loginName
    6. this.videoUrl = encodeURI(this.videoUrl)
    7. // #ifndef MP-ALIPAY
    8. this.videoContext = uni.createVideoContext('myVideo',this)
    9. // #endif
    10. },
    11. export function getVideoUrl(vId) {
    12. return root + 'video/playVideo/'+vId;
    13. }

            最终实现视频播放功能。

            测试使用的是chrome浏览器。

    四、nginx部署

            

            在前端配置好路由模式,其他任何都不用修改,直接在HbuilderX中打H5的包。

    将包打好后,将h5的包拷贝到nginx的html目录下,

    修改nginx中conf目录下的nginx.conf文件,

    1. 修改访问端口为8090,
    2. 修改首页路径,此处是访问html/familysystem/index.html文件
    3. 修改拦截/baseUrl/,然后转发到后端地址。

     

    http://localhost:8090/baseUrl/video/getRootDirectory?filePath=

    这是nginx发送的请求,需要将baseUrl拦截替换。

    所以最后请求路径就变为 http://localhost:8083/video/getRootDirectory?filePath=

    如果 proxy_pass 配置为 http://localhost:8083 ;  没有以 /  结尾,

    那么就不会替换拦截的baseUrl字段,

    所以请求地址会变为 http://localhost:8083/baseUrl/video/getRootDirectory?filePath=

    一个符号的差距,就有不同的方式,具体可以看此博客,前后端分离利用nginx转发请求后台接口地址-爱码网

     

    在终端nginx所在目录下,输入 start nginx.exe启动nginx。

    在浏览器端输入http://localhost:8090访问首页。

    nginx命令

    start  nginx.exe  启动nginx

    nginx -s stop       快速关闭Nginx,可能不保存相关信息,并迅速终止web服务。

    nginx -s quit       平稳关闭Nginx,保存相关信息,有安排的结束web服务。

    nginx -s reload     因改变了Nginx相关配置,需要重新加载配置而重载。

    nginx -s reopen     重新打开日志文件。

    nginx -c filename   为 Nginx 指定一个配置文件,来代替缺省的。

    nginx -t            不运行,而仅仅测试配置文件。nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件。

    nginx -v            显示 nginx 的版本。

    nginx -V            显示 nginx 的版本,编译器版本和配置参数。

    tasklist /fi "imagename eq nginx.exe"   windows下查看nginx进程

    五、后端打包

            后端是个maven工程,直接在idea中package即可打成一个jar包。

            在终端jar包所在目录,输入  java -jar  XXXX.jar来启动jar包。

     

    六、代码地址

    https://gitee.com/king_software/family-system-ficon-default.png?t=M85Bhttps://gitee.com/king_software/family-system-f

     

             两个项目工程放在同一个仓库中了,真正的名字叫FamilySystem。

    下载后改名分别导入到idea和hbuilderx中即可。

            

  • 相关阅读:
    根据表名称快速查询表所有字段是否包含特定数据筛选
    训练DeeplabV3+来分割车道线
    QT 在主机默认PDF查看应用中打开PDF文档(如通过菜单栏打开使用手册)
    一文带你玩转Redis缓存数据库
    Mainflux IoT:Go语言轻量级开源物联网平台,支持HTTP、MQTT、WebSocket、CoAP协议
    NX二次开发-通过点击按钮来控制显示工具条
    P1020 [NOIP1999 普及组] 导弹拦截
    2021年12月电子学会图形化二级编程题解析含答案:绘制多边形
    LVM 镜像卷配置与维护
    【Socket】解决TCP粘包问题
  • 原文地址:https://blog.csdn.net/lw18751836671/article/details/127859324