看到B站有个给win桌面加灵动岛歌词的很cool,于是想做一个差不多相同的
首先考虑的是如何获取到网易云的进度,首先想到了SMTC协议
这是一个系统级媒体接口,能获取到当前播放音频数据的元数据信息(如果软件有适配的情况下)
但经过搜索后发现网易云原生似乎并不支持SMTC,需要安装BetterNCM以及InfLink插件
但我并不想使用外置各种繁杂的框架及直接修改网易云程序,况且BNCM也已接近停更,性能方面也不太能及时完善
索性抱着试试的态度,先尝试获取一下SMTC信息,看看能不能获取到有用的东西
代码大概如下(C#)
using Windows.Media.Control;
// 获取 Session 管理器
var manager = await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
// 获取当前会话 (通常是最后活动的媒体App)
var session = manager.GetCurrentSession();
if (session != null)
{
// 获取元数据 (歌名/歌手)
var mediaProperties = await session.TryGetMediaPropertiesAsync();
Console.WriteLine($"{mediaProperties.Artist} - {mediaProperties.Title}");
// 获取进度
var timeline = session.GetTimelineProperties();
Console.WriteLine($"当前进度: {timeline.Position} / {timeline.EndTime}");
// 监听变化
session.TimelinePropertiesChanged += (sender, args) => {
var t = sender.GetTimelineProperties();
};
}
但尝试后发现无法正常获取,看来网易云开发团队确实很懒(Q音好像新版支持了
![[Pasted image 20251208195656.png]]
随后Ai给出另一个尝试,可能网易云没被正常激活?那就试一下获取全部活跃媒体
using Windows.Media.Control;
Console.WriteLine("正在扫描所有媒体会话...");
var manager = await
GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
var sessions = manager.GetSessions();
Console.WriteLine($"扫描到 {sessions.Count} 个活跃媒体应用:");
if (sessions.Count == 0) {
Console.WriteLine("❌ 真的一个都没扫到。");
}
结果自然是
![[Pasted image 20251208200251.png]]
看来SMTC这条路是走不通了
我尝试找找有没有其他的办法,好像都没有确切的方法能获取
那看来只能拿出Cheat Engine,启动!
尝试直接通过读内存的方式来实现这一功能(简单暴力属于是)
首先是扫描获取当前歌曲的进度数值,也就是播放到了哪一秒
但我不确定网易云是使用的哪种数据类型来存放,可能是秒,也可能是毫秒,或者Double等等
首先从最能保险的方式开始扫,把歌曲调整到00:00,首次扫描
![[Pasted image 20251208200817.png]]
可以看到有1000w个扫描数值,接下来就是层层筛选
这里我首先使用的是绝对数值(假设他是使用的秒)
先把歌曲调整到00:10,然后搜索新的数值10
![[Pasted image 20251208200943.png]]
结果直接缩减到22,再次进行筛选,往后推
![[Pasted image 20251208201021.png]]
看来第一步猜测失败,他并没有直接使用秒存储,那就尝试Plan B,使用毫秒
但是对于这种只能显示到秒精度的播放器,我无法知道确切的毫秒数值,只能使用增大/减少的数值来找出哪些出现了变化
![[Pasted image 20251208201248.png]]
依次循环进行这个过程 往后拉进度条->再次扫描->往后拉进度条->再次扫描
当然只扫描增大的可能很浪费时间,因为有些无关数值他就是会不停增大
可以随机反向多推一些 往前拉->减少的数值->再次扫描
这样往返多筛选几次,最后得到了以下几个
![[Pasted image 20251208201730.png]]
此时很显而易见了,当前歌曲进度是00:54,而地址列表里有五个类似的数值,看来是毫秒没错了
然后是点击播放音乐,这些地址的数值也会跟着变动,音乐停他们就停,基本确定了
接下来就是确定UI层和实际逻辑层的地址,将五个地址进行分别更改,查看哪个可以变动到实际的音乐进度
![[Pasted image 20251208201914.png]]
找到了,25593767568这个地址就是实际音乐进度的
但我发现一个问题,这个地址可以更改音乐进度,但点击播放时,他没有随实时进度更新,他只在用户手动拖动进度条时更新,那就没法用了,但可以保留这个地址,作为调整进度使用
![[Pasted image 20251208202427.png]]
那也就是说这个地址实际上是UI 控件的定位值,而不是音频引擎的播放时钟
经过资料查找和Ai分析,选择了更换搜索类型,以Double方式查找
在网易云(基于 Chromium/CEF)这种架构里,以及大多数音频库(如 FFmpeg, BASS)中,实时时间戳通常是 Double (双精度浮点数) 类型,单位是 秒
然后我就试着变换思路,选择双浮点查找
![[Pasted image 20251208202915.png]]
再次经过各种筛选,最后得出了以下这个地址
![[Pasted image 20251208213359.png]]
碰巧也是静态地址,不用找偏移值确定实际地址,只要网易云不更新,这个地址就可以一直用
结果很顺利,一切正常,重启网易云后也能正常继续实时读取
![[Pasted image 20251208213920.png]]
接下来是扩展一个写(控制进度)也就是上面提到的可控制地址
因为那个是动态地址,如果程序退出后再启动,实际地址会发生变化,需要计算偏移值,得出实际通向这个的地址
此时需要重新进行刚才的扫描步骤,然后拿到控制地址1734FC13228
![[Pasted image 20251208214647.png]]
双击地址添加到下面的地址列表,右键 - 生成 指针映射集
保存后再次右键,对该地址进行指针扫描,选择使用保存的指针映射集,选择刚刚保存的映射集
![[Pasted image 20251208215356.png]]
保存到同目录下,然后就得到了几个基址+偏移值
![[Pasted image 20251208215655.png]]
如果列表有很多不相关的(查看右侧指针是否数值对应实际数值,显示空或不对应则直接排除)
这个过程可以多次重复尝试,不要关闭指针扫描器窗口,重启网易云,重新按上面步骤找地址,找到后进行进一步重新扫描查找筛选,多次筛选后即可得到
![[Pasted image 20251208215930.png]]