Skip to content

Commit cfdd2c9

Browse files
committed
fix #40: 音频导出过程中的&first修正,消除WAV转MP3导致的延迟
1 parent f34c945 commit cfdd2c9

3 files changed

Lines changed: 23 additions & 13 deletions

File tree

MaiChartManager/Controllers/Music/MusicTransferController.cs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
using Microsoft.AspNetCore.Mvc;
99
using Microsoft.VisualBasic.FileIO;
1010
using NAudio.Lame;
11-
using SimaiSharp;
11+
using NAudio.Wave;
1212
using Vanara.Windows.Forms;
13-
using Xabe.FFmpeg;
1413
using FolderBrowserDialog = System.Windows.Forms.FolderBrowserDialog;
1514

1615
namespace MaiChartManager.Controllers.Music;
@@ -549,13 +548,26 @@ public async Task ExportAsMaidata(int id, string assetDir, bool ignoreVideo = fa
549548
await using var zipStream = HttpContext.Response.BodyWriter.AsStream();
550549
using var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, leaveOpen: true);
551550

551+
// 计算由于WAV转MP3导致的音频开头增加的空白段的长度,以便稍后通过&first参数给予修正。
552+
// 具体的情况和原理,详见https://github.com/MuNET-OSS/MaiChartManager/issues/40
553+
var wavPath = await AudioConvert.GetCachedWavPath(GetAudioCandidateIds(music));
554+
if (wavPath is null)
555+
{
556+
var message = BuildAudioResolveErrorMessage(music);
557+
logger.LogError("{message}", message);
558+
throw new FileNotFoundException(message);
559+
}
560+
using var wavReader = new WaveFileReader(wavPath);
561+
// 根据上面issue中的结论,wav转mp3引起的开头空白段的长度为1728采样点
562+
var audioDelay = 1728 / (double)wavReader.WaveFormat.SampleRate;
563+
552564
Ma2Parser parser = new();
553565
var simaiFile = new StringBuilder();
554566

555567
simaiFile.AppendLine($"&title={music.Name}");
556568
simaiFile.AppendLine($"&artist={music.Artist}");
557569
simaiFile.AppendLine($"&wholebpm={music.Bpm}");
558-
simaiFile.AppendLine("&first=0.0333");
570+
simaiFile.AppendLine($"&first={audioDelay::0.####}");
559571
simaiFile.AppendLine($"&shortid={music.Id}");
560572
simaiFile.AppendLine($"&genreid={music.GenreId}");
561573
var genre = StaticSettings.GenreList.FirstOrDefault(it => it.Id == music.GenreId);
@@ -622,6 +634,7 @@ public async Task ExportAsMaidata(int id, string assetDir, bool ignoreVideo = fa
622634
imageStream.Close();
623635
}
624636

637+
// 导出音频
625638
var soundEntry = zipArchive.CreateEntry("track.mp3");
626639
await using var soundStream = soundEntry.Open();
627640
var tag = new ID3TagData
@@ -633,16 +646,10 @@ public async Task ExportAsMaidata(int id, string assetDir, bool ignoreVideo = fa
633646
Comment = version?.GenreName,
634647
AlbumArt = img,
635648
};
636-
var wavPath = await AudioConvert.GetCachedWavPath(GetAudioCandidateIds(music));
637-
if (wavPath is null)
638-
{
639-
var message = BuildAudioResolveErrorMessage(music);
640-
logger.LogError("{message}", message);
641-
throw new FileNotFoundException(message);
642-
}
643649

644-
AudioConvert.ConvertWavPathToMp3Stream(wavPath, soundStream, tag);
650+
AudioConvert.ConvertWavToMp3Stream(wavReader, soundStream, tag);
645651
soundStream.Close();
652+
wavReader.Close();
646653

647654
if (!ignoreVideo && StaticSettings.MovieDataMap.TryGetValue(music.NonDxId, out var movieUsmPath))
648655
{

MaiChartManager/Services/MaidataImportService.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,6 @@ public ImportChartResult ImportMaidata(
243243
}
244244

245245
float.TryParse(maiData.GetValueOrDefault("first"), out var first);
246-
// Mai 的歌曲是从两帧后开始播放的
247-
first -= 1 / 30f;
248246

249247
var paddings = allCharts.Values.Select(chart => CalcMusicPadding(chart.simaiSharpChart, first)).ToList();
250248
// 音频前面被增加了多少

MaiChartManager/Utils/AudioConvert.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,11 @@ public static async Task<string> GetCachedWavPath(string acbPath, string awbPath
7777
public static void ConvertWavPathToMp3Stream(string wavPath, Stream mp3Stream, ID3TagData? tagData = null)
7878
{
7979
using var reader = new WaveFileReader(wavPath);
80+
ConvertWavToMp3Stream(reader, mp3Stream, tagData);
81+
}
82+
83+
public static void ConvertWavToMp3Stream(WaveFileReader reader, Stream mp3Stream, ID3TagData? tagData = null)
84+
{
8085
using var writer = new LameMP3FileWriter(mp3Stream, reader.WaveFormat, 256, tagData);
8186
reader.CopyTo(writer);
8287
}

0 commit comments

Comments
 (0)