TimothyQiu's Blog

keep it simple stupid

无锡求职有感

分类:闲扯

回到无锡一年了,能让人感觉有归属感的工作始终没有找到。因为这一年间换了两份工作,所以在面试时经常被质疑人品;尽管我也尽力解释,但还是感觉不吐个槽迟早会憋出心理疾病。

阅读剩余部分...

字符编码

分类:技术,闲扯

我们平时所说的「文本」基本上都是在说「电脑屏幕上的字符」,但是小学生都知道「计算机只懂 0101」,那么电脑究竟是怎么处理三千世界中如此纷繁复杂的文字的呢?

阅读剩余部分...

各式乱码

分类:闲扯

烫烫烫与屯屯屯

这两个乱码应该是不少 C/C++ 程序员的必经之路吧。

微软 Visual C++ 的 Debug 模式下,会为未初始化的内存填充一些初始值,以便调试。其中,栈上的内存都用 0xCC 初始化、堆上的内存都用 0xCD 初始化。

而如果把 0xCCCC 作为字符输出,在简体中文的 Windows 系统下,就会根据其使用的 GBK 编码将其解释为「烫」字;0xCDCD 则为「屯」。

变巨

如果你用过南极星,说明你已经老了。

在那个万码奔腾的年代,由于早年的《曹操传》和《三国志》等游戏使用的都是 Big5 编码的文本数据,而简体中文 Windows 系统使用的编码不同于 Big5。用「前朝的剑斩本朝的官」就产生了乱码。

「变巨」的 GBK 编码为 B1E4 BEDE(GB2312 亦然),而在 Big5 编码中这四个字节对应的汉字为「曹操」。

俸俸伲购美病

这是《英雄传说VI 空之轨迹SC》简体中文版中的一句对白,也是最初被玩家讽刺得最惨的地方。

打上官方修正补丁后可以发现原文为「嘿嘿嘿,还好啦。」之所以会产生这样的乱码是因为 GBK 编码:

BA D9 BA D9 BA D9 A3 AC BB B9 BA C3 C0 B2 A1 A3 // 嘿嘿嘿,还好啦。
   D9 BA D9 BA D9 A3 AC BB B9 BA C3 C0 B2 A1    // 俸俸伲购美病

缺了第一个字节……

锟斤拷

相对前面几个乱码的直白,这个乱码是很纠结的存在。

Unicode 中定义了一个特殊字符「�」即 U+FFFD,称作 Replacement Character。用来表示无法显示的字符或是无法解析的数据。

如果一段数据本身是使用 GBK 编码的,那么其中可能有很多部分不符合 UTF-8 编码规则。一个处理 UTF-8 数据的程序得到这段数据后,可以选择将数据中检测到不合 UTF-8 编码规则的部分替换为 UTF-8 编码的 U+FFFDEFBFBD,这样,就在自动消除编码问题的同时对用户给出了数据编码错误的提示。

经过上面这步处理后,数据中就产生了很多 EFBFBD 的序列,此时如果试图以 GBK 将其解码,那么两个这样的序列就成了「锟斤拷」,即 EFBF BDEF BFBD

小试了一下 FFmpeg

分类:技术,闲扯

今天逛 Nico 的时候忽然起了搬运的念头,于是把原视频下载下来,开始进行传说中的「战渣浪」运动。在地图上到处逛搜集到如下信息:

发现不是很麻烦,懒得再去找某个版本的 MediaCoder,就直接上 FFmpeg 了……

查看文件信息

为了确定码率,首先用这样的方法查看文件信息:

ffmpeg -i <输入文件>

我从 Nico 下载视频的时候不是混杂时段,下载到的是高清 MP4 文件,于是 FFmpeg 就会输出类似这样的信息:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'filename.mp4':
  Metadata:
  Duration: 00:02:59.77, start: 0.000000, bitrate: 430 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 854x480, 315 kb/s, 30 fps, 30 tbr, 30 tbn, 60 tbc
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16, 111 kb/s

可以看出一共有 1 个输入文件,其中包含 1 条视频流和 1 条音频流。各自的码率已经可以看得很清楚了,这里该文件的平均码率没有超过 500Kbps,于是安心地进行下一步。

将 MP4 封装为 FLV

因为下载下来的是 MP4 格式文件,需要将文件(容器)换为 FLV 才能够不被新浪二压:

ffmpeg -i <输入文件> -vcodec copy -acodec copy -f flv <输出文件>

FFmpeg 的 -vcodec-acodec 选项指定了输出文件的编码器,而填入 copy 则表示直接复制,不编码。

-f 选项是用来强制指定输出格式的,虽然 FFmpeg 自己会根据输出文件的扩展名猜,但还是写一下更保险。

其它未尽事宜

于是收工上传,不久发现直接成功了 = = 呃……我记得很久很久以前我用 MediaCoder 还失败了两次呢,囧。

这次很幸运的是下载到的文件码率没有超标,如果超标的话,据说这样可以指定码率:

ffmpeg -i input.mp4 -vcodec h264 -acodec aac -b:v <视频码率> -b:a <音频码率> output.mp4

至于传说中的 h264 2-pass 压制法(用来在更好的视频质量下控制码率),据说是这样的:

ffmpeg -i input.mp4 -pass 1 -vcodec h264 -an -b:v <视频码率> -f rawvideo -y NUL
ffmpeg -i input.mp4 -pass 2 -vcodec h264 -acodec aac -b:v <视频码率> -b:a <音频码率> output.mp4

这里的第一 Pass 因为目的只是取得一个包含视频信息的 log 文件,所以用 -an 禁用音频、用 NUL(或者 /dev/null)防止视频文件生成。

至于其它用法就留待以后要用上的时候再去研究了(懒……

以上。

切换到 Typecho

分类:闲扯

呃~换到 Typecho 了 >.<

之前的 WordPress 因为 PDO (SQLite) For WordPress 插件的关系,最近一次升级后无法升级数据库结构,完全没法进后台了。折腾许久无果之后,趁国庆把整个博客转移到 Typecho 上。

鉴于原先的 WordPress 用了 PDO(SQLite) 插件,而且文章也不多,所以我还是手动迁移了数据。过程中最头大的还是 Typecho 的日期时间存放的是 Unix 时间,而 WordPress 使用的是纯文本格式。

呃……写完发现好像也没什么特别的呢……WordPress 之前有三篇草稿状态的文章,基本上也都是开始写了才发现没什么特别的,就搁置着,汗 = =