/
aleksandrazimut
/
TimerCountdownDesktop
Обзор
Документация
Войти
/
aleksandrazimut
/
TimerCountdownDesktop
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/main/java/com/timerapp/service/AudioService.java
160 строк
6 KB
Aleksandr Azimut
init commit
17 дек 2025, 21:59
17 дек 2025, 21:59
3c602f1
Код
Авторство
О чём код?
package com.timerapp.service; import javafx.scene.media.Media; import javafx.scene.media.MediaPlayer; import javax.sound.sampled.*; import java.io.File; import java.net.URL; /** * Сервис для воспроизведения звуковых оповещений */ public class AudioService { private MediaPlayer mediaPlayer; private Clip clip; // Для OGG и других форматов через Java Sound API /** * Воспроизводит звуковой файл * * @param soundPath путь к звуковому файлу (MP3, WAV, OGG) или путь к ресурсу * (/sounds/...) */ public void playSound(String soundPath) { try { System.out.println("[AudioService] Начинаем воспроизведение звука: " + soundPath); // Останавливаем все предыдущие звуки stop(); // Проверяем формат файла String pathLower = soundPath.toLowerCase(); boolean isOgg = pathLower.endsWith(".ogg"); if (isOgg) { System.out.println("[AudioService] Воспроизводим OGG файл"); playOgg(soundPath); } else { System.out.println("[AudioService] Воспроизводим через JavaFX Media (MP3/WAV)"); playJavaFxMedia(soundPath); } } catch (Exception e) { System.err.println("Ошибка при воспроизведении звука: " + e.getMessage()); e.printStackTrace(); } } private void playOgg(String soundPath) throws Exception { AudioInputStream audioStream = null; // Получаем поток аудио if (soundPath.startsWith("/sounds/")) { URL resourceUrl = getClass().getResource(soundPath); if (resourceUrl == null) { System.err.println("Звуковой ресурс не найден: " + soundPath); return; } audioStream = AudioSystem.getAudioInputStream(resourceUrl); } else { File file = new File(soundPath); if (!file.exists()) { System.err.println("Звуковой файл не найден: " + soundPath); return; } audioStream = AudioSystem.getAudioInputStream(file); } if (audioStream != null) { // Для VorbisSPI иногда нужно конвертировать поток в PCM_SIGNED AudioFormat baseFormat = audioStream.getFormat(); AudioFormat decodedFormat = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false); AudioInputStream decodedAudioStream = AudioSystem.getAudioInputStream(decodedFormat, audioStream); clip = AudioSystem.getClip(); clip.open(decodedAudioStream); clip.start(); // Закрываем потоки после проигрывания (в идеале слушатель LineListener, но для // простоты здесь так) // Но clip проигрывается асинхронно, потоки закрывать сразу нельзя, если они // нужны clip'у // Clip загружает данные в память, так что можно закрыть поток, если он // короткий? // С OGG лучше держать открытым пока грузится? // Clip.open() читает данные. Так что поток можно будет закрыть потом. } } private void playJavaFxMedia(String soundPath) { try { String mediaUrl; if (soundPath.startsWith("/sounds/")) { var resourceUrl = getClass().getResource(soundPath); if (resourceUrl == null) { System.err.println("[AudioService] Ресурс не найден: " + soundPath); return; } mediaUrl = resourceUrl.toExternalForm(); System.out.println("[AudioService] Загружаем звук из ресурса: " + mediaUrl); } else { File soundFile = new File(soundPath); if (!soundFile.exists()) { System.err.println("[AudioService] Файл не найден: " + soundPath); return; } mediaUrl = soundFile.toURI().toString(); System.out.println("[AudioService] Загружаем звук из файла: " + mediaUrl); } Media media = new Media(mediaUrl); mediaPlayer = new MediaPlayer(media); mediaPlayer.setOnError(() -> System.err.println("Ошибка MediaPlayer: " + mediaPlayer.getError())); mediaPlayer.play(); System.out.println("[AudioService] Звук запущен успешно"); } catch (Exception e) { System.err.println("Ошибка MediaPlayer: " + e.getMessage()); e.printStackTrace(); } } /** * Останавливает текущее воспроизведение */ public void stop() { if (mediaPlayer != null) { mediaPlayer.stop(); } if (clip != null) { if (clip.isRunning()) clip.stop(); clip.close(); clip = null; } } /** * Освобождает ресурсы */ public void cleanup() { stop(); if (mediaPlayer != null) { mediaPlayer.dispose(); mediaPlayer = null; } } /** * Возвращает текущий MediaPlayer для доступа к метаданным (длительность звука) */ public MediaPlayer getMediaPlayer() { return mediaPlayer; } }