Skip to content

Streaming | Callback | 2024 Q3

Posted on:2024.09.30

TOC

Open TOC

Streaming

背景 & 基础

这里的 Streaming 指串流,指通过网络将服务端上的画面 (包括音视频) 流式传输到客户端上。之所以最近在研究串流方案,是因为在 T 大读研之前,我自己配置了一台高性能主机,但是笔记本仍然使用的是四年前的老古董。考虑到在 T 大偶尔会有去实验室露个头 or 去教学楼上个课的需求,但是老笔记本的离电续航只有不到两个小时,性能更是无话可说,这就意味着在笔记本电量耗尽后我就只能看📱摸鱼了,这显然是不可接受的。于是需求明确如下:

  1. 在宿舍外校园内的场景下,希望能够获得近似于台式机的性能进行开发,同时续航能够说的过去
  2. 在假期回家的场景下,考虑到台式机太过笨重 (并不想来回搬运),希望能够获得一定的游戏性能以供娱乐

在入学前,我大概拟定了三个方案:

  1. 购置全能本 (有独显),对老笔记本进行同定位升级
  2. 购置轻薄本 (无独显, but with OCuLink 接口),通过串流满足需求 ①,通过外置显卡坞满足需求 ②
  3. 舍弃需求 ②,购置平板进行串流满足需求 ①

在入学后,由于个人财力不足,并没有闲钱购置新的设备,于是只能在既有的设备上进行探索,也就是通过老笔记本和老平板进行串流。对于串流方案,我选择了 Sunshine + Moonlight 的方案,原因是开源免费,且延迟低效果好。对于这个方案的教程强烈推荐这个视频,如果看完了这个视频,Streaming 这一大节后面的内容也就不用看了🔜

远程控制

在服务端上行速率和客户端下行速率都充足的情况下,Sunshine + Moonlight 的串流方案实现了客户端远程控制服务端的功能,这完全可以满足上一节中的需求 ①,甚至是需求 ②,对于一些延迟不敏感的游戏而言。简而言之,这个方案包含下述几个步骤:

  1. 在服务端 (台式机) 上安装 Sunshine
  2. 在客户端 (笔记本 or 平板) 上安装 Moonlight
  3. 在 Moonlight 中输入服务端 IP 地址 (如果在一个局域网内应该会自动识别到) 并尝试🔗

  1. 在 Sunshine 中配对 (仅客户端第一次🔗需要)

  1. Enjoy~

在默认配置下,上述流程已经可以 works 了,如果在🔗过程中出现报错,且服务端是独显 + 集显的配置,记得要禁用掉集成显卡。为了获得更好的体验,建议将服务端和客户端的分辨率配置为一致的,例如我的 Apple iPad (9.7-inch, 2017) 分辨率是 2048 × 1536,服务端需要在 Sunshine 中 Configuration - Audio/Video - Advertised Resolutions 中添加客户端的分辨率,客户端则需要在 Moonlight 中设置串流分辨率。

副屏

由于 T 大宿舍的桌子下面塞不进去我的台式机,导致我的台式机只能放在桌面上,进而侵占了原本就不大的桌面面积。经过测量和计算,在不拆除挡板的前提下,是无论如何也放不下两台 24 寸的显示器的,于是现在我只能对着一台显示器码字,效率⏬⏬⏬。这个时候,串流方案可以使得客户端 (某个 15.6 寸的笔记本和某个 9.7 寸的平板) 作为服务端的副屏,只需在上一节的步骤前面配置 Virtual Display + Sunshine 即可:

  1. 安装 parsec-vdd 并添加虚拟显示器,分辨率与客户端一致

  1. 获取虚拟显示器编号,并在 Sunshine 中 Configuration - Audio/Video - Output Name 中配置

  1. 后续流程同上

这样就可以在系统设置中配置虚拟显示器的位置关系,并作为副屏使用了~

客户端

由于 Sunshine 和 Moonlight 都开源了,所以民间有很多的魔改版本,这里不做过多推荐,仅推荐一个 Moonlight 的第三方版本,主要的使用场景是对于客户端触控屏设备 (例如平板),可以支持多点触控。

这就很有意思了,在无线鼠标和无线键盘作为设备输入的基础上,还可以通过点击屏幕的方式操控服务端,例如单击、拖动屏幕、双指缩放等,大大增加了可玩性🛝

任务计划程序 + 飞书 Robot

前文提到,在客户端第一次🔗服务端的时候,需要在服务端上显式进行配对操作,此后客户端可以直接🔗服务端,这个前提是服务端的 IP 地址在配对后不发生变化。由于 T 大校园网的某些特性,在 offline 一段时间后重新连接到校园网,有概率获得到一个新的 IP 地址,此时如果客户端 Moonlight 保存的还是之前的服务端 IP 地址,就需要重新输入 IP 地址进行🔗 (无需在服务端上进行配对)。

由于上述机制,有可能出现下述情形:

  1. 前一天客户端🔗服务端
  2. 服务端 offline
  3. 第二天服务端 online,得到了一个新的 IP 地址
  4. 客户端再次🔗服务端,假如此时不在宿舍,就无法直接获取到服务端的 IP 地址 (理论上可以通过登录校园网后台获取,但这太麻烦了…)

因此需求就很明确了,在服务端 online 时,主动将其 IP 地址发送到一个便于获取的地方,例如某些即时通讯软件,最后的方案如下:

  1. 在服务端配置任务计划程序,在解锁时且网络连接可用后,执行 bat 脚本

  1. bat 脚本如下,通过 cip.cc 解析本地 IP 地址,并将其发送给飞书机器人
Terminal window
@echo off
:: 获取 IP 地址信息
for /f "tokens=2 delims=: " %%A in ('curl cip.cc ^| findstr "IP"') do set IP=%%A
:: 去掉 IP 地址前后的空格
set IP=%IP: =%
:: 使用 curl 发送 POST 请求,将 IP 地址发送到飞书机器人
curl -X POST -H "Content-Type: application/json" ^
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"%IP%\"}}" ^
https://open.feishu.cn/open-apis/bot/v2/hook/xxx
:: 开机时自动执行的脚本会执行完毕后自动关闭
exit

最后的效果如下🌫️

麦克风串流

回顾串流的概念,串流会将服务端上的画面 (包括音视频) 流式传输到客户端上,服务端传递给客户端的包括视频和音频信息,客户端传递给服务端的主要是外设的输入信息,但是 Moonlight 似乎并不原生支持麦克风作为输入。

考虑下述需求,我希望能够将老师授课时的声音即时传输给服务端,并在服务端上通过 Whisper 生成文本 (STT),基于生成的文本进行后续操作 (例如总结、对话等)。这里就需要实现麦克风串流的能力,我选择的方案是 AudioRelay,大概流程就是在服务端和客户端上安装 AudioRelay,服务端设置虚拟麦克风,监听客户端的麦克风输入。由于客户端可以通过串流远程控制服务端,所以上述过程可以在远程完成。

Callback

此处的 callback,大概是一种这样的行事逻辑,即『某个事件发生后一定会做某些事情』,类比计算机科学中的触发器 or 回调函数。这里强调两点,一是必然性,即一定会 do something;二是非平凡性,即不是简单的例如听到闹钟后起床之类的回调。这个 quarter 集中遇到了一些我觉得非平凡的 callbacks,由于没有笔力将其串起来写,故分点一一阐述。

Black Myth: Wukong

这个 callback 注册在四年前的暑假,在我的第一篇所谓的 essay 中,描述黑猴为『国产单机游戏之光』,如今这光已经切实照在了全球游戏玩家的身上。与我而言,黑猴最大的意义是给我打上了某种思想钢印,即多活几年就能等到黑猴发售了,于是这路上的艰险便不再会对我造成『真实伤害』。

艰险斗罢,无问西东,四年后的我确实以不可预料的状态迎来了黑猴的发售,指自己生出来的主机 + 提前配合好的手柄 + 赶着发售日的 T 大开学。依稀记得黑猴发售当日,我在几乎全程 woc 的心境下中通关了第一章,却因为开学的准备不敢留恋于后续的章节。开学后,我的注意力又大量放在了为 T 大祛魅上,加之实验室日常开发任务繁重,少有时间和精力投入在黑猴上。如今一月有余,我还堪堪在第四章迷路,给黑猴拉低通关率真是抱歉哈…

君の名は。

这个 callback 注册在八年前君名刚上映时,因为种种原因未能在电影院观看的我,此后一直默默期待着君名的重映,这一等便是八年。八年,我等来了君名的蓝光碟,等来了君名的 OST,等来了新海诚灾难三部曲的后两部,最终等到了君名的重映。

在八年前,君名对我的冲击力还是相当之大的,这里的冲击力指完结空虚综合症,仿佛心中某个地方空荡荡的,君名首次给我带来了这种感受。我依稀记得,当时我在很短的时间内反复观看了近十遍,在纸上理时间线,在网上找细节帖,还有那张经典的壁纸。那时的我还没掌握通过转移注意力的方式缓解完结空虚综合症,因而一头扎进了情感漩涡中。

在八年后,在电影院听完片尾曲『没什么大不了』后,我不忍离席,并不由感叹,即使在今天,君名也是属于最优秀的那一档 anime movie 之列,无可挑剔的画面、印象深刻的配乐、引人入胜的剧情。在精神拔节孕穗的人生阶段,能够欣赏到这样的作品,我觉得是一种莫大的幸运。

DEEMO II

这个 callback 注册在十年前,此处的十年是约数,因为记不太清楚入坑 DEEMO 的确切时间了,不过可以说,DEEMO 大抵是我第一款入坑的可以被视作正规军的移动端音乐游戏。我并不知道在十年前,出于什么契机,我下载这款大小超过一个 gigabyte 的 (伪) 付费游戏。从未来的视角来看,我想当时的我一定认为 DEEMO 是一款小众高难度游戏,可以很好的满足我的求异心理。殊不知,这种现在看来很好笑的理由,却导致我真正沉迷上了 DEEMO,以至于后来真正入了音游的大🕳️。

十年后,DEEMO II 国服发售,我久违的又体验到了这种心流状态。在花费了半个中秋假期打通了其主线剧情后,我依然觉得 DEEMO 仍然是经典中的经典,但 DEEMO II 是更加现代的 alternative。尽管 DEEMO II 在总体设计上不如 DEEMO 洗练,但美术和玩法上是一脉相承的,难度对萌新也更加友好 (指金色音符)。最后点名表扬 DEEMO II 的优化,在我 17 年的老 iPad 上依然有不错的游玩体验,这下又没有换新 iPad 的动力了…

いせかい

anime

简单记一下对今年七月新番的观感,可以总结为今年『吃』的最好的一个季度。这里着重聊一下败犬女主义妹生活,前者是近几年来现象级的校园题材轻改动画,后者是本季度低预算下观感极佳的文艺作品。

先说前者,败犬女主几乎全程满足了我对其的期待,从 PV1 作画的初见端倪,到 PV2 极佳的摄影、音乐、氛围呈现,还没开播前几乎就可以开🍾了。开播后的第一集果然不负所望,并且这种上头感几乎持续到了最后一集,这就是全力的 A1。前期我观看败犬女主的状态 be like: 看生放送 -> 看巴哈的熟肉 -> 看评论、切片和各种 reaction -> 戒断状态 (sleep) -> 看周六泛大将军解析 -> 无缝衔接生放送 -> … (loop)。诚然,败犬女主的综合制作水平是极高的,但更重要的是其对文艺作品的演绎方式基本上就在我的好球区内,这里不得不提其以弦乐 (钢琴 + 小提琴) 为主的 OST,很多名场面氛围感的营造我觉得 BGM 功不可没:

以及 OP 和三首个人 ED 我都很喜欢。总之对我而言,败犬女主基本上是一部找不出什么槽点的动画,至于社区对于所谓『青春感』的讨论,反正我是看爽了,理性分析就是理性不能。

如果败犬女主是一部可以随时安利给别人的本季度代表动画,义妹生活则与之完全相反,我估计超过 90% 的安利都会以失败告终,更具体的,如果能『看进去』这部动画的第一集,安利就应该成功了。说到底,义妹生活是那一种极其挑受众的作品,如果无法与平淡叙事下的男女主人公共情,那么这部动画在观感上一定是相当无聊的;反之,即使顶着作画资源匮乏的 debuff,单单去感受很多空镜头象征的心理活动,就足以在之后拍案叫绝。从这个角度看,可以把义妹生活定位成一部低成本的文艺片,它有很多短板,但是长板足够长,以至于可以忽略这些短板,这里的长板主要有两个,一是摄影,二是音乐。

对于摄影,这里便不得不提义妹生活的监督,在极其有限的资源下利用摄影做出了文艺片的质感。摄影可以简单理解为,将各个环节的素材组合成最终的影像内容,其中适时给予运镜、光效、特效等。在义妹生活中,男女主的各自视角、过去与现在、想象与现实,是通过不同的摄影方式呈现的,如胶片、老电视机、铅笔等,集大成的便是本片的第 9 集。对于音乐,我觉得本片的 main theme 是严格不弱于败犬女主的,下一个问题便是义妹生活的 OST 究竟何时发售,我很急…

aigc

谈及今年上半年配置主机时为什么显卡最终选择了 4070 TIS,其中有一些生产力相关的考虑,16GB 的显存可以让我在本地顺利推理经过 Q5_K_M 量化后 14B 参数的模型。这似乎有先射箭再画靶的嫌疑,待我从头开始说起。

其实我搞 aigc 的目的,说单纯确实单纯,说不单纯也确实不单纯。最开始也是最主要的需求是做生肉的翻译,包括各种音声、番剧、漫画等,翻译的输入无非两种,源语言的文本或音频:

由于需求很简单,上述工作流还是比较清晰的,同时运行 text-generation-webui 和 manga-image-translator 可以狠狠榨干我的 4070 TIS,让我非常愉悦。

TODO

小作文没时间写了,等 Q4 一起写😵‍💫