作者: meathill

  • 使用 Proxy 添加魔术属性/方法

    使用 Proxy 添加魔术属性/方法

    最近在开发我厂的 QA 工具时,遇到一个问题。我需要模拟 Puppeteer 的所有方法,以便兼容原先的 JS 文件。Puppeteer 提供一个 .asElement() 方法,可以把函数执行结果转换成一个伪 DOM Element(如果函数返回的就是 DOM Element 的话),然后我们就可以在 Node.js 里调用原本属于 DOM 的方法,比如 .focus()。Pupputeer 会替我们完成映射和函数调用,并且返回结果。

    对于大部分对象来说,我只要模拟对应的属性、方法,然后用自己的函数实现功能即可。但是 DOM Element 有上百个属性和方法,手工实现一遍实在太低效了。必须寻找其它途径。

    好在我之前看过 Proxy 的介绍,赶紧翻出文档和书又复习两遍,就大概知道怎么做了。

    Proxy 类如其名,可以“代理”对某个对象的访问。你可以把他理解成明星的经纪人。明星成名之前都是自己处理一切事务,有了经纪人之后,大部分事务就由经纪人负责,但仍然有一些事情需要明星自己处理。

    Proxy 的用法很简单,实例化时,把要代理的对象传进去,定义一下代理方法就好。

    const obj = { name: 'meathill' };
    new Proxy(obj, {
      get(target, property) {
        // 如果对象中有要求的属性或方法,则返回
        if (property in target) {
          return target[property];
        }
        // 没有的话,进行其它处理
        return 'hello';
      }
    });
    
    obj.name // 'meathill'
    obj.age // 'hello'
    obj.sex // 'hello'

    接下来,比如我们访问 obj.foo,那么代理就会生效,它会先检查 obj,如果这个对象上本来就有 foo 属性,就会返回;如果没有,则会调用我们定义的方法来处理。

    如此一来,我们可以定义一个 VElement 类,这个类可以实现一些特殊方法,比如 .type(str) 输入,.click() 点击等;然后用 Proxy 代理其它方法和属性,让对象进入插件 Context 执行。


    关于如何创建具有魔法属性/方法的类,请移步阅读 使用 Proxy 创建有魔术属性/方法的类


    Proxy 还有其它方法也很有用,尤其是 get 对应的 set ,以后再介绍。大家可以自己抽空研究下。

    参考

    • 阮一峰的 ES6
    • 《深入理解 ES6》

  • 远程工作一年半,聊聊远程的问题

    远程工作一年半,聊聊远程的问题

    2017年8月,我加入现在 OpenResty Inc.,开始我职场生涯第一次全职远程的工作。如今,一年半时间过去,我发现远程工作并不如我之前想象的那样美好,还有很多问题是我一开始没想到的,这里记录一下。

    (更多…)
  • Chat idea:Vue 进阶之路

    Chat idea:Vue 进阶之路

    本文记录一下 Vue 里常见的坑,为下一次 GitChat 做准备。

    (更多…)
  • 近期用 webpack-dev-server 作代理的一些经验

    近期用 webpack-dev-server 作代理的一些经验

    如今前端开发使用 webpack-dev-server 作为本地服务器已经是基本配置,加上 proxy 功能可以很好的应对 SSL、跨域、线上环境切换等需求。Vue CLI 3 里也做了相应的集成,用起来很方便。

    (更多…)
  • Chrome 扩展在页面执行 JS

    Chrome 扩展在页面执行 JS

    基于安全考虑,Chrome 扩展运行在一个独立的沙箱里,不能直接接触页面里的变量和实例。但有些时候我们必须在当前页面的环境里执行 JS,比如近期开发 Navlang 时遇到一个需求:修改浏览器环境里语言信息,实现语言切换。

    (更多…)
  • 2019年计划

    2019年计划

    年年有今日,岁岁有今朝。这两天感冒,这会儿眼睛一直发酸(那种想打喷嚏的酸),也不太想打游戏,干脆写写总结,立立 flag 吧。

    (更多…)
  • OpenResty Inc. 全球招募代理

    OpenResty Inc. 全球招募代理

    我们也欢迎其他企业成为我们的销售代理商,在世界任何国家和地区销售我们的产品和服务(只要不在中国和美国商务部的地区黑名单上),实现互利共赢。有兴趣的企业可以发送电子邮件到 info@openresty.com 与我们联系。非常感谢!我们的销售工程师的招聘贴子已经吸引到代理商企业了,所以再专门提一下。

  • 2018 买了啥

    2018 买了啥

    2018 年总结的第二篇。这篇总结新购的物品,及使用体验。希望将来冲动购物的时候,能够想到这篇文章,回来看看,好好想想是不是真的要买。

    (更多…)
  • FFMPEG 笔记

    FFMPEG 笔记

    截取视频

    ffmpeg -i abc.mp4 -ss 3:13 -to 2:41:13 -c copy output.mp4
    • -i 输入文件
    • -ss 开始时间
    • -to 结束时间
    • -c copy 直接截取

    这样的截取方式,如果源视频的关键帧间隙很大,可能出现因缺失第一个关键帧导致的黑屏。此时,可以考虑用 -c:v libx264 之类的参数重新编码。

    合并

    ffmpeg -f concat -safe 0 -i files.txt -c copy -y output.wav

    其中,files.txt 是所有待合并的文件,以以下的形式记录:

    file /path/to/wav/1.wav
    file /path/to/wav/2.wav
    ....

    转换格式

    转换格式很简单,有输入有输出,ffmpeg 会根据它们的扩展名自动选择合适的编码器,生成通用性最好的目标文件。比如 wav 2 mp3:

    ffmpeg -i a.wav a.mp3

    如果需要截取或者使用特定的编码器,那么就按照一般的用法添加参数即可,比如 flv 2 mp4:

    ffmpeg -i 1.flv -c:v libx264 -crf 19 -strict experimental 1.mp4

    其中,-c:v 是“视频编码器”的意思,音频编码器就是 -c:acrf 是质量,最小越好,取值范围是 18 -28。类似的,rm 2 MP4:

    ffmpeg -i ss.rm -c:v libx264 -c:a aac -b:a 32k -strict experimental ss.avi

    在 Ubuntu 下不能使用 libfaac,只能使用 aac。还要调整级别,-strict -2 不行,必须是 -strict experimental

    转换 iPad 支持的视频

    ffmpeg -i input.mkv -c:v libx264 -profile:v main -level 3.1 -preset medium -crf 23 -x264-params ref=4 -c:a copy -movflags +faststart output.mp4

    不知道为啥,直接 .mp4 或者 -c:v libx264 都不行,必须用上面这个。

    缩放

    ffmpeg -i input.mp4 -vf scale=320:-1 -strict -2 output.mp4

    好吧,这次 -strict -2 好使了。如果报错,可以试着把 -1 改成 -2

    裁剪画面

    ffmpeg -i input.mp4 -filter:v "crop=500:1080:1420:0" output.mp4

    crop 的参数为:宽、高、x、y。

    调整声音

    有些视频声音太小,需要调整一下:

    ffmpeg -i input.mp4 -filter:a "volume=N" output.mp4

    其中,N 可以是百分比,比如 1.0(一倍,不变),2.0(两倍);或者是加减的分贝,比如 10dB(增加10分贝),-20dB(减少20分贝)。不过根据我实地测试,调整后的视频的平均音量并不完全是调整的分贝。

    获取平均音量:

    ffmpeg -i input.mp4 -filter:a volumedetect -f null /dev/null 

    提取声音

    # 不转码,只提取声音,很快
    ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
    # 转码,便于四处播放
    ffmpeg -i sample.avi -q:a 0 -map a sample.mp3
  • 我的知识变现 2018:再见

    我的知识变现 2018:再见

    2017年的时候我开始尝试知识变现,然后花了大约一年的时间,发现自己其实并不适合这个领域。当然最重要仍然是经济问题:要达到我当时的生活水平,我需要投入远远不止一年的时间,而我家庭情况不允许这样做。

    2017年下半年,我幸运地找到了一份全职工作,然后开始慢慢告别知识变现 。

    2018 年年初做计划时,我仍给自己定下一些计划,包括每天在 SegmentFault 上回答一个问题。但没能坚持下来。因为很多问题并不值得回答,很多人也不会问问题。我每天在寻找合适回答的问题上都要花费很多时间。

    我后来总结,很多人其实并不适合从事开发工作。并非每个人都喜欢学习、愿意改变习惯、提升工作能力。很多人只想把这个事情当成一个工作,因为看起来,软件开发既轻松,收入又高——“总不能进工厂吧”他们说。这些人的目标是勉强满足老板/客户的需求,他们的理想是“不用工作”。

    问问题的时候,他们只想知道某某某问题的解决方案是什么,他们并不关心前因后果,也不想理清自己的思路。即使问题非常愚蠢,即使你的答案已经非常接近他们要的方案,他们也无所谓。

    这让我非常不爽,因为跟我的理想差异巨大。我喜欢写代码,想把程序员作为终身职业。我喜欢研究写代码的技巧,通过学习我能获得非常大的成就感。我也很乐意分享这些知识和技能。然而作为非专业培训人士,我很难超出自己的体验做分享,也就很难提供给他们合适的知识产品。

    所以我后来也开始慢慢转变态度。早先只要有人问问题,我都知无不言,言无不尽,做一个最好的引路人。接着我发现这样做并不好,除了浪费自己的时间,其实客观上也在浪费那些“不合适的人”的时间。所以我现在倾向于,如果我认为一个人不适合学习编程,我就早早的拒绝他(昨天就有一个人被我怼出群了……)。

    好吧,所以总结一下我的知识变现 2018:再见,知识变现。

    (更多…)