diff --git a/src/main/java/net/dirtydeeds/discordsoundboard/ChatSoundBoardListener.java b/src/main/java/net/dirtydeeds/discordsoundboard/ChatSoundBoardListener.java index 1b0072e..c4302aa 100644 --- a/src/main/java/net/dirtydeeds/discordsoundboard/ChatSoundBoardListener.java +++ b/src/main/java/net/dirtydeeds/discordsoundboard/ChatSoundBoardListener.java @@ -104,21 +104,31 @@ public void onMessageReceived(MessageReceivedEvent event) { "\n" + commandCharacter + "stop - Stops the sound that is currently playing." + "\n" + commandCharacter + "info - Returns info about the bot.```"); } else if (message.startsWith(commandCharacter + "volume")) { - int newVol = Integer.parseInt(message.substring(8)); + int fadeoutIndex = message.indexOf('~'); + int newVol = Integer.parseInt(message.substring(8, (fadeoutIndex > -1) ? fadeoutIndex - 1 : message.length())); + int fadeoutTimeout = 0; + if (fadeoutIndex > -1) { + fadeoutTimeout = Integer.parseInt(message.substring(fadeoutIndex + 1, message.length())); + } if (newVol >= 1 && newVol <= 100) { muted = false; - soundPlayer.setSoundPlayerVolume(newVol); + soundPlayer.setSoundPlayerVolume(newVol, fadeoutTimeout * 1000); replyByPrivateMessage(event, "*Volume set to " + newVol + "%*"); LOG.info("Volume set to " + newVol + "% by " + requestingUser + "."); } else if (newVol == 0) { muted = true; - soundPlayer.setSoundPlayerVolume(newVol); + soundPlayer.setSoundPlayerVolume(newVol, fadeoutTimeout * 1000); replyByPrivateMessage(event, requestingUser + " muted me."); LOG.info("Bot muted by " + requestingUser + "."); } } else if (message.startsWith(commandCharacter + "stop")) { - LOG.info("Stop requested by " + requestingUser + "."); - if (soundPlayer.stop()) { + int fadeoutIndex = message.indexOf('~'); + int fadeoutTimeout = 0; + if (fadeoutIndex > -1) { + fadeoutTimeout = Integer.parseInt(message.substring(fadeoutIndex + 1, message.length())); + } + LOG.info("Stop requested by " + requestingUser + " with a fadeout of " + fadeoutTimeout + " seconds"); + if (soundPlayer.stop(fadeoutTimeout * 1000)) { replyByPrivateMessage(event, "Playback stopped."); } else { replyByPrivateMessage(event, "Nothing was playing."); diff --git a/src/main/java/net/dirtydeeds/discordsoundboard/service/SoundPlayerImpl.java b/src/main/java/net/dirtydeeds/discordsoundboard/service/SoundPlayerImpl.java index 4de194a..11f2b2d 100644 --- a/src/main/java/net/dirtydeeds/discordsoundboard/service/SoundPlayerImpl.java +++ b/src/main/java/net/dirtydeeds/discordsoundboard/service/SoundPlayerImpl.java @@ -22,6 +22,8 @@ import net.dv8tion.jda.utils.PermissionUtil; import net.dv8tion.jda.utils.SimpleLog; import org.springframework.stereotype.Service; +import java.util.concurrent.TimeUnit; +import java.lang.InterruptedException; import javax.annotation.PreDestroy; import javax.inject.Inject; @@ -54,6 +56,7 @@ public class SoundPlayerImpl implements Observer { private float playerVolume = (float) .75; private final MainWatch mainWatch; private boolean initialized = false; + private boolean isFading = false; private MusicPlayer musicPlayer; private FilePlayer player; private String playerSetting; @@ -105,15 +108,47 @@ public Map getAvailableSoundFiles() { } return returnFiles; } - + /** * Sets volume of the player. * @param volume - The volume value to set. */ public void setSoundPlayerVolume(int volume) { - playerVolume = (float) volume / 100; - if (isMusicPlayer()) { - musicPlayer.setVolume(playerVolume); + setSoundPlayerVolume(volume, 1000); + } + + /** + * Sets volume of the player. + * @param volume - The volume value to set. + */ + public void setSoundPlayerVolume(int volume, int timeout) { + int currentVolume = Math.round(playerVolume * 100); + + int volumeDiff = currentVolume - volume; + if (volumeDiff < 0) { + volumeDiff = volumeDiff * -1; + } + + if (volumeDiff != 0 && isFading == false) { + boolean isFading = true; + int microInterval = Math.round(timeout / volumeDiff); + while (currentVolume != volume) { + if (currentVolume < volume) { + currentVolume++; + } else { + currentVolume--; + } + playerVolume = (float) currentVolume / 100; + if (isMusicPlayer()) { + musicPlayer.setVolume(playerVolume); + } + try { + TimeUnit.MILLISECONDS.sleep(microInterval); + } catch (InterruptedException e) { + // mute... + } + } + isFading = false; } } @@ -299,16 +334,32 @@ public void playFileForDisconnect(String fileName, VoiceLeaveEvent event) throws * @return boolean representing whether playback was stopped. */ public boolean stop() { + return stop(0); + } + + /** + * Stops sound playback and returns true or false depending on if playback was stopped. + * @return boolean representing whether playback was stopped. + */ + public boolean stop(int timeout) { + boolean result = false; + float originalVolume = playerVolume; + + if (isMusicPlayer()) { if (musicPlayer != null && musicPlayer.isPlaying()) { + setSoundPlayerVolume(0, timeout); musicPlayer.stop(); + playerVolume = originalVolume; return true; } else { return false; } } else { if (player != null && player.isPlaying()) { + setSoundPlayerVolume(0, timeout); player.stop(); + playerVolume = originalVolume; return true; } else { return false;