第 58 期:代码是否越简洁抽象越好
@Author : Lewis Tian (taseikyo@gmail.com)
@Link : github.com/taseikyo
@Range : 2024-04-07 - 2024-04-13
Weekly #58
本文总字数 3991 个,阅读时长约:6 分 22 秒~12 分 43 秒,统计数据来自:算筹字数统计。

*Photo by Ulrich & Mareli Aspeling on Unsplash
不缘天上云龙会,谁解湘南𧑐蚌持? —— 刘三吾《湘南杂咏三首 其一》
Table of Contents
algorithm 🔝
review 🔝
作者介绍他使用短链的经历,在短链被重定向到真正链接之前,被广告公司设置了 cookie,而这些 cookie 能在使用其广告技术的所有其他网站上跟踪:
$ curl -v https://tinyurl.com/examplezoom
...
> GET /examplezoom HTTP/2
> Host: tinyurl.com
...
< location: https://redirect.viglink.com?key=a7e37b5f6ff1de9cb410158b1013e54a&u=https%3A%2F%2Fzoom.us%2Fj%2F123456789&prodOvrd=RAC
$ curl -v 'https://redirect.viglink.com?key=a7e37b5f6ff1de9cb410158b1013e54a&u=https%3A%2F%2Fzoom.us%2Fj%2F123456789&prodOvrd=RAC'
> GET /?key=a7e37b5f6ff1de9cb410158b1013e54a&u=https%3A%2F%2Fzoom.us%2Fj%2F123456789&prodOvrd=RAC HTTP/1.1
> Host: redirect.viglink.com
...
< Set-Cookie: vglnk.PartnerRfsh.p=; Domain=.viglink.com; Path=/; SameSite=None; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Secure
< Set-Cookie: vglnk.Agent.p=v-c935c520ecc561fe60a9418874e023b7; Domain=.viglink.com; Path=/; SameSite=None; Expires=Mon, 01 Feb 2021 16:52:34 GMT; Secure
果然是只要有盈利的地方,就有空子钻。
tip 🔝
1、问题描述
打电话的对话,被拆分成了两个 PCM 文件。其中主叫的录音文件 A.pcm,被叫的录音为 B.pcm。
问题是怎么合成一个混音的对话文件 AB.wav。
2、WAV 文件的录音格式
常见的声音文件主要有两种,分别对应于单声道(11.025KHz 采样率、8Bit 的采样值)和双声道(44.1KHz 采样率、16Bit 的采样值)。
采样率是指:声音信号在“模→数”转换过程中单位时间内采样的次数。采样值是指每一次采样周期。WAVE 文件数据块包含以脉冲编码调制(PCM)格式表示的样本。WAVE 文件是由样本组织而成的。在单声道 WAVE 文件中,声道0代表左声道,声道1代表右声道。在多声道WAVE文件中,样本是交替出现的。
WAV 文件的格式:
big
ChunkID
4
文件头标识,一般就是 "RIFF" 四个字母
ASCII 码表示的 “RIFF”。(0x52494646)
little
ChunkSize
4
整个数据文件的大小,不包括上面 ID 和 Size 本身
36+SubChunk2Size,或是 4 + (8 + SubChunk1Size) + ( 8 + SubChunk2Size ),这是整个数据块的大小(不包括 ChunkID 和 ChunkSize 的大小)
big
Format
4
一般就是 "WAVE" 四个字母
ASCII 码表示的 “WAVE”。 (0x57415645)
big
SubChunk1ID
4
格式说明块,本字段一般就是 "fmt"
新的数据块(格式信息说 明块)ASCII 码表示的 “fmt”—— 最后是一个空格。(0x666d7420)
little
SubChunk1Size
4
本数据块的大小,不包括 ID 和 Size 字段本身
本块数据的大小(对于 PCM,值为 16)。
little
AudioFormat
2
音频的格式说 明
PCM = 1 (比如,线性采样),如果是其它值的话,则可能是一些压缩形式
little
NumChannels
2
声道数
1 => 单声道
little
SampleRate
4
采样率
采样率,如 8000,44100 等值
little
ByteRate
4
比特率,每秒所需要的字节数
等于 : SampleRate * numChannels * BitsPerSample / 8
little
BlockAlign
2
数据块对齐单元
等于:NumChannels * BitsPerSample / 8
little
BitsPerSample
2
采样时模数转换的分辨率
采样分辨率 ,也就是每个样本用几位来表示,一般是 8bits 或是 16bits
big
SubChunk2ID
4
真正的声音数据块,本字段一般是 "data"
新数据块,真正的声音数据。ASCII 码表示的 “data “(0x64617461)
little
SubChunk2Size
4
本数据块的大小,不包括 ID 和 Size 字段本身
数据大小,即,其后跟着的采样数据的大小。
little
Data
N
音频的采样数据
真正的声音数据
3、查看录音的 PCM 文件
# pcm转立体声mp3
ffmpeg -i input1.pcm -i input2.pcm -filter_complex "amovie=input1.pcm [l]; amovie=input2.pcm [r]; [l] [r] amerge" output.mp3
# amr转混音amr
ffmpeg -i input1.amr -i input2.amr -filter_complex amix=inputs=2:duration=longest -ab 12.2k -ar 8000 -ac 1 output.amr
# 在后面加上 -loglevel quiet -y, 可以覆盖输出文件,避免输出日志,如:
ffmpeg -i input1.amr -i input2.amr -filter_complex amix=inputs=2:duration=longest -ab 12.2k -ar 8000 -ac 1 output.amr -loglevel quiet -y
4、测试效果
4.1、1.amr 和 2.amr 是左右声道的录音,现在合成混音 1_2.amr
ffmpeg -i 1.amr -i 2.amr -filter_complex amix=inputs=2:duration=longest:dropout_transition=2 -ab 12.2k -ar 8000 -ac 1 1_2.amr
4.2、1.wav 和 2.wav 是左右声道的录音,现在合成立体声 1_2.mp3,即左声道是 1 的声音,右声道是 2 的声音。
ffmpeg -i 1.wav -i 2.wav -filter_complex "amovie=1.wav [l]; amovie=2.wav [r]; [l] [r] amerge" 1_2.mp3
4.3、双声道的pcm转换为单声道的amr,指定编解码器
ffmpeg -y -f s16le -ar 8000 -ac 2 -i 1.pcm -acodec amr_nb -ab 12.2k -ar 8000 -ac 1 1.amr
2. 如何生成键盘输入统计看板
其实这个东西也不难,就是监听键盘的输入并保存,然后使用一个可视化框架将其可视化即可。
share 🔝
1. 代码是否越简洁抽象越好
https://overreacted.io/goodbye-clean-code/
上面的文章讲述了作者的重构代码的经历,将同时重复冗余的代码进行了精简重构,结果他老板让他把代码改回了老版本。这里就引出一个话题:代码是否越简洁抽象越好?
很显然,如果是自己维护的代码,自己知道其逻辑,当然是越简洁抽象越好的,但是作为公司的某个产品,你要知道维护这个代码的是你与你的同事,如果你高度简洁抽象,代码确实减少了,但是理解成本却大大提升了,随着人员变动,新来的同事需要去花费很多时间去理解原来的代码逻辑,从公司层面来讲,这显然是得不偿失的。即便某款产品背后是一堆屎山代码,但是它能跑,能给用户提供服务并且未出错,它就是好的不是吗?
最后更新于
这有帮助吗?