MetaSound 游戏音频实战,带程序化生成。做出成品已经到4月6日了。视频在这里:https://www.bilibili.com/video/BV1Pq421w7Eh/。这篇文章想以文字的方式记录一些要点。
文章存档 | 技术乱炖 | 二维空间 | 所思所想 | English |
|
MetaSound 游戏音频实战,带程序化生成。做出成品已经到4月6日了。视频在这里:https://www.bilibili.com/video/BV1Pq421w7Eh/。这篇文章想以文字的方式记录一些要点。
最近需要把一个视频文件容器从 MKV 转为 MP4。以前的话就直接重编码了,反正看不出来。由于近期录屏用过 OBS,知道它有一个一键转封装的功能,而且又快又好,所以想用它的。试了一下,不行。(后面通过 FFmpeg 命令行输出推测应该就是部分流无法识别。)
那就直接用 FFmpeg 吧。我对它的命令行不熟,只用过几次,需求也不大。所以这里就做个记录。
源 MKV 有9条数据流,其中流0为视频流0,流1为音频流0,流2为字幕流0,其他分别是附件流0到5。我只需要在目标 MP4 中保留视频流和音频流。命令行如下:
1 | ffmpeg -find_stream_info -i input.mkv -map 0:v:0 -map 0:a:0 -map -0:s -codec copy output.mp4 |
-find_stream_info
测试流格式。-codec copy
复制编解码信息。(因为源视频流是 H.264、音频流是 AAC-LC,MP4 也支持这些格式。)-map
指定流映射。其中可以指定负映射来删除流。上面删除字幕流等效于 -sn
。这样在输出文件中就只有一条视频流和一条音频流了。
替代数据流(alternate data stream)从 Windows 3.1 就开始正式使用了。这是 NTFS 的一项特性,ReFS 貌似有有限的支持(我没测试过)。这个功能是 Windows 识别的文件系统的可选功能,不过(常见的)实现可以认为就一种。关于它的简要介绍,微软的文档已经写得比较清晰了。
3月23日的的时候 GitHub 错误地更新了主机的 SSH 密钥。这导致基于 SSH 的 Git 操作直到本地更新密钥之前都会失效。
由于我的博客是通过 Hexo-Git 部署的,所以这次一提交,也掉坑里了。
直接 hexo d
,首先显示的是如下的错误消息(截取开头):
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
接着阅读可以发现是检测到密钥不匹配,而且开启了强制密钥验证,为了防止中间人攻击,所以就报错了。因为我以前通过 SSH 方式进行过 Git 提交,所以本地的密钥数据库(.ssh/known_hosts
)存在主机记录。所以先按那篇文章所说的,删除旧的密钥:
ssh-keygen -R github.com
执行完成后我再尝试推送,但遇到了另一个问题:
Error: Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
因为此时我还没有手工通过 SSH 方式提交,所以数据库不存在记录。为了解决这个问题,我在 GitHub 上加回了本机的私钥(忘了是什么原因没掉了,之前是2017年设置的,呜呜)。但是这个问题仍然存在。有没有能不通过 SSH 进行一次 Git 拉取/提交而刷新 SSH 密钥的方法呢?(明显,直接 SSH Shell 上 GitHub 是不可能的。)
我对 SSH 工具不熟,所以还是找了一下。根据这篇文章的指示,运行一下 ssh-keyscan
就行:
ssh-keyscan github.com
然后将输出的内容加入到 known_hosts
里面。之后就正常了。
此外,还可以通过 -F
查询主机是否已知,或用 -l
列出所有已知主机:
ssh-keygen -F github.com
ssh-keygen -l
从 Unity 2019.1 开始,Unity 提供了一个新的模块 Input System。它提供了方便的控制器切换、多控制方式可配置性、可扩展的控制器支持(例如映射虚拟控制器)等等。比起以前的 Input Manager 来说结构化了不少,不用每个游戏都自己再写一套映射系统了。关于它的基础使用我就不说了,网上在它发布不久早就有了许多教程。这篇博文要记录的是绝大多数地方都没提到的,它的“控制方案”(control schemes)的使用方法和适合场景。
昨天晚上我的笔记本,联想Y540(9750H/16G/1650,在欧洲买的)的键盘突然罢工了。我本来想重启进 BIOS 开 VT 的,然而进入 BIOS 后键盘完全无法操作,只能电源键强杀。
再次开机,发现登录界面也无法用键盘控制(包括输入)了。没办法,先用屏幕键盘凑合一下。进去后打开设备管理器,发现键盘消失了,即插即用设备倒是多了一个无法读取设备描述符的设备(错误代码 2B
)。禁用、卸载、重启数次依然如此。
由于我还有一个台式机,用的是 USB 键盘,所以先拿它来救急。我发现,在进入 BIOS 后,外置键盘是可以用的,笔记本自己的键盘倒是不行(CapsLk、NumLk 也不亮)。那么是不是固件问题呢?手动从 BHCN42WW
更新到 BHCN44WW
,键盘依然无法使用。
这时候我发现了一个有趣但无法解决问题的事实。Y540 的键盘是有背光的,使用 Fn+空格调整亮度。现在,无论是在 Windows 下还是在 BIOS 中,这个功能都是可用的。另外,我能进入 BIOS,说明至少 F2 也是在那之前好好工作了的,要不根本没法进。也就是说,键盘的硬件(电路板、键帽、排线等等)应该是没问题的,大概率是软件出了意义不明的问题。
然后在联想自己的用户论坛上找到了这么一个帖子,让人把电池耗尽再开机。我试了试,断开电源,低电量时 Windows 自动休眠了。接回电源,再开机,键盘仍然没有恢复。我觉得这个方法行不通。但是在我第二天早上重启之后,NumLk 亮起来了。再一试,登录界面有响应了。也就是说,在接入电源后,你得再重启一次,让某个固件刷某个东西才行。
后来搜索发现,联想笔记本的键盘问题发生频率不低,断电法这种让人费解的办法甚至是一些网站推荐的在换修前的最终手段。也有因为联想自己固件更新导致硬件错误(而且无法回滚)的愤怒老哥,还有其他愤怒老哥(1、2)。究竟如何,还是大家评判吧。
Methods in C# have special checks if tuples appear in their signatures. Sometimes you can see confusing compile errors due to these checks, for example, in interface implementation. Unfortunately there is no such a “formal document” that defines these behaviors. So I note them down here, which may serve as a side note until the specification follows up (or not :D).
C# 中带元组的方法,在涉及继承、接口实现等等情况时遵循特殊的规则。可惜这部分并没有一篇文档记载,于是我就先记下来,以后如果这个规则正式成文了(或没成文),本文都可以起到参考作用。
这次讲讲我是怎么得到土豆新动作的骨骼曲线表的。
在换了机器之后因为分类问题第一次更新博客。在数据迁移的时候,因为一个月前已经将源文件用 Git 管理了,所以我就没有完全复制博客文件夹里的内容,而是直接 clone 下了源文件做 deploy。当看到显示出许多的 create mode
的时候我就有一种不好的预感,一看出现了个 forced update,就知道完了。上一次删除 .deploy
导致博客的 repo 被 forced update 还是在2014年末。所以整个博客的提交记录相当于又被清零了。这次就吸取了教训,给这个 repo 也加上了提交保护。
又是一个奇怪的需求:用 Foobar2000 播放网易云音乐缓存的文件。
欢迎到作品的 Itch.io 页面去支持作者。另外这个系列目前由三个连续的故事组成:one night, hot springs、last day of spring 和本作 spring leaves no flowers。
本文内容涉及剧透,建议自行游玩后再阅读。同时,故事之间有一些关联,阅读一部或多部可能会带来不同的游戏体验。
我一开始是在 QooApp 上浏览最近发行的游戏,偶然间被标题和图标画风的某种组合给吸引了。看了简介之后我决定下载下来玩一玩。
今天看博客园,看到一篇文章。它的主要内容是:
ConcurrentHashMap<K, V>
不支持 null
值?因为这样就无法区分给定的键不存在还是对应值就是 null
。ConcurrentHashMap<K, V>
不支持 null
键?可能只是 Lea 自己的喜好——因为从逻辑上来说,允许也没有什么问题(虽然有潜在的语义错误)。文章内容不赘述了。
我看完之后想到的是,.NET 的并发容器(ConcurrentDictionary<TKey, TValue>
等等)的 API 设计和它的普通容器有着巨大的不同。把它们和这个 ConcurrentHashMap<K, V>
的坑联系在一起,可能会发现什么。
一次无可奈何的 Python 提速。
今天要做某个功能,其中我想用一个单一参数的宏,来实现基类访问。毕竟两个参数的谁都会(我故意漏掉了末尾的分号,这样强制在使用时加上分号):
#define DECLARE_CLASS(this_class, base_class) \
typedef base_class MyBase; \
typedef this_class MyClass
对于普通的类,实现起来是这个样子:
#define DECLARE_ROOT_CLASS(class_name) \
typedef class_name MyClass
#define DECLARE_CLASS(class_name) \
typedef MyClass MyBase; \
typedef class_name MyClass
使用:
class Base {
DECLARE_ROOT_CLASS(Base);
};
class Derived : public Base {
DECLARE_CLASS(Derived);
};
很明显,这样利用 typedef
的覆盖规则,省去了再抄一遍基类名称的麻烦。另外,我用了老式的 typedef
而不是更现代的 using
,这在这里只是风格问题,对语义无影响。
对于模板类,我打算如法炮制。可是,问题出现了。
我最近在写关于 GRIS 的文章。由于种种原因,现在进度只有大约三分之一,所以更新要等到之后了。不过我尽量赶在时间节点之前写完。为什么要写,简单说来,就是冲击太大了,“余音绕梁,三日不绝”。回头再看一些我所知道的玩意儿,瞬间就觉得索然无味。
如果有人关注我最近的活动的话或许会注意到,这半年来我推代码的频次相较以往同期要少。嗯,首先是 CS 确实很有意思,而且以我的基础可以看得比较全面(能自然地看见“点”之间的“线”),这样要深挖的就多多了。HTI……我的思维运转方式不是那样的,所以除了课上讲的冰山一角,基本都看不清,所以业余时间都投入到代码上了。
还有一个原因是我希望做一个更有趣的人。除了抽象的代码,我也乐于欣赏艺术创作。欣赏久了,自然就产生了投身于创作的想法。就像笼中之鸟羡慕飞翔的鸟儿一样。以我的性格,要是只能代码一条路走到黑我肯定要抹脖子了。临渊羡鱼,不如退而结网。
在B站上我之前一般是做烧笋的创作谱面;去年因为造一些轮子所以发了一些成果视频。这是我放松的一个选择。但是这毕竟形式非常单一而且(我认为)总是摆脱不了无生命感。——写谱面,在许许多多的规则之下,发挥的余地其实比较少(我不是硬核玩家),而且普遍关注的是技术难度,缺少要表达的主题。每一种艺术都不过是表达的方式,私以为代码也是这么一种手段;有的人擅长这种,有的人擅长那种,仅此而已。当然观众也得有相应的鉴赏能力。
所以我就想了,要是投入等量的时间,能让一种技能从70上升到75,或者让另一种从0上升到15,该如何选择呢?事实上这和 RPG 游戏加点一样是个一直困扰着我的难题。我选择在艺术上从0加到15,很清楚这并不会带来“一技傍身”的优势,而是希望借由将自身化为艺术创作者,去理解他们的视角和思维,会遇到什么问题,我的方案比别人差在哪里或者好在哪里。
继最开始的简单剪辑(1、2)之后,我开始尝试其他的形式:混搭(1、2)、手书(1、2)、MAD 和改谱(远算不上编曲)。每个作品的个中滋味恐怕都不是一两段话能说完的,也并不只是视频简介里的那些。当然,创作水平肯定是无法一蹴而就的。所以除了我自己的练习和体悟之外,我希望寻找更新的想法,希望它们也确实地传达给观众了。反正又不图名又不图利,若是能被欣赏,或进一步地,在此基础上衍生创作,丰富大环境,那就是更好的了。
那么近况如何呢?我确实在大脑没退化的前提下比之前更快乐了。比之前整天在代码上挖掘,望天叹气要好多了。我觉得这偶尔的音乐、绘画和视频创作是有一份功劳的。自己有趣不有趣……还不知道。至于产出的效益,那要等时间来回答。
胡乱说了一些话,权当跨(农历)年的一篇吧。
NW.js 有一个或两个上下文,使用时要多加小心。