
2月份,正是肇庆玉龙寨油菜花盛开的季节。
一大片一大片差不多有一人高的油菜花,看着就觉得精神。
沿着田垄可以步入油菜花花海之中,沉醉,宁静。
幻想着,可以漂浮在这么一片花海之上,一切都变得美好起来。
Code + Design ^ Life
2月份,正是肇庆玉龙寨油菜花盛开的季节。
一大片一大片差不多有一人高的油菜花,看着就觉得精神。
沿着田垄可以步入油菜花花海之中,沉醉,宁静。
幻想着,可以漂浮在这么一片花海之上,一切都变得美好起来。
我走的哪些弯路就不详细说了,直奔主题。曾经 mkv 如此流行,以至于好多老资源都是 mkv 格式的,在 PC 上播放没问题,但如果想直接在电视或者投屏,问题就很多了,可能编码不支持,可能字幕不显示。但对于 mp4 格式的视频,手机和电视等设备都显得友好很多。如果直接用转换工具把 mkv 转换成 mp4 的话,得到的结果是不包含字幕的,对于不擅长看生肉的人来说是很痛苦的。而对于已经包含内嵌字幕的 mkv,解决的思路是先把字幕提取出来,然后在转换的时候带上。
在此之前先说明一下,这个方案是在win上的工具来完成的。而且源视频是包含内嵌字幕的。对于没有内嵌字幕的,只能从网上找好,然后直接压制。
需要小丸工具箱。建议从官方网站下载。
如何安装请参考官方指南。打开界面如下图。
不知道每个人各自的目的地会是在哪里。
或许,我们不必知道。
因为在人生的大道上,总会有一些人会一路同行,互为同伴。
有过疑惑,也有过争执;有过沉默,也有过并肩作战。
彼此信念不同,种族不同,但不成障碍,也不成牵绊。
你我都只是匆匆过客。
好好的道一声,别了。
使用 Phantomjs 对网页进行截图,在本地运行都是好好的,但是一到服务器,首先遇到部署问题,然后是中文乱码问题,遇到中文字符就渲染成下划线 “_”。(其实不仅仅是中文,韩文什么的也是渲染不出来)。
这个问题应该不难,应该是因为服务器没有安装中文字体导致的。但难题是 alpine linux 的中文字体不太好找。网上搜了一圈,在这个 How can I use Chinese in Alpine headless chrome? 问答里找到点线索。
主要有以下两种写法(使用 Docker 进行部署的):
RUN echo @edge http://nl.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories && apk add wqy-zenhei@edge
还有这种:
RUN apk add wqy-zenhei --update-cache --repository http://nl.alpinelinux.org/alpine/edge/testing --allow-untrusted
上面两种写法我都试过了,都不行,第一种写法说找不到 @edge 的版本,第二种写法说抛了个错 BAD signature 就退出了。
反正都不行。
无奈只能继续搜索,在 alpine linux package 网站里是可以搜到这个 wqy-zenhei 的,理论上第二种写法应该是对的,但是为何始终提示 BAD signature 这个错误?重新又试了几次之后,感觉肯定有哪里出错了,难道这个 repo 里的文件是不对的?于是搜索 alpine linux 的其它 repository,还找到了,赶紧试试。
RUN apk add fontconfig mkfontscale wqy-zenhei --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing --allow-untrusted
运气真好,这个 repository 里的文件是没有问题的。然后修改了一下配置,加上 fontconfig 和 mkfontscale 两个依赖。这样,就可以在服务器愉快地渲染中文内容了,神奇的是加上这一行之后,连韩文都搞定了。一箭双雕笑。
基础环境是 alpine-node:6,要把 Phantomjs 部署到该服务器上,发现直接在 package.json 里加上 phantomjs-prebuilt 的依赖是不能运行的。
网络搜了一轮,发现是 Phantomjs 在 alpine linux 上是有问题的,找到这个 issue,尝试把下面这段加到 Dockerfile 里:
RUN apk update && apk add --no-cache fontconfig curl curl-dev && \
mkdir -p /usr/share && \
cd /usr/share \
&& curl -L https://github.com/Overbryd/docker-phantomjs-alpine/releases/download/2.11/phantomjs-alpine-x86_64.tar.bz2 | tar xj \
&& ln -s /usr/share/phantomjs/phantomjs /usr/bin/phantomjs \
&& phantomjs --version
的确在加入这段之后,它能找到 phantomjs 了,但是执行 createPage 的操作时并不返回,不清楚是不是哪个 package 里的 bug,打开 debug 之后,发现 send 事件之后是没有 receive 事件的,NOOP command 也仅仅发送一次,也就是说 phantomjs 没有收到命令,或者收到了没有反应。由于缺乏上下文,不清楚网上其它人是怎么能跑起来的,没办法,只好另寻它路。
然后搜到这个代码片段,它里面是使用了 phantomized,试了一下这段代码:
# 2: Download+Install PhantomJS, as the npm package 'phantomjs-prebuilt' won't work on alpine!
# See https://github.com/dustinblackman/phantomized
RUN set -ex \
&& apk add --no-cache --virtual .build-deps ca-certificates openssl \
&& wget -qO- "https://github.com/dustinblackman/phantomized/releases/download/2.1.1/dockerized-phantomjs.tar.gz" | tar xz -C / \
&& npm install -g phantomjs \
&& apk del .build-deps
这次终于能运行了。
今天是个好日子——1024程序员日。
豆瓣上备受好评的 《Linux C 编程一站式学习》 网上几大书店都无货了,淘宝有,但是贵,然后竟然在 Github 上找到它的在线版本 http://akaedu.github.io/book/,真心要点赞啊。
这个书还有个新版本,叫《一站式学习 C 编程》,也是无货的。具体内容我没有比较过,但是基础知识应该是差不多的。新版书名中把 Linux 去掉了,也是可以理解的,毕竟 C 不局限于 Linux,特别是现在多种平台,还有逐步升温的各式嵌入式设备,在可以 预见的未来 C 语言还将继续扛大旗。
这样看趋势还不明显,不过相信很快大家都会感受到的了。
网上找了好一轮,找到个比较像样而且足够短的 hashCode 实现,是从 Java 的 hashCode 中借鉴而得的。原理见 Java hashCode() ,也可以跟这里的 Java String 的源码 参照对比一下。
为了使用的方便,稍稍再改良了一下
function hashcode(str) { var hash = 0, i, chr, len; if (str.length === 0) return hash; for (i = 0, len = str.length; i < len; i++) { chr = str.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; // Convert to 32bit integer } return hash; } hashcode("this is a string") //-1853110172
这里接受的参数是一个 String,其它类型怎么办?可以先做一个统一的处理,比如
hashcode(JSON.stringify(obj))
序列化之后再使用 hashCode 函数,基本所有类型数据都通吃,除了含有循环嵌套的对象。
PS:
函数实现中有一行使用了 “|” 运算符,只是利用 Bitwise 运算符转换参数为 32bit,用来确保结果是个 32位整数。
通常数据库可以生成唯一的 ID,最多的就是数字序列,也有像 MongoDB 这样产生组合序列的,不过这种形式的 ID 由于是序列,是可以预测的。如果想得到不可预测且唯一的 ID,方法还是有的。
下面主要以 Node.js 的环境为例。
Github 上有个 node-uuid 项目,它可以快速地生成符合 RFC4122 规范 version 1 或者 version 4 的 UUID。
安装,既可以通过 npm install node-uuid ,也可以在 package.json 中定义。使用方式:
var uuid = require('node-uuid'); // 产生一个 v1 (基于时间的) id uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a' // 产生一个 v4 (随机) id uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1’
听起来很有保证,只是……有点太长了。
坊间也有一些在 UUID 基础上随机截取几位的办法来组成一个新的短一点的字符串,只不过唯一性就又重新成为一个问号了。
另外一个方法,来自 hashids,它的原理就是从数字经过一个加盐(salted)算法产生一个哈希(hash)字符串。这样算法就是通过混淆使结果具有不可预测性,而唯一性依然由数字本身来达成,从而得到(类似 youtube 里的)足够短,不可预测且唯一的 ID。
安装方式类似,只是 hashids 建议使用一个固定的版本。比如在 package.json 中
"dependencies": { "hashids": "0.3.3" }
使用方法也很简单。先设定一个字符串作为 salt。
var Hashids = require("hashids"), hashids = new Hashids("this is my salt”);
然后对数字(准确来说是数字数组)进行编码
var hash = hashids.encrypt(12345); // Nkk9 var hash = hashids.encrypt(683, 94108, 123, 5); // aBMswoO2UB3Sj
对数组编码可以有很有趣的用法,比如需要在一个分布式的环境里使用,可以使用机器编号 + 序列数字组合数组然后再编码。
有编码就有解码
var numbers = hashids.decrypt("NkK9”); // [12345]
编码的输出会随着数字的增大而变长,为了达到足够混淆,它可以指定最少长度。
hashids = new Hashids("this is my salt", 8); var hash = hashids.encrypt(1); // gB0NV05e
还有其它选项,比如控制输出所使用的字符,编码 MongoDB 的 ObjectId 等等。
上面介绍的两个项目,各有各优缺点,不过目的是一致的,可以根据实际情况选用。两个项目在其它语言上也有类似的实现。
国内的网络形势你懂的,要翻墙,无法是 VPN 或者 proxy。我个人还是用 proxy 比较多,浏览器里装个插件就能自动适应。但是那只是针对浏览器,命令行也很常用,遇墙就会卡着不动了。
有一个软件可以帮助你在 Command Line 里使用 proxy,叫 ProxyChains-NG (new generation)
在 Mac 上安装超简单(只要你机器上装好了 brew)
brew install proxychains-ng ==> Downloading https://downloads.sourceforge.net/project/proxychains-ng/proxychains-4.7.tar.bz2 ######################################################################## 100.0% ==> ./configure --prefix=/usr/local/Cellar/proxychains-ng/4.7 --sysconfdir=/usr/local/Cellar/proxychains-ng/4.7/etc ==> make ==> make install ==> make install-config ==> /usr/local/Cellar/proxychains-ng/4.7: 9 files, 92K, built in 10 seconds
其它平台的安装大同小异,先找找有没有一个命令能搞掂的,没有的话参考一下其文档的 Installation 部分。
然后,做一个简单配置,打开配置文件
vi /usr/local/etc/proxychains.conf
视乎你的安装方式不同,配置文件的地方略有不同,但会遵从平台的一般规范,例如在 Linux 上安装,配置文件的位置可能在 /etc/proxychains.conf
打开配置文件之后,略过前面所有,直奔最后一行,默认配置是使用 tor 的,根据你机器上 proxy 的种类配置好就可以了。常见的配置
http 127.0.0.1 8080 socks5 127.0.0.1 1080
其实上面几行就有 example ,找到合适的照抄就是了。
最后,使用也非常简单,只要在命令前面加个 proxychains4,比如
proxychains4 telnet targethost.com
PS. 还有个名字接近但更加老牌的同类软件, ProxyChains ,使用方法几乎一样。