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

基于Java JLayer的可暂停播放器无法播放音频求助

基于JLayer实现可暂停播放器无法播放的问题排查

我尝试基于JLayer包的Advanced Player实现一个可暂停的播放器对象,参考了Stack Overflow上的实现方案,但目前无法播放音频。以下是我的PausablePlayer类代码及实例化方式,恳请帮忙排查问题原因:

PausablePlayer类代码

package com.musicstreamingapp;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javazoom.jl.player.advanced.AdvancedPlayer;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;


public class PausablePlayer {

    private final static int NOTSTARTED = 0;
    private final static int PLAYING = 1;
    private final static int PAUSED = 2;
    private final static int FINISHED = 3;

    // 实际处理播放的核心对象
    private final AdvancedPlayer player;

    // 用于线程通信的锁对象
    private final Object playerLock = new Object();

    // 播放器状态标记
    private int playerStatus = NOTSTARTED;

    public PausablePlayer(final InputStream inputStream) throws JavaLayerException {
        this.player = new AdvancedPlayer(inputStream);
    }

    public PausablePlayer(final InputStream inputStream, AudioDevice audioDevice) throws JavaLayerException {
        this.player = new AdvancedPlayer(inputStream, audioDevice);
    }

    /**
     * 启动播放(暂停时恢复)
     */
    public void play() throws JavaLayerException {
        synchronized (playerLock) {
            switch (playerStatus) {
                case NOTSTARTED:
                    final Runnable r = new Runnable() {
                        public void run() {
                            playInternal();
                        }
                    };
                    final Thread t = new Thread(r);
                    // 移除了原代码中的守护线程设置
                    t.setPriority(Thread.MAX_PRIORITY);
                    playerStatus = PLAYING;
                    t.start();
                    break;
                case PAUSED:
                    resume();
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 暂停播放,返回是否成功进入暂停状态
     */
    public boolean pause() {
        synchronized (playerLock) {
            if (playerStatus == PLAYING) {
                playerStatus = PAUSED;
            }
            return playerStatus == PAUSED;
        }
    }

    /**
     * 恢复播放,返回是否成功进入播放状态
     */
    public boolean resume() {
        synchronized (playerLock) {
            if (playerStatus == PAUSED) {
                playerStatus = PLAYING;
                playerLock.notifyAll();
            }
            return playerStatus == PLAYING;
        }
    }

    /**
     * 停止播放,未播放时无操作
     */
    public void stop() {
        synchronized (playerLock) {
            playerStatus = FINISHED;
            playerLock.notifyAll();
        }
    }

    private void playInternal() {
        while (playerStatus != FINISHED) {
            try {
                // 每次播放一帧音频
                boolean ret = player.play(1);
                if (!ret) {
                    break;
                }
            } catch (final JavaLayerException e) {
                e.printStackTrace(); // 添加异常打印,排查解码错误
                break;
            }
            // 检查是否暂停或终止
            synchronized (playerLock) {
                while (playerStatus == PAUSED) {
                    try {
                        playerLock.wait();
                    } catch (final InterruptedException e) {
                        // 中断时终止播放器
                        break;
                    }
                }
            }
        }
        close();
    }

    /**
     * 关闭播放器,无论当前状态如何
     */
    public void close() {
        synchronized (playerLock) {
            playerStatus = FINISHED;
        }
        try {
            player.close();
        } catch (final Exception e) {
            // 忽略关闭时的异常
        }
    }
    // 原代码末尾多余的{}代码块已删除
}

播放器实例化代码

public static void playAudio(byte[] song) {
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(song);
    try {
        PausablePlayer player = new PausablePlayer(byteArrayInputStream);
        player.play();

        // 暂停恢复测试
        Thread.sleep(5000); // 播放5秒后暂停
        player.pause();
        System.out.println("已暂停歌曲");
        
        Thread.sleep(5000); // 暂停5秒后恢复
        player.resume();
        System.out.println("已恢复歌曲");

        // 播放5秒后停止
        Thread.sleep(5000); 
        player.stop();
    } catch (JavaLayerException | InterruptedException e) {
        e.printStackTrace();
        System.out.println("播放音频出错: " + e.getMessage());
    } 
}

问题排查与修复建议

  1. 修正语法错误:原PausablePlayer类末尾存在多余的{ }代码块,会导致编译失败,必须删除。
  2. 验证音频数据完整性:确保传入的byte[] song是完整且有效的MP3文件字节数据,可以先尝试用普通AdvancedPlayer直接播放该字节数组,确认音频本身无损坏。
  3. 添加异常日志:在playInternal的JavaLayerException捕获块中添加打印语句,排查是否是解码过程中出现错误。
  4. 调整线程测试逻辑:如果音频时长较短,主线程的Thread.sleep会导致播放器在睡眠期间已经播放完毕,后续暂停/恢复操作无效。可以添加状态检查,或更换更长的测试音频。
  5. 显式初始化音频设备:如果默认音频设备初始化失败,可尝试显式创建音频设备并传入播放器构造函数:
    AudioDevice audioDevice = new JavaSoundAudioDevice();
    audioDevice.open(player.getDecoder());
    PausablePlayer player = new PausablePlayer(byteArrayInputStream, audioDevice);
    

内容的提问来源于stack exchange,提问作者Bennett Godinho-Nelson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:17:07