简介这是一套面向流媒体开发者与前端工程师的EasyMedia前端界面资源基于Vue.js实现RTSP与FLV直播点播播放并提供单屏、四分屏、九分屏、十六分屏等多分屏布局适用于安防监控、多路视频同屏预览等场景。资源包共22个文件以7个vue组件与7个js脚本为主涵盖路由、状态管理、播放器封装及HTTP请求模块另含json配置、浏览器兼容列表、ESLint规范等工程配置从项目构建到运行调试形成完整前端工程体系整包仅101KB轻量易部署。目前已有16561人学习下载。通过阅读源码可掌握Vue组件化组织方式、RTSP/FLV播放流程、多分屏状态切换逻辑以及前端工程化配置方法对需要快速搭建流媒体前端界面或研究播放器集成方案的开发者具有直接参考价值。1. 从 EasyMedia-ui.zip 说起它到底是拿来干嘛的很多人第一反应是解压、npm install、npm run dev结果发现里面根本没有 src 目录。EasyMedia-ui.zip 这个压缩包多数情况下指的是媒体管理平台的前端界面资源可能带完整源码也可能只是构建好的一份 dist 产物无论哪种最终要干的事都一样把它接进你已经有的媒体服务让人能登录、看媒体列表、发起转码、拉起播放器。真正花时间的不是把页面跑起来而是三件事接口地址怎么配、登录鉴权怎么接、流媒体播放地址怎么拼。这三件事不顺界面再好看也是空壳。下面按拆包看结构、本地跑通、对接后端、部署避坑的顺序走一遍适合一个人扛前后端的开发者也适合想从界面反推媒体服务接口设计的人。2. 先拆包再动手EasyMedia-ui 的目录结构与三种常见形态2.1 用 unzip 无损解包先看根目录清单先别急着双击压缩包。Windows 自带的解压会把目录和权限属性弄丢偶尔还带出 __MACOSX 这类隐藏目录后面 npm 安装会莫名报错。我一般在 Linux 或 macOS 上解压目标目录先建好避免解出来一堆文件散在当前目录mkdir -p /work/media-platform mv EasyMedia-ui.zip /work/media-platform/ cd /work/media-platform unzip EasyMedia-ui.zip -d easymedia-ui-src ls -lah easymedia-ui-src几个参数的用途说一下-d是指定解压目标目录目录不存在时 unzip 会直接建如果解压后 ls 发现中文文件名变乱码说明这个 zip 是在 Windows 用 GBK 编码打的再加一遍unzip -O gbk EasyMedia-ui.zip -d easymedia-ui-src重新解压就能恢复正常。这一步做完你得到的 easymedia-ui-src 就是后面所有操作的工作目录建议全程用绝对路径引用它避免后面 nginx 配置里相对路径埋坑。根目录清单要重点看几个文件package.json 存在与否、dist 或 src 目录存在与否、有没有 README 或 deploy 目录。有一条捷径先看文件总大小。如果整个包只有 1~3 MB 且没有 package.json基本可以断定是构建产物后面第 3 章的开发命令就不适用了如果包有几十 MB 且有 node_modules说明对方打包时把依赖也塞了进来这种包安装时可以跳过 npm install 直接跑但我不建议直接复用依赖版本可能和本机不匹配。2.2 源码包、构建包与预发布包先分清再谈接入把解压结果按形态分类是后续所有操作的前提。我按根目录特征分三种形态根目录特征接入方式容易踩的坑源码包有 package.json、src/、vite.config.*npm install 后开发调试再构建依赖装不上、Node 版本不匹配构建包只有 dist/ 或直接把 index.html 摊在根目录拷贝到 Nginx 静态目录改接口地址刷新页面 404、静态资源 404预发布包构建产物 nginx.conf 或 deploy/ 说明改配置里的后端地址后直接部署配置里写死了测试环境 IP区分方法其实很简单根目录有 package.json 就是源码包没有 package.json 但有 index.html就是构建包两者都有且多了部署目录就是预发布包。拿到预发布包先别急着部署把里面 nginx.conf 的 server_name 和 proxy_pass 改成你自己的环境再检查 upstream 指向的后端端口是否还活着。如果是源码包接下去按第 3 章来如果是构建包跳第 4 章直接联调接口然后再看第 4 节的部署配置。我在帮某公司的媒体后台接一个大屏展示时就吃过一次构建包的亏以为它是源码包花了一晚上装依赖最后发现根本没有 src 目录白白浪费了时间。这个分类动作务必在解压后两分钟内完成。2.3 入口文件与构建配置先认出框架再决定下一步打开解压后的 index.html观察 script 标签的路径。Vite 构建出来的典型长这样/assets/index-xxxxxxxx.js文件名带一串 hashwebpack 构建则可能是static/js/app.xxxx.js如果入口里既有 idroot 又有 React 字样那就是 React 工程Vue 工程通常是 idapp 或 idvue_app。这个判断决定了代理配置和路由模式的处理方式。grep -Eo src[^] index.html | head -10输出里能看到入口 JS 的引用路径。注意路径开头是不是绝对路径/assets/...如果带前导斜杠说明构建配置里 base 是根路径部署在子目录时一定会 404不带斜杠则相对路径部署更灵活。这个看似不起眼的细节是后面“部署完白屏”问题的一个主要来源先记下来第 5 章展开。顺着入口再找构建配置文件Vite 对应 vite.config.js/tswebpack 对应 vue.config.js 或 webpack.config.js。打开看 server.proxy 和 base 字段能直接确认开发代理和后端地址写在哪。如果 config 文件里已经有代理第 3 章就不用自己另写直接改 target 就行。识别框架时顺便把路由模式也记下来入口 JS 里如果出现 createWebHistory是 history 模式生产环境刷新会走服务器必须有 try_files 回退出现 createWebHashHistory是 hash 模式部署更省心但 URL 会带 #。这个信息在第 4.4 节配置 Nginx 时直接决定 try_files 要不要写。这一套识别流程走下来不超过五分钟你就知道这份包该怎么接、接口层在哪里改、部署时要注意什么。3. 本地跑通 EasyMedia-ui最小开发环境命令3.1 先确认 Node 版本与包管理器别急着 install源码包跑不起来十次有八次不是代码问题是环境问题。最容易翻车的就两个Node 版本和包管理器不一致。先看锁文件和 engines 字段再动手安装这是省时间的第一步。cd /work/media-platform/easymedia-ui-src cat package.json | grep -A3 engines node -vengines 字段不是每个源码包都有没有时就看锁文件package-lock.json 对应 npmpnpm-lock.yaml 对应 pnpmyarn.lock 对应 yarn。锁文件是在哪个包管理器下生成的就用哪个管理器装依赖混用的后果轻则依赖树对不上重则装完启动直接报 Module not found。尤其是 node-sass 这类老依赖和 Node 版本强绑定Node 18 上经常编译失败遇到这种情况先降到 Node 16 再试别急着改代码。另一个容易忽略的是 npm 版本本身npm 9 对锁文件要求严格老项目锁文件是 v2 时经常报错装个 Node 16 自带的 npm 8 就没事了。如果你机器上有多个 Node 版本我习惯用 nvm 管理。先nvm use 16再 node -v 确认当前版本然后安装。npm 源太慢就切到 npmmirrornpm config set registry https://registry.npmmirror.com。这一步不做后面 install 卡半小时很常见算是玄学问题里最不玄的一个。3.2 安装依赖与启动开发服务器环境确认完进入安装启动环节npm install --registryhttps://registry.npmmirror.com npm run dev如果锁文件是 pnpm 生成的第一行换成pnpm install --registryhttps://registry.npmmirror.com如果是 yarn则yarn install --registry...。装依赖时盯着终端最后有没有 error 关键字npm 默认会吞掉部分警告只要不出现 ERR! 就可以继续。启动后终端会打印本地访问地址Vite 默认 5173webpack 一般是 8080 或 3000。浏览器打开后看到登录页有以下几种情况第一种是长得像登录页但没有验证码说明这个包走的是用户名密码接口第二种是直接跳进了一个带着假数据的列表页说明启用了前端 mock第三种是白屏加报错说明入口文件或依赖有问题。看到前两种别高兴太早页面能出来只代表前端活着不代表后端通了。我记得第一次接这类包时看着页面能登录以为完事了结果列表全是 mock 数据真实接口一个没通这个“假活”状态比白屏更迷惑人。建议在启动后顺手打开 F12 的 Network 面板刷新页面看里面请求的 host 是 localhost 还是后端真实地址这一步能立刻判断页面是否还在走 mock。如果 Network 里完全看不到 /api 请求先看前端是不是写死了 mock 开关常见变量是 VITE_USE_MOCK把它置为 false 再重启。启动后如果白屏别急着怀疑代码。第一步看浏览器 console 有没有红色报错第二步看 Network 里入口 JS 是否 200。如果 JS 都加载了但页面空白多半是路由初始化和鉴权跳转的逻辑问题把 URL 里的 hash 或路径清掉再刷新一次。如果 JS 本身 404回头看 2.3 里提到的绝对路径问题开发服务器没配置好历史回退也会有这种现象。3.3 环境变量与本地代理让页面先碰到数据大多数 EasyMedia-ui 这一类前端包接口地址都收敛在环境变量和请求封装里。Vite 工程看.env.development里面常见的键是 VITE_API_BASE、VITE_MEDIA_BASE。前者是接口前缀后者是流媒体地址前缀。如果 .env.development 里没有接着看 src/api/request.js 或 src/utils/request.ts找 axios 实例的 baseURL。cat .env.development 2/dev/null grep -rn VITE_ .env* src/ | head -20看到 VITE_API_BASE/api 之后就要决定是让前端直接请求完整地址还是在开发环境配代理。直接请求完整地址的做法简单但跨域、cookie、鉴权头会连续出问题我一般不推荐。开发环境配代理才是稳定方案Vite 代理写得很短// vite.config.ts import { defineConfig } from vite export default defineConfig({ server: { port: 5173, proxy: { /api: { target: http://127.0.0.1:8080, changeOrigin: true, }, }, }, })这段配置的意思是浏览器里所有以 /api 开头的请求都会被 Vite 的开发服务器转发到 http://127.0.0.1:8080后端收到的请求像从 8080 直接发出的规避了浏览器跨域限制。两个参数重点说明一下changeOrigin 必须为 true否则后端如果按 Host 头做白名单校验会拒绝转发过来的请求target 端口要跟后端服务实际监听端口一致后端在 8090 就写 8090写错端口看到的现象是代理请求一直 pending 然后 502。如果后端接口前缀不是 /api 而是 /v1就把 proxy 的键改成 /v1或者在代理里加一层 rewriteproxy: { /api: { target: http://127.0.0.1:8080, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ), }, }rewrite 的作用是把 /api/login 转成 /login 再转发适用于后端接口本身不带 /api 前缀的情况。配好后重启 npm run dev浏览器里登录一次Network 面板看到真实接口返回 JSON就说明开发链路通了。提示Vite 的 proxy 配置修改后不会热更新必须重启 dev server 才生效别改完配置直接刷新页面发现没变化就以为写错了。4. 把 EasyMedia-ui 对接真实媒体服务从登录态到播放地址4.1 登录鉴权与 Token 处理先看请求封装再谈切换页面能跑起来之后第一件要打通的事就是登录。打开 src/api 或 src/services 目录找到封装 axios 的文件看两处baseURL 是什么请求拦截器里有没有加 Authorization 头。多数媒体管理后端采用 token 鉴权登录接口返回 token 后前端存进 localStorage后续每个请求头顶一个 Bearer token少数走 session cookie那种情况代理必须保证 cookie 透传。先确认后端登录接口的形式curl -X POST http://127.0.0.1:8080/api/login \ -H Content-Type: application/json \ -d {username:admin,password:admin123}观察返回结构。常见两种{code:0,msg:ok,data:{token:...}}和{token:...,expires:7200}。拿到后和前端代码比对前端若从 res.data.token 取值而后端返回的是 data.accessToken就需要修改响应拦截器里的解析逻辑。这类问题我一般改前端不改后端因为协议字段名是后端多个调用方共用的前端包只有你一个人改成本最低。修改后重新登录Network 里看到后续请求带上了 Authorization 头登录链路就算通了。如果登录接口返回 401 而不是 JSON先检查当前请求的 Content-Type 和后端要求的表单格式是否一致。部分后端只接受application/x-www-form-urlencodedaxios 默认发的是 JSON此时登录接口连不上后端日志会显示参数解析失败。这算一个高频切入点先确认再排查别的。4.2 媒体列表与转码任务的接口联调登录进来后进入媒体列表页按 F12 刷新观察页面发了哪些请求。常见的是 GET /api/media/list、GET /api/media/transcode/tasks 之类。逐个检查三点请求方法、分页参数名、响应包装结构。curl http://127.0.0.1:8080/api/media/list?page1pageSize10 \ -H Authorization: Bearer $TOKEN返回的 JSON 里重点是外层包裹字段。前端组件如果读 res.data.list而后端返回的是 res.data.records列表就会渲染为空但不报错。这种“静默失败”是联调阶段最费时间的问题因为页面不红不白只是表格没数据。我的做法是先在浏览器控制台跑一次fetch(/api/media/list?page1pageSize10, { headers: { Authorization: Bearer localStorage.getItem(token) } }).then(r r.json()).then(console.log)然后把返回 JSON 的关键字段和前端列表组件绑定的字段名对一遍。字段名不一致就改前端 map 那一层嵌套层级不一致就改响应拦截器里的 data 解包。这里别图快直接改组件先用一段代码确认字段结构再改最小的一处。关于分页参数媒体列表接口常见的参数名组合是 page/pageSize 和 pageNum/pageSize少数是 offset/limit。如果前端传的参数名和后端不匹配典型现象是第一页能出来但翻页后越翻越糊涂后端把 page 当偏移量用。这个联调要认真对照接口文档没有文档就去看后端的 Controller 入参注解别靠猜。4.3 播放器与流地址拼接的参数细节媒体平台界面里最核心的交互是播放。这个环节的问题大多不在播放器组件本身而在你交给播放器的那个地址。前端拿到媒体对象后通常需要把相对 url 拼上流媒体服务的 base有的还要拼接 token、过期时间。写成工具函数最稳妥// src/utils/play.js export function buildPlayUrl(media) { const base import.meta.env.VITE_MEDIA_BASE || http://127.0.0.1:8090/live const url new URL(media.url, base) if (media.token) { url.searchParams.set(token, media.token) } return url.toString() }逻辑说明new URL 的第二个参数是 base它能正确处理相对路径拼接避免手写字符串时少一个斜杠导致路径错误searchParams.set 会自动处理已有 queryString 的情况避免二次拼接产生?tokenxxxtokenyyy这种重复参数。VITE_MEDIA_BASE 建议放在 .env.production 里区分环境不要在代码里写死。拼接完成后把地址直接在浏览器新标签页打开测试能播放再交给播放器组件。如果新标签页能放而页面里黑屏问题就出在播放器配置上常见的有三处hls.js 版本和后端切片格式不匹配播放器容器高度为 0autoplay 被浏览器拦截。最后一种最反直觉浏览器自动播放策略要求静音状态下才能自动起播所以很多播放器初始化时 muted 必须为 true否则起播直接失败。这个限制要提前知道别等用户反馈“点开没声音、再点才有画面”再去排查。4.4 生产构建与 Nginx 部署要点联调完成后就是构建部署。构建前确认两件事第一是前端路由模式第二是部署在根路径还是子路径。确定后对应调整。npm run buildVite 项目构建前检查 vite.config 里的 base 字段。部署在根路径时 base 用默认的 /部署在/console/子路径时base 必须改成/console/否则 dist 里 index.html 引用的资源路径是 /assets/xxx.js浏览器会去域名根路径找资源全部 404。改完之后构建然后打开 dist/index.html 看 script 标签确认引用路径带了 /console/ 前缀再上传。Nginx 部署我常用的配置server { listen 80; server_name demo.example.com; location /console/ { alias /srv/www/easymedia-ui/dist/; try_files $uri $uri/ /console/index.html; } location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }alias 的路径末尾必须有 /常见写法/srv/www/easymedia-ui/dist少了结尾斜杠请求 /console/assets/a.js 时会拼接成 /srv/www/easymedia-ui/distassets/a.js直接 404。try_files 的最后一个参数 /console/index.html 是给前端 history 路由做回退没有这一行用户在列表页按 F5 刷新时 Nginx 找不到对应的静态文件返回 404。如果前端是 hash 模式路由这一行可以不要URL 带 # 的页面刷新不会走到服务器。如果后端 API 前缀和前端不一致比如前端请求 /api/list 而后端接口是 /list就在 location /api/ 里加 rewritelocation /api/ { rewrite ^/api/(.*)$ /$1 break; proxy_pass http://127.0.0.1:8080; }rewrite 把 /api/ 前缀剥掉后再转发。注意 proxy_pass 后面不要带路径否则会和 rewrite 叠加出双重重写导致接口 404。5. EasyMedia-ui 集成避坑5 个常见翻车点与排查下面这 5 个坑是按出现频率排的前 3 个几乎每个接这批包的人都会碰到后 2 个遇到一次能记一年。每一条都按现象、原因、解决展开方便你对照排查。5.1 依赖装不上或装完启动报一堆错现象npm install 执行到一半报错退出或者装完后 npm run dev 一启动就抛 Module not found、node-sass 编译失败。原因绝大多数情况是包管理器混用。这份包用 pnpm 生成锁文件你用 npm install依赖树对不上或者本机 Node 版本太高老依赖里的原生模块在新版本下编译不过。解决先看锁文件确定包管理器npm install 改 pnpm installnode-sass 报错优先把 Node 降到 16 再装。如果项目里已经有 node_modules 且能跑就别重新安装直接沿用。还有一招兜底npm install --legacy-peer-deps 处理 peerDependencies 冲突。同类变种是 npm 缓存损坏导致 install 一直报 EINTEGRITY这种直接删 node_modules 和 package-lock.json 重装。5.2 页面能开但登录接口 404现象浏览器打开登录页正常输入账号密码后 Network 里登录请求返回 404或者接口一直 pending 然后 502。原因404 多半是代理路径没对上前端请求 /api/login 而后端接口只有 /login代理没做 rewrite502 则是代理 target 端口写错后端没在监听那个端口。解决先看 Network 里失败请求的完整 URL对照 vite.config 里 proxy 的 key。路径不对加 rewrite端口不对改 target。改完必须重启 dev servervite 的 proxy 配置不是热更新的不重启不生效。同类变种是代理目标地址写成了 localhost而后端只监听了 127.0.0.1 的 IPv4 栈localhost 解析到 IPv6 后连接失败这时把 target 改成 127.0.0.1 就行。5.3 列表接口 200 但页面没数据现象Network 里接口正常返回 JSON状态码 200但页面表格空白不报错。原因响应字段不一致。后端返回 data.records前端读 data.list或者分页字段名 page 与 pageNum 对不上。这类问题不报错最容易让人反复怀疑后端数据没生成。解决控制台 fetch 一次接口打印 JSON和组件绑定字段逐一对。改前端 adapter 或响应拦截器把字段统一成组件需要的结构。改完刷新表格有数据就说明找对了。同类变种是布尔值语义反了后端 isSuccess 为 true 表示成功前端判断的是 result true字段类型从 int 0/1 切到 boolean 时很容易踩。5.4 构建部署后白屏、资源 404现象本地 npm run dev 一切正常build 完丢到 Nginx 后打开白屏控制台一堆 .js/.css 404。原因base 路径或 alias 配置问题。前端部署在 /console/ 子路径但 base 是 /资源请求去了根路径或者 nginx alias 结尾少了斜杠路径拼接错误。解决修改构建配置里的 base 为 /console/重新构建检查 dist/index.html 里资源引用带不带前缀nginx alias 目录末尾补 /。如果已经上线了临时处理可以把资源引用改成相对路径但这只是救火正式方案仍然是配好 base。同类变种是 CDN 加速场景资源没回源成功表现为首次打开有页面、刷新后部分资源 404要检查 CDN 的缓存键是否包含了带 hash 的文件名。5.5 播放器黑屏或自动播放失败现象点击播放按钮后播放器不黑屏但无画面有的浏览器直接拒绝起播控制台提示 autoplay 被拦截。原因播放地址没拼对或者 autoplay 策略。隐藏较深的原因是后端返回的 media.url 是相对路径前端没拼 base另外浏览器要求静音才能自动播放。解决先用浏览器新标签页直接打开播放地址验证能放说明地址没问题问题在播放器不能放就检查 buildPlayUrl 的拼接逻辑。自动播放被拦截时把播放器初始化参数 muted 设为 true或者改为点击事件内再初始化播放器因为用户点击后浏览器会放行自动播放。同类变种是 HLS 切片跨域播放器请求 m3u8 文件被 CORS 拦掉需要流媒体服务在响应头加 Access-Control-Allow-Origin。排查这类问题顺序比命令更值钱。我的固定套路是先看 Network再打印接口响应最后才动代码。跳过前两步直接改代码往往会把一个字段名问题改成两个。把上面 5 条按顺序走一遍多数集成问题都能定位到具体层面不会在“前端的问题还是后端的问题”里绕圈子。6. 进阶验证用一轮回归清单确认 EasyMedia-ui 真正可用部署完成后不要只看首页打开就宣告成功。下面是我固定用来验收媒体管理前端的回归清单每次发版照着走一遍能挡住绝大多数线上白屏反馈。检查项操作预期结果登录鉴权正常登录后刷新页面token 未丢、停留原页面子路径刷新在 /console/media/list 直接 F5200页面正常渲染播放器静音起播点击播放画面立即起播列表翻页切到第二页数据完整静态资源打开控制台看 network无 404接口超时提示停掉后端再操作有错误 toast不白屏回归脚本不是必须写但至少把下面几行存成 check.sh每次发版前跑一遍资源完整性验证curl -s -o /dev/null -w %{http_code} http://127.0.0.1/console/index.html curl -s -o /dev/null -w %{http_code} http://127.0.0.1/console/assets/app.js第一行验证入口可访问第二行验证构建产物里的 JS 能被正常加载。注意把 assets/app.js 换成你 dist 里实际的文件名两个都是 200 说明部署目录和 base 基本没配错。接口层面的验证直接对 /api/media/list 跑一次 curl带 token 看返回 JSON比在页面上点点点更能暴露问题。说个自己踩过的教训某次上线只在根路径测了首页没测子路径刷新结果用户反馈一刷新就白屏查了半天是 base 配错加 alias 少斜杠两个问题叠在一起。后来把这份清单固定成发版前的必做项再没出过同类问题。界面资源这东西跑通不稀罕处处能跑才算完。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?