博主介绍:某大厂从事多年后端开发(Go,C++),目前在学习前端项目,还是一名前端新手。喜欢思考一些实用的小项目并付诸实践。欢迎志同道合的小伙伴一起交流学习,同时希望得到大家的支持,如果您觉得博主的文章对您还有一点点用处,麻烦点个赞,谢谢,同时对文章内容有任何问题和建议,也希望您在评论区留言。
一、前言介绍
1.1 项目来源
博主平时喜欢看剧的电影,与大多数喜欢追剧的人不同,我不是平时工作日去各种视频平台,充值各种会员或等待每集30s的广告看热播剧,我更喜欢下班后或周末下载一些高清的视频沉浸式观看。下载的视频自然需要一款本地视频播放器,之前使用QQ影音,虽然支持的视频模式很多,但是最大的问题就是没有很好的本地视频管理功能,没法知道你上次看到哪一集,哪个地方。没法发弹幕,没法统计你本地/磁盘有多少视频…,而我觉得这些功能是喜欢本地看视频的小伙伴非常需要的,至少对我我自己来说是很希望有这些功能。基于这样的思考和目标,设计实现了本项目。
1.2 创新之处
博主目前没有发现有一款很好的本地视频管理系统,大多是基于video 标签实现了打开/上传本地视频进行播放的小项目,但是这样的操作是比较麻烦的。本项目不需要手动查找,只需要初次使用时进行手动同步后续就可以一键打开播放。后端使用了快速查找/过滤视频算法,可以快速查找本地的视频文件。用户的操作数据保存在本地数据库,再也不用苦思冥想上次看到哪里了。前端通过后端服务器开启的api获取视频流播放,大至10G+视频播放也不会占用太多内存和卡顿。
二、系统设计
本地视频管理系统是在windows操作系统中进行开发运用的,可以使用静态网页直接打开,也可以开启http服务方便其他终端接入。系统的前端使用vue3框架,后端使用go beego web框架,数据库使用sqlite3。
2.1 设计原则
本地视频管理与播放系统的设计与实现思想如下:
1、操作简单方便,系统的界面简单明了:简单明了的页面布局,方便用户找到自己需要的功能。
2、功能较为完善,提供视频播放器的基本功能,尽可能提供更多的管理功能,增删查改。
3、轻量,不需要安装复杂的第三方插件和数据库,在一般性能的PC上都能稳定流程运行。
2.2 整体架构
2.3 系统功能设计
2.4 时序图设计
#mermaid-svg-ba8oiQsryowd4RQ0 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 .error-icon{fill:#552222;}#mermaid-svg-ba8oiQsryowd4RQ0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ba8oiQsryowd4RQ0 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ba8oiQsryowd4RQ0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ba8oiQsryowd4RQ0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ba8oiQsryowd4RQ0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ba8oiQsryowd4RQ0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ba8oiQsryowd4RQ0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ba8oiQsryowd4RQ0 .marker.cross{stroke:#333333;}#mermaid-svg-ba8oiQsryowd4RQ0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ba8oiQsryowd4RQ0 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ba8oiQsryowd4RQ0 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-ba8oiQsryowd4RQ0 .actor-line{stroke:grey;}#mermaid-svg-ba8oiQsryowd4RQ0 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 .sequenceNumber{fill:white;}#mermaid-svg-ba8oiQsryowd4RQ0 #sequencenumber{fill:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 .messageText{fill:#333;stroke:#333;}#mermaid-svg-ba8oiQsryowd4RQ0 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ba8oiQsryowd4RQ0 .labelText,#mermaid-svg-ba8oiQsryowd4RQ0 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-ba8oiQsryowd4RQ0 .loopText,#mermaid-svg-ba8oiQsryowd4RQ0 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-ba8oiQsryowd4RQ0 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-ba8oiQsryowd4RQ0 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-ba8oiQsryowd4RQ0 .noteText,#mermaid-svg-ba8oiQsryowd4RQ0 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-ba8oiQsryowd4RQ0 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ba8oiQsryowd4RQ0 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ba8oiQsryowd4RQ0 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-ba8oiQsryowd4RQ0 .actorPopupMenu{position:absolute;}#mermaid-svg-ba8oiQsryowd4RQ0 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-ba8oiQsryowd4RQ0 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-ba8oiQsryowd4RQ0 .actor-man circle,#mermaid-svg-ba8oiQsryowd4RQ0 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-ba8oiQsryowd4RQ0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
用户
首页
播放页面
后端
本地磁盘
登录
同步
搜索
搜索信息
开启服务器
视频列表
播放
获取播放信息
返回视频信息
编辑视频信息
同步数据库
返回
用户
首页
播放页面
后端
本地磁盘
三、功能介绍
3.1 同步功能
同步功能是首次/有新增视频时需要手动从后端同步本地视频列表到数据库和前端。同步之后,再次打开是不需要再同步了。
3.2 搜索/过滤功能
同步完成后,可以对同步的视频进行搜索,标签过滤或者查看最近观看的视频等常用操作,方便更好的观看和管理视频。
3.3 合集功能
通过下载工具下载电视剧后,会通过文件夹识别出同一个文件夹内的视频,用户只需要全选或选择部分视频加入合集。个别视频也可以在视频播放页面加入合集。操作还是非常简单的,加入合集的视频可以连续播放/点播,可以展示在同一个评论列表中。
3.4 视频播放
视频播放页面主要由三部分组成,包括播放器、评论/合集列表、视频详情。为提供更多的视频播放功能,重写了video的control,支持常用的播放、暂停、全屏、音量调节等功能。还添加了下一集/上一集、时间输入跳转、截图、评论功能。
3.5 快捷键
播放器快捷键少不了,下面是本项目使用的快捷键,可以在播放页面使用。
快捷键名称功能Space播放/暂停Ctrl打开评论/关闭评论窗口Enter确认评论Left左快进6sRight右快进6sInsert截图Alt + A打开/关闭评论列表
3.6 数据库
本项目使用的sqlite本地数据库,其实就是二进制文件,在第一次使用时会自动创建 lmdb.db 数据库文件。后续的视频同步/编辑等操作会增删查改该数据库文件,所以该文件至关重要需要保护好。
必要时可以使用SQLiteStudio打开,对数据库进行编辑修改。
四、实现分析
4.1 技术架构选择
前端主要使用Vue3、 js、 naive-ui、scss技术和框架,使用了vue3的路由管理、全局数据管理、组合式api。vue易学易用,性能出色,是适用场景丰富的 Web 前端框架。
后端使用了Go、beego v2 web框架、beego orm数据库接口,数据库是sqlite3。Go语言是21世纪的C语言,性能出色,支持协程并发,beego也是一款优秀的web框架,有丰富的路由管理和orm功能。
4.2 关键技术分析
4.2.1 快速搜索、过滤视频文件
大家应该都用过everything搜索工具,搜索速度是非常快。原因是Everything并不扫描整个磁盘,只是读取磁盘上的USN日志,所以速度飞快。利用everything的api接口,传入过滤参数即可快速实现视频文件的搜索和过滤。
err := es.EverythingSetSearch(searchExt)// 设置查询条件if err !=nil{returnnil, err
}
err = es.EverythingSetMax(maxMovieNum)if err !=nil{returnnil, err
}// 设置好需要查询结果,包括文件名称,路径,创建时间等
err = es.EverythingSetRequestFlags(es.EverythingRequestFileName | es.EverythingRequestPath |
es.EverythingRequestDateCreated | es.EverythingRequestDateModified | es.EverythingRequestDateAccessed |
es.EverythingRequestSize)
4.2.2 获取本地视频流
基于安全考虑,浏览器是不允许直接传入视频路径变量进行播放的,而是需要input打开视频文件读取后播放,所以在获取到了视频路径后通过正常的方案是没法进行播放的,本项目通过Go beego Web框架启动了文件服务器,将视频文件路径转化为http url,前端通过url获取视频流进行播放。
// 定义磁盘号var fileDirs =[]string{"C","D","E","F","G","H","I","J","K"}// 启动文件服务器for_, fileDir :=range fileDirs {
beego.Handler("/"+fileDir+"/*", http.StripPrefix("/"+fileDir+"/", http.FileServer(http.Dir(""+fileDir+":"))))}
4.2.3 视频列表管理
通过pina组件,设置了全局变量,通过修改变量的值来渲染出不同的视频列表搜索/过滤结果。
exportconst useVideoData =defineStore({id:"videoData",state:()=>{return{videoData:[],}},actions:{addVideoData(val){this.videoData.push(...val);},setVideoData(val){this.videoData = val;}},persist:{enabled:false,strategies:[{key:'videoData',storage: localStorage,}]}})
5 您可能会关心的问题
1、哪里可以下载使用?
目前代码已经开源且发布 v1.0.0版本
项目地址
v1.0.0 release下载
预览地址
2,支持哪些视频格式?
支持mp4,部分mkv格式,不支持rmvb格式。
3、手机端可以使用吗?
在PC端开启服务器端口后,手机端在同一个局域网(连接同一个wifi)后可以打开使用,目前手机端只提供了基本的搜索和播放功能。
4、同步会不会需要很久?
后端使用了快速搜索算法,可以快速搜索本地、移动硬盘、U盘等磁盘上的视频文件,不会超过10s。
5、什么时候需要同步?
首次使用需要同步、数据库文件丢了需要重新同步、新增视频文件\插入移动磁盘后需要同步。非以上场景是不需要同步的。
6,视频从本地磁盘拷贝到移动硬盘/改了文件的名称会不会导致数据丢失/重复?
数据的存储是根据视频文件的创建时间和大小作为键,只要不改变视频大小和创建时间就不会丢失数据,同时后台会定期清理校验无效的视频信息。
7、性能如何,会不会很占内存?
目前博主使用情况看,本地列表差不多300个视频,性能没有问题,不会占用太多内存。
6 下一步计划
其实两周前这些功能都已经开发完毕,目前博主也在使用编译后的系统看视频,效果还是挺好的,但是基于之前的想法是要提供更多的功能的,目前的UI这块不是很理想,所以不想在此版本上继续开发。想用ts和新的UI,可能会参考itab,开发一款单页面web应用,支持包括简单的剪辑、写影评等功能。
版权归原作者 hust_a 所有, 如有侵权,请联系我们删除。