示例代码使用的是DryWetMidi库。该程序播放MIDI文件(MIDI. path)的按钮点击,直到文件结束。问题是似乎没有办法用另一个按钮来停止播放。
有没有人有MIDI库的经验,知道如何使按钮停止当前文件播放?
@using Melanchall.DryWetMidi.Multimedia;
@using Melanchall.DryWetMidi.Core;
<span @onclick="@(() => PlayMidi())">
<button>Play</button>
</span>
@code{
private static Playback playback;
public void PlayMidi()
{
var midiFile = MidiFile.Read(MIDI.Path);
var outputDevice = OutputDevice.GetByName("Microsoft GS Wavetable Synth");
playback = midiFile.GetPlayback(outputDevice);
playback.Start();
SpinWait.SpinUntil(() => !playback.IsRunning);
Console.WriteLine("Playback stopped or finished.");
outputDevice.Dispose();
playback.Dispose();
}
}
你的代码有两个问题:
-
playBack
和outputDevice
对象在PlayMidi
函数内被处理。这意味着当您尝试从该函数外部访问playBack
对象时,它已经被处置了。 -
播放按钮直到midi播放完毕才会完成执行。这是因为
PlayMidi
函数中的SpinWait
一直等到playback.IsRunning
为假。换句话说,如果你调用一个函数来停止正在播放的playBack
对象,它将不会停止,直到midi完成播放。
我已经更新了你的代码来正确处理对象。我还注释了SpinWait
部分,并包含了一个停止按钮和StopMidi
功能。这将允许您停止播放,重新播放,并在需要时再次停止。
@page "/"
@using Melanchall.DryWetMidi.Multimedia;
@using Melanchall.DryWetMidi.Core;
@implements IDisposable
<span @onclick="@(() => PlayMidi())">
<button>Play</button>
</span>
<span @onclick="@(() => StopMidi())">
<button>Stop</button>
</span>
@code {
private Playback playback { get; set; }
private OutputDevice outputDevice =
OutputDevice.GetByName("Microsoft GS Wavetable Synth");
public void PlayMidi()
{
var midiFile = MidiFile.Read("Midi/Cymatics - Waves MIDI 10 - E Min.mid");
playback = midiFile.GetPlayback(outputDevice);
playback.Start();
//SpinWait.SpinUntil(() => !playback.IsRunning);
Console.WriteLine("Playback stopped or finished.");
}
private void StopMidi()
{
playback.Stop();
}
public void Dispose()
{
outputDevice.Dispose();
if (playback != null)
playback.Dispose();
}
}