You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF NAudio音乐播放器暂停后再播放音频从头重启问题求助

NAudio WPF平台播放暂停恢复异常解决方案

问题原因分析

  • 核心错误是每次触发PlayPause_Click点击事件时,都会重新初始化AudioFileReader对象,相当于每次点击都重新加载音频文件,原有暂停时记录的播放位置会被直接重置,这就是重新播放时会从头开始的根本原因。
  • 其次每次点击播放时都会重新实例化WaveOutEvent对象,重复初始化输出设备,不仅会造成资源泄漏,也会导致播放状态无法正常保留。
  • 你提到将初始化逻辑移到窗口加载方法中触发报错,大概率是变量作用域或资源初始化顺序的问题,调整初始化逻辑即可解决。

修复方案

第一步:定义窗口全局成员变量

将音频相关对象和状态标识放到窗口类的全局作用域,不要在点击事件中声明:

// 窗口类全局成员
private AudioFileReader audioFile;
private WaveOutEvent outputDevice;
private bool isPlaying = false; // 替换原有含义模糊的tru变量,命名更清晰
private DispatcherTimer dispatcherTimer;

第二步:窗口加载时一次性初始化资源

在窗口的Loaded事件中完成音频文件、输出设备的初始化,全程只执行一次:

private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
    audioFile = new AudioFileReader(@"D:\kondio.mp3");
    outputDevice = new WaveOutEvent();
    outputDevice.Init(audioFile);
    
    // 这里保留你原有dispatcherTimer的初始化逻辑即可
    dispatcherTimer = new DispatcherTimer();
    dispatcherTimer.Interval = TimeSpan.FromMilliseconds(1000);
    // 原有定时器Tick事件逻辑保持不变
}

第三步:修改点击事件逻辑,仅做状态切换

点击事件中不再重复初始化资源,只处理播放、暂停的状态切换:

private void PlayPause_Click(object sender, RoutedEventArgs e)
{
    if (!isPlaying)
    {
        PlayImage.Source = BitmapToImageSource(Resource1.pause);
        isPlaying = true;
        dispatcherTimer.IsEnabled = true;
        outputDevice.Play();
        dispatcherTimer.Start();
    }
    else
    {
        PlayImage.Source = BitmapToImageSource(Resource1.play);
        isPlaying = false;
        outputDevice.Pause();
        dispatcherTimer.IsEnabled = false;
    }
}

补充注意事项

在窗口关闭事件中添加资源释放逻辑,避免音频文件被持续占用:

private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
    outputDevice?.Stop();
    outputDevice?.Dispose();
    audioFile?.Dispose();
}

你原有代码中的tru1 = true属于无用笔误代码,可直接删除。

内容的提问来源于stack exchange,提问作者chrissylittle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 19:24:04