Skip to content

Commit 73959b2

Browse files
committed
feat: 导入谱面时,支持maidata中的&demo_seek和&demo_len
1 parent 10f63d1 commit 73959b2

6 files changed

Lines changed: 28 additions & 9 deletions

File tree

MaiChartManager/Controllers/Charts/ImportChartController.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Text.RegularExpressions;
2+
using MaiChartManager.Controllers.Music;
23
using MaiChartManager.Services;
34
using Microsoft.AspNetCore.Mvc;
45
using SimaiSharp;
@@ -11,7 +12,7 @@ namespace MaiChartManager.Controllers.Charts;
1112
public class ImportChartController(StaticSettings settings, ILogger<StaticSettings> logger,
1213
MaidataImportService importService) : ControllerBase
1314
{
14-
public record ImportChartCheckResult(bool Accept, IEnumerable<ImportChartMessage> Errors, Dictionary<ShiftMethod, float> chartPaddings, bool IsDx, string? Title, float first);
15+
public record ImportChartCheckResult(bool Accept, IEnumerable<ImportChartMessage> Errors, Dictionary<ShiftMethod, float> chartPaddings, bool IsDx, string? Title, float first, CueConvertController.SetAudioPreviewRequest? previewTime);
1516

1617
[HttpPost]
1718
public ImportChartCheckResult ImportChartCheck(IFormFile file, [FromForm] bool isReplacement = false)
@@ -99,7 +100,7 @@ public ImportChartCheckResult ImportChartCheck(IFormFile file, [FromForm] bool i
99100
{
100101
errors.Add(new ImportChartMessage(Locale.MusicNoCharts, MessageLevel.Fatal));
101102
fatal = true;
102-
return new ImportChartCheckResult(!fatal, errors, new Dictionary<ShiftMethod, float>(), false, title, 0);
103+
return new ImportChartCheckResult(!fatal, errors, new Dictionary<ShiftMethod, float>(), false, title, 0, null);
103104
}
104105

105106
float.TryParse(maiData.GetValueOrDefault("first"), out var first);
@@ -142,14 +143,22 @@ public ImportChartCheckResult ImportChartCheck(IFormFile file, [FromForm] bool i
142143

143144
var chartPaddings = MaidataImportService.CalcChartPadding(maiCharts, out _);
144145

145-
return new ImportChartCheckResult(!fatal, errors, chartPaddings, isDx, title, first);
146+
CueConvertController.SetAudioPreviewRequest? previewTime = null;
147+
if (float.TryParse(maiData.GetValueOrDefault("demo_seek"), out var demo_seek))
148+
{
149+
// 当只有demo_seek没有demo_len时,则把demo_len设为一个很大的数,表示preview直到音频结尾;SetAudioPreviewApi中会自动把实际的loopEnd限制到音频长度以内。
150+
if (!float.TryParse(maiData.GetValueOrDefault("demo_len"), out var demo_len)) demo_len = 10000f;
151+
previewTime = new CueConvertController.SetAudioPreviewRequest(demo_seek, demo_seek + demo_len);
152+
}
153+
154+
return new ImportChartCheckResult(!fatal, errors, chartPaddings, isDx, title, first, previewTime);
146155
}
147156
catch (Exception e)
148157
{
149158
logger.LogError(e, "解析谱面失败(大)");
150159
errors.Add(new ImportChartMessage(Locale.ChartParseFailedGlobal, MessageLevel.Fatal));
151160
fatal = true;
152-
return new ImportChartCheckResult(!fatal, errors, new Dictionary<ShiftMethod, float>(), false, "", 0);
161+
return new ImportChartCheckResult(!fatal, errors, new Dictionary<ShiftMethod, float>(), false, "", 0, null);
153162
}
154163
}
155164

MaiChartManager/Controllers/Music/MusicTransferController.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,11 @@ public async Task ExportAsMaidata(int id, string assetDir, bool ignoreVideo = fa
574574
if (AudioConvert.TryResolveAcbAwb(GetAudioCandidateIds(music), out _, out var previewAcb, out _) && previewAcb is not null)
575575
{
576576
var previewTime = CriUtils.GetAudioPreviewTime(previewAcb);
577-
if (previewTime.StartTime >= 0)
577+
if (previewTime.StartTime >= 0 && previewTime.EndTime > previewTime.StartTime)
578+
{
578579
simaiFile.AppendLine($"&demo_seek={previewTime.StartTime}");
580+
simaiFile.AppendLine($"&demo_len={previewTime.EndTime - previewTime.StartTime}");
581+
}
579582
}
580583
}
581584
catch

MaiChartManager/Front/src/client/apiGen.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ export interface ImportChartCheckResult {
276276
title?: string | null;
277277
/** @format float */
278278
first?: number;
279+
previewTime?: SetAudioPreviewRequest;
279280
}
280281

281282
export interface ImportChartMessage {

MaiChartManager/Front/src/views/Charts/ImportCreateChartButton/ImportChartButton/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default defineComponent({
6868
errors.value.push({ level: MessageLevel.Warning, message: t('chart.import.error.convertPaidFeature'), name: dir.name, isPaid: true });
6969
}
7070

71-
let first = 0, chartPaddings, name = dir.name, isDx = false;
71+
let first = 0, chartPaddings, name = dir.name, isDx = false, previewTime = undefined;
7272
if (maidata) {
7373
const checkRet = (await api.ImportChartCheck({ file: maidata })).data;
7474
reject = reject || !checkRet.accept;
@@ -80,11 +80,12 @@ export default defineComponent({
8080
name = checkRet.title!;
8181
if (checkRet.isDx) id += 1e4;
8282
isDx = checkRet.isDx!;
83+
if (checkRet.previewTime) previewTime = checkRet.previewTime
8384
}
8485

8586
if (!reject) {
8687
meta.value.push({
87-
id, maidata, bg, track, chartPaddings, name, first, movie, isDx,
88+
id, maidata, bg, track, chartPaddings, name, first, movie, isDx, previewTime,
8889
importStep: IMPORT_STEP.start,
8990
})
9091
}
@@ -169,6 +170,7 @@ export default defineComponent({
169170
let audioPadding = chartPadding - music.first;
170171

171172
await api.SetAudio(music.id, selectedADir.value, { file: music.track, padding: audioPadding, ignoreGapless: !!tempOptions.value.ignoreGapless });
173+
if (music.previewTime) await api.SetAudioPreview(music.id, selectedADir.value, music.previewTime);
172174

173175
if (music.movie && !tempOptions.value.disableBga) {
174176
currentMovieProgress.value = 0;

MaiChartManager/Front/src/views/Charts/ImportCreateChartButton/ImportChartButton/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ImportChartCheckResult, ImportChartMessage, ShiftMethod } from "@/client/apiGen";
1+
import { ImportChartCheckResult, ImportChartMessage, SetAudioPreviewRequest, ShiftMethod } from "@/client/apiGen";
22

33
export enum STEP {
44
none,
@@ -30,6 +30,7 @@ export type ImportMeta = {
3030
chartPaddings: ImportChartCheckResult['chartPaddings'],
3131
first: number,
3232
isDx: boolean,
33+
previewTime?: SetAudioPreviewRequest
3334
}
3435

3536
export type FirstPaddingMessage = { first: number, chartPaddings: ImportChartCheckResult['chartPaddings']}

MaiChartManager/Utils/CriUtils.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ public static async Task<byte[]> CreateAcbWithPreview(string wavPath, byte[] awb
4343
criTable.Load(File.ReadAllBytes(Path.Combine(StaticSettings.exeDir, "templateV3.acb")));
4444

4545
var cueTable = criTable.Rows[0].GetTable("CueTable");
46-
cueTable.Rows[0]["Length"] = (int)((float)format.SampleCount / format.SampleRate * 1000);
46+
float audioLength = (float)format.SampleCount / format.SampleRate;
47+
cueTable.Rows[0]["Length"] = (int)(audioLength * 1000);
4748
criTable.WriterSettings = CriTableWriterSettings.Adx2Settings;
4849
criTable.Rows[0]["CueTable"] = cueTable.Save();
4950

5051
var trackEventTable = criTable.Rows[0].GetTable("TrackEventTable");
52+
// 对loopEnd予以截断,防止前端传来的loopEnd超过音频结尾的范围
53+
if (loopEnd.TotalSeconds > audioLength) loopEnd = TimeSpan.FromSeconds(audioLength);
5154
trackEventTable.Rows[1]["Command"] = MakeCommandForPreview(loopStart, loopEnd);
5255
criTable.Rows[0]["TrackEventTable"] = trackEventTable.Save();
5356

0 commit comments

Comments
 (0)