重磅!python获取同步输出的桌面网易云音乐歌词(内存偏移获取)

您所在的位置:网站首页 网易云音乐歌词在哪找 重磅!python获取同步输出的桌面网易云音乐歌词(内存偏移获取)

重磅!python获取同步输出的桌面网易云音乐歌词(内存偏移获取)

2024-02-18 09:12| 来源: 网络整理| 查看: 265

最喜欢研究跟音乐相关的东西了,就像有的人爱喝酒吗,我离不开音乐,撸代码的时候,来点音乐,状态飙升,就跟晚上有人喜欢自己买点花生米小酌一下。 一直想做一个歌词输出的屏幕,心里暗暗合计了好一阵了,无非大致有如下几种思路: 一、买个副屏,显卡可识别的那种,然后把显示歌词的小窗拖过去即可,这种方法最简单,但是成本较高; 二、自己做个音乐播放器,就可以随便想怎么输出歌词了,这种方法工作量太大,需要自己用pyqt写个音乐播放器,我又有强迫症,界面太丑不干,得花费好一阵; 三、想办法获取电脑桌面歌词,输出到单片机,这种方法比较好,但是技术要求高一些,还是想采用这种方法。 如何获取电脑屏幕上的歌词呢? 最先想到的,截图,然后获取直接OCR。。。太笨而且费资源,然后看到python其实可以操作内存,有人用python写了植物大战僵尸的修改器,受到启发,直接通过查找内存找到歌词,然后随便怎么输出都行了。 奥里给,开始干,没想到网上有用的资料太少,然后自己汇编、内存了解的比较少,这一做就是一整天,好在终于搞定了。

首先,任何数据都在内存里,最直观的就是游戏数据,血量,金钱之类的,小时候应该很多人都用过金山游侠修改数据,就是那套原理,那么歌词作为文本,也是数据,为啥我不找找呢,于是搞了个CE打法,先显示英文的歌词,一直查找第一位字母的ASCII码,果然找到了,歌词不是什么敏感数据,一般也不会加密之类的,所以很典型很顺畅的找到了。

然后,网上教程说用OD去找偏移量,其实CE也可以搞定,一顿顺腾摸瓜,最最最重要的偏移量他来了,上图: 在这里插入图片描述 可以很清楚看到实时显示歌词的地址是怎么来的,从cloudmusic.dll的基址开始,经过三次偏移得道,当然最后一次是0,可以不用算。 原理知道了,愣着干嘛,一顿操作如虎,搞定了,这里,网易云音乐歌词的规则也被我看出来了,每个字,不管是英文还是中文,都占用两个bytes,中文用的是unicode编码,两个字符高低位反过来,如原来是\x34\x12就变成u1234,就行了,这里网上居然没找到现成的转换方式,网上找点有点的东西是真的费劲。。。于是自己手动写了坨屎山,转换了。英文就是\x00接ascii吗,如果遇到连续两个\x00\x00视为词句歌词结束,现在规则全看不透了,搞定。 在这里插入图片描述 这样就做好了,感觉干了件大事,网上没有相关资料代码,全靠自己摸索哦 上代码:

#2022-10-15 by jd3096 vx:jd3096 import pymem import time import socket import win32process from win32con import PROCESS_ALL_ACCESS import win32api import ctypes from win32gui import FindWindow def GetProcssID(address,bufflength): pid = ctypes.c_ulong() kernel32 = ctypes.windll.LoadLibrary("kernel32.dll") hwnd = FindWindow("DesktopLyrics", u"桌面歌词")#获取窗口句柄 hpid, pid = win32process.GetWindowThreadProcessId(hwnd)#获取窗口ID hProcess = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)#获取进程句柄 ReadProcessMemory = kernel32.ReadProcessMemory addr = ctypes.c_ulong() ReadProcessMemory(int(hProcess), address, ctypes.byref(addr), bufflength, None)#读内存 win32api.CloseHandle(hProcess)#关闭句柄 return addr.value def Get_moduladdr(dll): #找到dll的内存基址 modules = list(Game.list_modules()) for module in modules: if module.name == dll: Moduladdr = module.lpBaseOfDll return Moduladdr def get_add(): #从基址加偏移量反复三次得到实际内存地址 Char_Modlue = Get_moduladdr("cloudmusic.dll") addr = GetProcssID((Char_Modlue + 0xAF7C44),4) ret = addr + 0xc8 ret2 = GetProcssID(ret, 4) ret3 = ret2 + 0x14 ret4 = GetProcssID(ret3, 4) print (hex(ret4)) return ret4 Game = pymem.Pymem("cloudmusic.exe") lyrics_addr=get_add()#实际内存地址 lyrics_len=200 last_lyrics=b'' def B2Q(uchar): """单个字符 半角转全角""" inside_code = ord(uchar) if inside_code < 0x0020 or inside_code > 0x7e: # 不是半角字符就返回原来的字符 return uchar if inside_code == 0x0020: # 除了空格其他的全角半角的公式为: 半角 = 全角 - 0xfee0 inside_code = 0x3000 else: inside_code += 0xfee0 return chr(inside_code) def stringB2Q(ustring): """把字符串强行全角""" return "".join([B2Q(uchar) for uchar in ustring]) def b2u(b): #bytes转unicode方法 我感觉应该有现成的函数,就是找不到好气,只能写了坨屎山凑合用 length=len(b) sr='' for i in range(0,length,2): b0=hex(b[i]) b1=hex(b[i+1]) if b0=='0x0': #第一位如果是0说明不是中文,中文占2bytes s1=chr(b[i+1]) sr+=s1 else: if len(b0)==4: s0=str(b0[2:4]) else: s0='0'+str(b0[3]) if len(b1)==4: s1=str(b1[2:4]) else: s1='0'+str(b1[2]) s=s0+s1 result=b'\x5c\x75' for ss in s: bb=ss.encode() result+=bb sr+=result.decode("unicode_escape") return sr def get_lyrics(): global last_lyrics raw_bytes=Game.read_bytes(lyrics_addr,lyrics_len) use_bytes=raw_bytes.split(b'\x00\x00')[0] if len(use_bytes)%2==1: use_bytes+=b'\x00' lyrics_bytes=b'' for i in range(0,lyrics_len,2): #构建bytes 这里高低位需要调换一下顺序 b1=use_bytes[i:i+1] b2=use_bytes[i+1:i+2] lyrics_bytes+=b2+b1 if last_lyrics!=lyrics_bytes: #检查看词是否变化 last_lyrics=lyrics_bytes return b2u(lyrics_bytes) else: return None def sendto(lyric): quan=stringB2Q(lyric) data=quan.encode('gbk') return data # tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) # tcp_server.bind(("", 30960)) # tcp_server.listen(5) # tcp_client, tcp_client_address= tcp_server.accept() while True: lyrics=get_lyrics() if lyrics!=None: print(lyrics) data_send=sendto(lyrics) #tcp_client.send(data_send) time.sleep(0.1)

中间注释的部分就是可以通过tcp发送歌词数据到任意单片机上,老本行回归,也可以用串口,随便发挥,上俩做好的图: K210 K210 FFT加歌词输出 在这里插入图片描述 之前提到的中景园oled带字库那个屏幕,用TCP实现。

这次真的是爽爆了,完全实时同步,随便切歌,拉进度,歌词永远同步。 不过没有彻底完善,比如遇到日文韩文等显示不了,英文强行被我转GBK,很占地方,这个看心情再说吧哈哈哈,懂原理了什么时候解决都不急。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3