-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathget_data.html
154 lines (119 loc) · 6.46 KB
/
get_data.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BeatSaver Recognization</title>
<script src="https://gildas-lormeau.github.io/zip.js/demos/lib/zip.min.js"></script>
</head>
<body>
<a href="https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf/related?hl=en">安装跨域插件</a>
<div id="results_dom"></div>
<script src="sandbox.bundle.js"></script>
<script>
function similar(s, t, f) { if (!s || !t) { return 0 } var l = s.length > t.length ? s.length : t.length
var n = s.length
var m = t.length
var d = []
f = f || 3
var min = function (a, b, c) { return a < b ? (a < c ? a : c) : (b < c ? b : c) }
var i, j, si, tj, cost
if (n === 0) return m
if (m === 0) return n
for (i = 0; i <= n; i++) { d[i] = []
d[i][0] = i } for (j = 0; j <= m; j++) { d[0][j] = j } for (i = 1; i <= n; i++) { si = s.charAt(i - 1)
for (j = 1; j <= m; j++) { tj = t.charAt(j - 1)
if (si === tj) { cost = 0 } else { cost = 1 } d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost) } } let res = (1 - d[n][m] / l); return res }
let results = localStorage["results"] || "[]"
results = JSON.parse(results)
updateResults()
function updateResults() {
console.log(results.reduce((p, c) => p + (c.match.result ? 1 : 0), 0), results.length)
results_dom.innerHTML = `目前匹配成功率:${(results.reduce((p, c) => p + (c.match.result ? 1 : 0), 0) / results.length * 100).toFixed(3)}%<br>结果:\n${results.map(v => {
if (v.match.result == null) return `<div class='song'><span class="name">${v.saver.name}</span><span class="result"><bold>匹配失败。</bold></span></div>`
return `<div class='song'><span class="name">${v.saver.name}</span><span class="result"><bold>匹配成功:${v.match.result[0].song.name}</bold></span></div>`
}).join("")}`;
localStorage["results"] = JSON.stringify(results)
}
// throw Error("stopppp")
function toNCMBuffer(audiodata, from, len) {
let now = 0;
let json = {}
let buf = audiodata.getChannelData(1)
while (now < len * 8e3) {
json[now] = buf[now * audiodata.sampleRate / 8e3 + from * audiodata.sampleRate];
now += 1;
}
return json;
}
async function getMatches(rawdata, length) {
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
// myHeaders.append("Cookie", "NMTID=00OX5XnP2Lye8FNsU-Kv9N8jeXqYWAAAAGBh-ODmw");
var urlencoded = new URLSearchParams();
urlencoded.append("duration", length);
urlencoded.append("times", "2");
urlencoded.append("decrypt", "1");
urlencoded.append("rawdata", rawdata);
urlencoded.append("algorithmCode", "shazam_v2");
urlencoded.append("sessionId", "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
return await (await fetch("https://interface.music.163.com/api/music/audio/match", requestOptions)).json()
}
function timeout(ms) {
return new Promise((rs) => {
setTimeout(() => { rs() }, ms);
})
}
localStorage["lastPage"] ||= "1";
!(async function () {
while (1) {
let songs = await (await fetch(`https://beatsaver.com/api/search/text/${localStorage["lastPage"]}?sortOrder=Latest`)).json()
for (let song of songs.docs) {
let { previewURL, downloadURL } = song.versions[0];
let buffer = await (await fetch(previewURL)).arrayBuffer()
let mapBlob = await (await fetch(downloadURL)).blob()
let reader = new zip.BlobReader(mapBlob)
let rzip = new zip.ZipReader(reader)
let infodat = (await rzip.getEntries()).filter(v => v.filename.toLowerCase() == "info.dat")[0]
let info = JSON.parse(await infodat.getData(new zip.TextWriter()));
let songfile = (await rzip.getEntries()).filter(v => v.filename.endsWith(info._songFilename.split(".").pop()))[0]
let songdata = await songfile.getData(new zip.BlobWriter());
const audioCtx = new AudioContext();
let data = await audioCtx.decodeAudioData(await songdata.arrayBuffer())
let secs = 4
let matches = { data: {} };
let now_opt = 0, similarity = -1;
while ((secs + 20) < data.duration && similarity <0.6) {
let _matches = await getMatches(NeteaseRecordArrayToBase64(toNCMBuffer(data, secs, 6)), 6)
console.log("attempt " + secs)
if (_matches.data.result) {
matches=_matches
let namea=matches.data.result[0].song.name,nameb=info._songName
namea=namea.toLowerCase().replace(/[\[,(,\(].*?[\),),\]]/g,"").replace(/\s/g,"");
nameb=nameb.toLowerCase().replace(/[\[,(,\(].*?[\),),\]]/g,"").replace(/\s/g,"");
similarity = similar(namea,nameb);
if(namea.includes(nameb)||nameb.includes(namea))similarity=1;
console.log(`Name similarity ${similarity} ["${namea}","${nameb}"]`)
}
secs += 30
await timeout(1000)
}
results.push({
saver: song,
match: matches.data
})
updateResults()
}
localStorage["lastPage"] = parseInt(localStorage["lastPage"]) + 1
}
})()
</script>
</body>
</html>