接上回Deemo提取MIDI,今天Deemo2终于可以玩了!

然后翻了一下Deemo2跟Deemo1的“钢琴音”部分是几乎完全一样的,就是说可以用几乎同样的方法提取它的MIDI轨,稍微改了下代码,又水一篇帖子。
与上次(没看过的应该先康康,比如MIDIUtil该怎么修,逃)有两点不同,
一个是谱面资源不是放apk里的,就是游戏安装完后还需要先把那2G的资源下载,然后手机插电脑,复制Android/com.rayark.deemo2/files所有文件(当然,你知道该复制哪些的话也可以不用全复制:),然后用AssetStudio打开提取其中的TextAsset文件(同建议全提取,除非你知道哪些是要提取的:),然后看到的那堆***.easy/normal/hard.json的文件就是谱面文件。
另一个是这次的sounds里面不知道为什么有null的,所以要加个if把它提出。
最后代码:(记得改RESULT_DIR和JSON_DIR的路径,其实和上次的几乎一样的,懒得优化了,逃)
import json
from midiutil.MidiFile import MIDIFile
import numpy as np
import os
import pandas as pd
RESULT_DIR = 'path\\to\\your\\result_dir'
JSON_DIR = 'path\\to\\your\\asset_exported_dir\\TextAsset\\'
# get file name
tmp = []
for _,_,f in os.walk(JSON_DIR):
    tmp = f
files = []
for t in tmp:
    if 'hard' in t:
        files.append(t)
#print(files)
# run
werrors = []
jerrors = []
for name in files:
    print('starting -> '+name)
    # get notes in file
    try:
        with open(JSON_DIR+name,'r') as f:
            datas = json.loads(f.read())
    except:
        jerrors.append(name)
        print('get json error -> '+name)
        print('------------------')
        continue
    speed = datas['speed']
    #print(speed)
    #print(list(datas))
    notes = datas['notes']
    #print(list(notes[0]))
    sounds = []
    for n in notes:
        try:
            try:
                t = n['_time']
            except:
                t = 0
            if n['sounds'] != None:
                for s in n['sounds']:
                    sounds.append({'d':s['d'],'p':s['p'],'v':s['v'],'t':t})
        except KeyError:
            #print('!')
            None
    #print(len(sounds))
    #print(list(notes[0]['sounds'][0]))
    try:
        start = sounds[0]['t']
        for s in sounds:
            s['t'] -= start
    except:
        None
    # get bpm
    times = []
    for s in sounds:
        #if s['p']<50:
        times.append(s['t'])
    #times = [s['t'] for s in sounds]
    if(len(times)<2):
        bpm = 60
    else:
        dt = []
        for i in range(len(times))[1:]:
            r = times[i]-times[i-1]
            if r != 0:
                dt.append(r)
        gm = pd.Series(data=dt)
        bpm = 60/gm.mode()[0]
        while(bpm>200):
            bpm /= 2
        while(bpm<60):
            bpm *= 2
    bpm = round(bpm)
    #bpm = int(bpm)
    print('bpm -> '+str(bpm))
    # write midi
    MyMIDI = MIDIFile(1)
    track = 0  
    time = 0
    bias = float(bpm/60)
    # Add track name and tempo.
    MyMIDI.addTrackName(track,time,name+'_deemo')
    MyMIDI.addTempo(track,time,bpm)
    for s in sounds:
        MyMIDI.addNote(0,0,s['p'],s['t']*bias,s['d']*bias,s['v'])
    # And write it to disk.
    try:
        binfile = open(RESULT_DIR + name.split('.')[0]+'.mid', 'wb')
        MyMIDI.writeFile(binfile)
        binfile.close()
    except:
        werrors.append(name)
        print('write file error -> '+name)
        #continue
    #print('finished -> '+name)
    print('------------------')
print('json_errors:')
for e in jerrors:
    print(e)
print('write_error:')
for e in werrors:
    print(e)
附:996(Doge
