电视直播工具推荐

https://github.com/andandroidor/ourtv

June 29, 2024 · 1 min · word · 水华

win 掌机远程控制 ps5

其实一共有两套方案 稍微麻烦一点的时使用 chiaki 或者和我一样使用 psremoteplay chiaki chiaki 也叫千秋其实已经是一个非常成熟的工具了 https://sr.ht/~thestr4ng3r/chiaki/ 主要麻烦的一点是,你需要自己获取对应的 psn accound id Obtaining your PSN AccountID Starting with PS4 7.0, it is necessary to use a so-called “AccountID” as opposed to the “Online-ID” for registration (streaming itself did not change). This ID seems to be a unique identifier for a PSN Account and it can be obtained from the PSN after logging in using OAuth. A Python 3 script which does this is provided in scripts/psn-account-id.py. Simply run it in a terminal and follow the instructions. Once you know your ID, write it down. You will likely never have to do this process again. ...

May 5, 2024 · 1 min · 137 words · 水华

如何实现表格的列拖拽的

因为使用el-table实现,所以一些抓取dom的class类通过el-table内置的类实现,实际如果是简单表格的话,可以自行增加class来实现 底层框架/原理 sortablejs 核心的拖拽原理,我们通过使用sortablejs提供的dom拖拽方案,实现 我们通过让sortablejs的el参数指定到el-table的header上 const query = ".el-table__header-wrapper thead tr" const el docuemnt.querySelector(query) // this.$el.querySelector(query) 那么表头的那一行的所有th就变为拖拽目标了,之后根据index的顺序变化,可以反推到列的切换上 核心代码 const sortable = new Sortable(el, { onEnd(evt) { let { newIndex, oldIndex, item } = evt; // 通知上级交换column位置 } }) 其他一些实现 跨表格实现 跨表格实现思路在于,通过在window上建立一个桥接用的map 缓存table的dom => vue实例对应关系 const sortable = new Sortable(el, { onEnd(evt) { const { to, from, pullMode } = evt; const toContext = window.bridge.get(to) const fromContext = window.bridge.get(from) let { newIndex, oldIndex, item } = evt; // 通知from和to对应的数据进行切换即可 } }) 拖拽优化 虽然核心代码很简单,但是不够完美,拖拽的时候只有表头可以进行拖动,实际上整列是没有跟着一起拖动的 所以我们需要进行样式上的优化,主要有两点 拖拽时候的影子 该列所有td跟随表头拖动 ...

December 11, 2021 · 5 min · 875 words · 水华

用JS去读取【MMD】中vmd文件的那些事

未来能用js编写的软件,都会用js编写 前言 MikuMikuDance,简称MMD,如果是b站用户的话,应该都看到过一个专门的mmd分区,里面是各类舞蹈视频,这个是早期(真的很久了)给v家角色制作舞蹈动画的一个软件,当然除了v家6人以外,崩坏3,元神各类角色相关的宅舞投稿都有 mmd其实本质上还是一款三维动画制作软件,包含 模型 动作 关键帧等一系列相关的概念,模型的话,TGA式,大妈式,很多都有相关的配布,模型和镜头也有相关的发布,其实相关产业已经很完善了,但是这一次,我打算对mmd中保存动作,镜头,表情和关键帧的VMD(Vocaload Mation Data)文件下手了,当然主要还是因为。。。 mmd不支持mac!我不想装windows啊,作为前端工程师的我,如果想实现类似的渲染,那么,一方面是需要搞定模型的渲染**(Tree.js永远的神)**,另一方面就是能够编辑解析其中的vmd文件了 当然,为了解决动作的问题, 一方面,mmd提供了kinect进行捕捉,另一方面,我也想试试用posenet来解析动作,不过在这之前,先得吧vmd搞定 顺便,练习一下用js读取二进制流嘛 几个概念 二进制流 文件其实就是一堆 0,1 组成的二进制码流,在javascript的世界中,这种文件叫做ArrayBuffer, 虽然我们不能直接操作,但是做相应的读取还是没用问题的 你不能直接操作 ArrayBuffer 的内容,而是要通过类型数组对象或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。 用js获取二进制流有几种办法,最常用的就是从file直接转过来,这里我们通过FileReader即可 FileReader 接口提供的 readAsArrayBuffer() 方法用于启动读取指定的 Blob 或 File 内容。当读取操作完成时,readyState 变成 DONE(已完成),并触发 loadend 事件,同时 result 属性中将包含一个 ArrayBuffer 对象以表示所读取文件的数据。 当然啦,还有很多种办法,比如把请求头设置成arrayBuffer等等,这里请查阅相关的文档吧 TypedArray 在真实的使用场景(比如其他语言体系,例如c)其实对bytes有很多种不同的编码方案,用来表示不同的类型,int型一般2个字节这种,在js中也有相对应的TypedArrays 只要参考对照表,其实读取方面就比较简单了 VMD文件的格式 光有文件流,还需要一套相应的读取方案才行,感谢国内两位大佬的相关文章,解惑了 ...

December 6, 2020 · 2 min · 235 words · 水华

如何发布一个vue组件到npm

如今做vue的相关开发,基本都离不开vue-cli,有时候,我们也会将自己工作中抽象出来的优秀方法或者组件发布给外网进行使用,本文基于自身写的seed组件系统整理一下如何自动化发布到npm的一个流程 一些前期准备 github账号和仓库地址 npmjs的账号 整体构建流程 既然要做,就考虑一下完全自动化构建发布吧,基于github actions来完成整个CI/CD工作,主要包含,代码的自动构建,自动发布文档到github.io以及自动发布到npm上 所以我们需要 vue-cli 创建项目 github code 用于在github action的时候访问授权 npmjs code 发布的时候用的code vuepress 可以在md中使用vue组件的文档构建工具 一些合理的命名,在组件发布到npm后,调用者也能正确的使用 开始安装vue-cli 请老手直接跳过 npm install -g @vue/cli # OR yarn global add @vue/cli vue create 你的项目名称 更改你的目录结构 初始化的vue项目目录基本是为了开发一个网页app使用的,然而我们的目标是构建一个lib所以需要将目录结构进行一定的更改 原本的src文件夹存放的是页面的源代码,在组件库构建中,相当于是一个演示目录,所以我们将其更名为examples, 同时在根目录下新建一个packages存放我们开发的lib需要的代码,当然,如果有一些通用的lib文件的话,也新建一个lib文件夹好了 既然目录结构改了,一些默认的入口地址也进行更换 增加jsconfig.json 这个主要为了方便vscode提示,大概例子为 { "compilerOptions": { "target": "esnext", "experimentalDecorators": true, "baseUrl": ".", "checkJs": false, "paths": { "@/*": [ "./examples/*" ], "{你的项目名称}/packages/*": [ "./packages/*" ], "{你的项目名称}/lib/*": [ "./lib/*" ], "types/*": [ "types/*" ] } }, "exclude": [ "node_modules", "lib", "docs", ".github", "public" ] } 增加vue.config.js 这里为了做别名引用,以及修改开发时的页面的入口文件地址为新的目标文件夹 ...

August 8, 2020 · 4 min · 726 words · 水华

给你的vuepress站点加个live2d吧

很早以前,个人博客站点用的是hexo构建的,当时因为好玩给自己的站点加了一个live2d挂件,现在倒是将博客迁移到了vuepress上,可是找了半天没有一个vuepress的插件可以让我使用自定义的live2d模型,没办法只能自己封装了一个 如何使用 基于pixi-live2d-display我封装了一个vuepress插件,叫vuepress-plugin-pixi-live2d-display,可以自定义传入model的地址 不过只支持model3之后的模型版本 安装 npm i vuepress-plugin-pixi-live2d-display or yarn add vuepress-plugin-pixi-live2d-display 上传模型 可以上传到第三方平台比如oss, 或者在vuepress的.vuepress/public文件夹下 拿到对应的model3.json文件地址 添加配置 在.vuepress.config.js中添加 module.exports = { plugins: [ ['vuepress-plugin-pixi-live2d-display', { model: "你的模型地址" }] ] } 就可以使用啦 当然,因为底层依赖包是通过script引入的,本身存在时间差,所以live2d加载一开始会比较慢,也有可能会因为依赖库未加载完成报错 其他还有一些配置参数可以参考组件配置https://www.npmjs.com/package/vuepress-plugin-pixi-live2d-display

March 9, 2020 · 1 min · 33 words · 水华

前端和excel的那些事

在开发需求中,经常会遇到需要和excel相关的需求,毕竟不是所有人都是程序员,很多的业务都是通过excel去进行数据的整理归类计算的,excel中提供的一系列快捷功能,统计功能也非常的实用,但是这也就造成了除了和接口打交道,前端也需要和excel打一下交道 excel 是什么 excel是微软出的一款电子表格软件,wps是国内知名的免费办公软件,以及苹果的Numbers同样都支持编辑和生成excel文件 excel 的格式 这里说的不是单纯的excel而是平时前端开发的时候所使用到的**excel类型**的文件格式,主要有 csv csv 是一种纯文本的格式,非常的简单,每一行代表一行,没一列通过,进行分割,我们只需要通过split函数就能直接分割成对应的二维数组结构 xsls/xls 区别在于 xls类型的文件我们可以通过存储网页的形式存储下来,xsls就是一个纯的二进制文件了,这一类更倾向于使用类库进行操作 读取 如果是csv,最简单的情况下,就直接使用<input type="file">,只有用fileReader读取为纯文本就行了 nodejs和browser唯一的区别就在于,node还支持直接通过steam等概念进行输入,而browser只有arrayBuffer这一种手段 在一般情况下,直接fileReader读取excel都会是二进制流,不过根据其编码规范是可以进行还原的,其中的对应关系比较负责 常用的库 库的左右就在于,他们能将excel的文件专为对应的js对象供我们操作 sheet.js 社区开源版本的xlsx.js就可以完成读取和写入的工作了, 以下是 sheet.js 的对应数据结构. 读取也狠方便 XLSX.read(buffer, { type: "buffer" }); 不过官方的文档相对还是比较难以理解的,一般日常我用另外一个库 exceljs js-xlsx 的 思想构成也是通过将二进制流转为js对象的方式方便我们操作,不过 api 方面设计的更加友好一点 最主要的两点。 中文文档 demo 易懂 读取也很容易,通过fileReader.readAsArrayBuffer 就能直接读取,如果是在node环境下,更能直接通过steam和file接口直接获取数据 // load from buffer var workbook = new Excel.Workbook(); workbook.xlsx.load(data) .then(function() { // use workbook }); 写入 原生 js 这个只适用于 js xls 2013 之前的xls模式是可以将一个html文件导出成一个.xls文件的所以我们首先定义一个html <table id="tblData"> <tr> <th>Name</th> <th>Email</th> <th>Country</th> </tr> <tr> <td>John Doe</td> <td>john@gmail.com</td> <td>USA</td> </tr> <tr> <td>Michael Addison</td> <td>michael@gmail.com</td> <td>UK</td> </tr> <tr> <td>Sam Farmer</td> <td>sam@gmail.com</td> <td>France</td> </tr> </table> 接着获取html之后导出 ...

February 14, 2020 · 1 min · 212 words · 水华

postgresql全文搜索引擎

带权重的搜索引擎 双十一背后的技术 参考此文 对其进行改进和自定义 毫秒级的为该文章 具体实施流程 分词(英文基本无需分词) zhparser 安装 SCWS. wget -q -O - http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2 | tar xf - cd scws-1.2.3 ; ./configure ; make install 注意:在FreeBSD release 10及以上版本上运行configure时,需要增加--with-pic选项。 如果是从github上下载的scws源码需要先运行以下命令生成configure文件: touch README;aclocal;autoconf;autoheader;libtoolize;automake --add-missing git clone https://github.com/amutu/zhparser.git cd zhparser make && make install CREATE EXTENSION zhparser; CREATE TEXT SEARCH CONFIGURATION zhcfg (PARSER = zhparser); ALTER TEXT SEARCH CONFIGURATION zhcfg ADD MAPPING FOR n,v,a,i,e,l,j,m WITH simple; 增加类型 select ts_debug('zhcfg','三一') ; ts_debug 可以查看到分词的token类型 如果不在之前的mapping内的话是不会被分词的 解决方案是 ALTER TEXT SEARCH CONFIGURATION zhcfg ADD MAPPING FOR [没有的类型] WITH simple; 设置分词参数 ...

October 18, 2019 · 4 min · 837 words · 水华

纯css实现table表头吸顶

原文章https://css-tricks.com/position-sticky-and-table-headers/. 本身产品有个需求需要表格自动吸顶,本身用了 antd design 的 scroll 实现的,现在使用 css 实现,效果更好 thead和tr上无法设置 styleposition: sticky;, 到那时在th上却可以,这也意味着,其实你可以在一个传统的table上实现吸顶 header 效果,如果你不清楚吸顶实现的原理,大概实现起来会很棘手吧,使用 css 总比原先用 js 去监听事件然后改变position好得多 兼容性 查看兼容性 只要不是 ie 这种活化石,基本都已经支持了 使用 保证 table 的 position 为 relative 给每个 th 加上 sticky 例子 .stickyTable { :global(table) { position: relative; :global(th) { position: sticky; top: 0; z-index: 9999; } } }

September 9, 2019 · 1 min · 53 words · 水华

一次node内存泄漏排查和解决

背景 公司需要对接各种渠道,进行渠道管理进行了统一规范,生成了 ChannelManager 这个类,上线后发现一直报警,内存居高不下,而且走势呈阶梯上升,判断发生了内存泄漏 技术栈 Nuxt 基于 nuxt 和 vue 开发的一套前端代码 nodejs 性能平台 alinode,一个 ali 官方出的用来监控整个 node 内存和机器运行情况的程序,非常好用,问题是数据有一定延时 解决的步骤 首先尝试临时解决问题 因为线上一共有四台机器跑 ssr,所以通过设置不同的 crontab 进行分批重启 pm2,使得服务不间断 下线问题的 feture 最近上线的 feture 只有 channelManager,于是回滚代码之后重新发布,发现问题解决,找到问题代码区域 CodeReview 开会大家回顾整个问题代码,分析之后发现可能的问题在于使用了 global 的 mixin,改成 Vue plugin 的形式使用,具体可以参考这个 issue 测试环境下发现问题依旧没有解决 验尸 对比了最近几次 alinode 抓下的堆快照,发现所有的闭包都是 vue 实例,而且都会有一个同样的 key$channelManager 找出问题所在 最终发现是上 channelManager 的时候在 nuxt 的 plugin 中使用了 inject,因为 inject 的时候是同一个实例,本身的目的是可以获取 channel 列表 module.exports = (ctx, inject) => { const ChannelManager = require('ChannelManager') inject('channelManager', ChannelManager) } 原因 在于 v8 的整个 gc 机制在于是否能够被访问到,因为 inject 之后不知道为何从 channelManager 能够访问到所有 inject 之后的 vue 实例,所以这一系列的 vue 对象都不可被回收 ...

June 1, 2019 · 1 min · 90 words · 水华