实习记录
项目启动
npm install 失败
将 package-lock.json 文件删去后,再 install 才成功
原因大概是团队中的 node 版本不同
package-lock.json 会在 npm 更改 node_modules 目录树 或者 package.json 时自动生成 ,它准确的描述了当前项目npm包的依赖树,并且在随后的安装中会根据 package-lock.json 来安装,保证是相同的一个依赖树,不考虑这个过程中是否有某个依赖有小版本的更新。(安装依赖时,优先 package-lock.json ,没有时再看 package.json)
它的产生就是来对整个依赖树进行版本固定的(锁死)。
注意,使用cnpm install
时候,并不会生成 package-lock.json
文件,也不会根据 package-lock.json
来安装依赖包,还是会使用 package.json
来安装。
修复漏洞
修复上线前检测出的漏洞,主要是基于 DOM 的 XSS 攻击的安全隐患。
https://blog.csdn.net/lgxzzz/article/details/125010336
相关插件 xss / vue-xss(只支持 js) / vue-dompurify-html
发现问题主要是因为使用了 v-html
1.通过 vue-dompurify-html 插件 实现
1 |
|
1 |
|
1 |
|
2.通过 xss 插件实现
https://github.com/leizongmin/js-xss
1 |
|
1 |
|
后台管理系统新增页面
曲库管理
作用
用于从后台管理系统将音乐资源导入数据库,从而显示在 APP 中。
主要需求
资源有三个级别:教材 > 专辑 > 单曲,每个级别都可以新增(上传)或删除。
输入框用于搜索教材,单选框用于固定乐器
可以下载教材到本地
APP版本管理
作用
用于记录与管理 APP 版本的迭代信息。
两个 APP :调音器 / 好乐器
两个 os:ios / 安卓
主要需求
新增版本
查看版本详情
题库管理页面迭代
首页新增陪练总览部分
查看陪练的用户信息以及答题信息
难点
技术上没什么太难的地方
但是当时有两个问题花了我比较久的时间。
一个问题是在上传资源的时候,资源会丢失,我找了很久问题的原因,后面问了 leader 才知道是被平安拦截掉了,平安的安全措施比较严格,不能从内网向外网传稍大的资源。这个问题要完全解决非常麻烦,可能架构上要改,所以就没有从技术层面去解决,而是在上传资源的时候切到外网。
音乐基础新增试唱功能
作用
一种新题型,原先的题型主要都是选择题。
主要需求
给一个谱子,用户点击 button 倒计时后开始清唱,用户开始唱的时候会录音,同时会有一个小方块来提示用户唱到哪一个音符了。这个小方块会随着时间移动,当它移动到某个音符的上面,就说明应该唱到这个音了。唱完之后会将录音传给后端,使用算法比对进行打分,然后返回一个分数给用户。
两种谱子:五线谱 / 简谱
两种谱子给的资源不一致
五线谱有 xml 文件,将其转为 json 后,解构获得有效信息,主要是每个音符的 起始时间、终止时间、和在谱子中的位置
简谱没有 xml 文件,因此需要 解析 mid 文件来获取每个音符的时间信息,而位置信息要根据谱子来计算,因为谱子的制定是有规则的,谱子里的距离和时间是线性的,我们可以通过音符的时间信息计算出他们的位置。
而有每个音符触发的时间有音符在谱子中所处的位置,我们就可以控制方块在正确的时间处于正确的位置上来提醒用户。
零碎的需求
五线谱 / 简谱 的切换
播放录音
播放范唱(midi,人声)
控制速度
节拍器
难点
控制方块的位置,花了些时间计算
对于 midi 文件的理解与处理,npm 上找了很多包来解析 midi 和播放 midi
节拍器
总结
情景,任务,行动,结果
实习期间,我完成的最主要的一个工作是在我们已有的一个app上新增一个功能,首先介绍一下这个app,这个app一方面它是一个调音器,是一个乐器的辅助工具;另一方面,它是一个音乐题库,这个题库里面只有比较老套的选择判断题,我的任务就是要给这个题库加一种新题型,题干是一首歌的谱子(可以选择五线谱和简谱),题目要求用户跟着谱子演奏乐器,前端会进行录音,在演奏完毕后传给后端,后端结合算法做一个评分,再返回给前端。这是整个的一个流程。这个流程其实很简单,有难度的是一些辅助功能。
1.在录音时谱子上面会有一个指示器,实时指向当前应该被唱到的音符,避免用户漏拍子或者唱着唱着不知道唱到哪了。
2.实现了一个类似于全民k歌的功能,首先会根据谱子的数据利用svg绘制一个音高线图,这个音高线图会随着时间向左移动,用户在哼唱时会有一个小球根据用户哼唱的音高上下跳动,用于辅助用户控制自己的音准。
3.实现了一个节拍器控件,节拍器就是在录音时会根据谱子规律的发出哒哒哒哒哒哒的音效,用来辅助用户更好地跟紧节奏。这个问题我想到两种解决方案,一是利用一个很短的音频文件,每当指示器指到一个新的音符就播放它。二是利用 H5 的 Web Audio API 的 Audio Context 来创造声音,原理就是创建振荡器,制定波形和频率,然后将其和电脑的扬声器连接就可以了。因为声音本质就是通过震动产生的嘛。考虑到我没有现成的音频资源,也秉持着不额外增加资源的原则,就选择了第二种方案。在测试第二种方案的时候也遇到了问题,就是 Audio Context 所创建的音频并不是一个可以被反复利用的音频,它会在播放完毕后被销毁。而因为在我们的场景下需要短时间反复播放该音频,反复的创建销毁实例肯定不是一个好的选择,而且 Audio Context 因为需要声卡中的资源,所以硬件上会有限制,不能同时创建太多的音频。我最后的解决方案是在开始录音的时候创建一个不设终止时间的音频,但是断开和扬声器的连接,根据谱子需要打节拍的时候就短暂连接上音频发出一声哒,直到录音终止再销毁这个音频实例,这样我们每次录音就只需要创建一个音频。
这是几个最主要的功能,还有一些零零散散的比较简单的,比如说控制录音时的速度控件,这个速度实际会影响三个部分,谱子上的指示器移动的速度,音高线图移动的速度,还有节拍器哒哒哒的速度。我是将速度转成了时间,因为一首歌的时间是固定的嘛,每个音符也是固定的,所以不管是哪个部分,到了规定的时间就去做规定的事情。
关于封装组件
结构
按功能和位置分(主要是按功能)

引入并使用子组件
1 |
|
1 |
|
学习到了什么
git
git add .
git commit -m “…”
git push
git stash
git stash pop
vue3 + ts 实操
- vue3
- 组件间通信(全局事件总线 emitBus 较多)
- nextTick
- ts
- interface
- vue3
代码规范
- 宏观上
代码分块明确,同一功能的代码尽量放在一起提升可维护性,当然 vue3 的组合式 api 意义就在这里;
抽离函数逻辑,不要把一块东西写的太复杂。同样的,组件也是;
- 微观上
变量命名不要太长、要尽量能够顾名思义;
减少魔法数字的出现,用变量替代;
项目开启了 eslint,对于是否书写分号这些细节也有要求;
独立解决未知问题的能力
- 领域未知
之前从未接触过音乐领域,乐理也是一窍不通。但在做需求的过程中需要一定的音乐基础,主要是在对于数据的理解上(比如数据中时间的单位我一开始以为是 ms,后面才知道是跟节拍有关,那么要将节拍转成 s,又涉及一个新的名词叫 bpm)以及一些插件的使用上(如 midi 音频文件的播放插件 / 解析 midi 的插件 / 读取用户声音频率的插件),读取到频率后怎么转成数字音高,数字音高怎么转成符号音高。
- 从未接触过的需求
刚拿到需求还是比较迷茫的,因为里面有一些东西是之前没有接触过的。
通过努力一步一步的解决了
沟通能力
- 与产品和后端的沟通非常重要
理解有参差的话会事倍功半,在写后台管理项目时就遇到了问题
- 不懂要问
不要僵着浪费时间