use of fredboat.audio.queue.SplitAudioTrackContext in project FredBoat by Frederikam.
the class MusicPersistenceHandler method reloadPlaylists.
private void reloadPlaylists(JDA jda) {
File dir = new File("music_persistence");
if (appConfig.isMusicDistribution()) {
log.warn("Music persistence loading is disabled on the MUSIC distribution! Use PATRON or DEVELOPMENT instead" + "How did this call end up in here anyways?");
return;
}
log.info("Began reloading playlists for shard {}", jda.getShardInfo().getShardId());
if (!dir.exists()) {
log.info("No music persistence directory found.");
return;
}
File[] files = dir.listFiles();
if (files == null || files.length == 0) {
log.info("No files present in music persistence directory");
return;
}
for (File file : files) {
try {
Guild guild = jda.getGuildById(file.getName());
if (guild == null) {
// only load guilds that are part of this shard
continue;
}
JSONObject data = new JSONObject(FileUtils.readFileToString(file, Charset.forName("UTF-8")));
boolean isPaused = data.getBoolean("isPaused");
final JSONArray sources = data.getJSONArray("sources");
@Nullable VoiceChannel vc = jda.getVoiceChannelById(data.getString("vc"));
@Nullable TextChannel tc = jda.getTextChannelById(data.getString("tc"));
float volume = Float.parseFloat(data.getString("volume"));
RepeatMode repeatMode = data.getEnum(RepeatMode.class, "repeatMode");
boolean shuffle = data.getBoolean("shuffle");
GuildPlayer player = playerRegistry.getOrCreate(guild);
if (tc != null) {
musicTextChannelProvider.setMusicChannel(tc);
}
if (appConfig.getDistribution().volumeSupported()) {
player.setVolume(volume);
}
player.setRepeatMode(repeatMode);
player.setShuffle(shuffle);
final boolean[] isFirst = { true };
List<AudioTrackContext> tracks = new ArrayList<>();
sources.forEach((Object t) -> {
JSONObject json = (JSONObject) t;
byte[] message = Base64.decodeBase64(json.getString("message"));
Member member = guild.getMemberById(json.getLong("user"));
if (member == null)
// member left the guild meanwhile, set ourselves as the one who added the song
member = guild.getSelfMember();
AudioTrack at;
try {
ByteArrayInputStream bais = new ByteArrayInputStream(message);
at = audioPlayerManager.decodeTrack(new MessageInput(bais)).decodedTrack;
} catch (IOException e) {
throw new RuntimeException(e);
}
if (at == null) {
log.error("Loaded track that was null! Skipping...");
return;
}
// Handle split tracks
AudioTrackContext atc;
JSONObject split = json.optJSONObject("split");
if (split != null) {
atc = new SplitAudioTrackContext(jdaEntityProvider, at, member, split.getLong("startPos"), split.getLong("endPos"), split.getString("title"));
at.setPosition(split.getLong("startPos"));
if (isFirst[0]) {
isFirst[0] = false;
if (data.has("position")) {
at.setPosition(split.getLong("startPos") + data.getLong("position"));
}
}
} else {
atc = new AudioTrackContext(jdaEntityProvider, at, member);
if (isFirst[0]) {
isFirst[0] = false;
if (data.has("position")) {
at.setPosition(data.getLong("position"));
}
}
}
tracks.add(atc);
});
player.loadAll(tracks);
if (!isPaused) {
if (vc != null) {
try {
player.joinChannel(vc);
player.play();
} catch (Exception ignored) {
}
}
if (tc != null) {
CentralMessaging.message(tc, MessageFormat.format(I18n.get(guild).getString("reloadSuccess"), sources.length())).send(null);
}
}
} catch (Exception ex) {
log.error("Error when loading persistence file", ex);
}
boolean deleted = file.delete();
log.info(deleted ? "Deleted persistence file: " + file : "Failed to delete persistence file: " + file);
}
}
use of fredboat.audio.queue.SplitAudioTrackContext in project FredBoat by Frederikam.
the class MusicPersistenceHandler method persist.
private void persist(int code) {
File dir = new File("music_persistence");
if (!dir.exists()) {
boolean created = dir.mkdir();
if (!created) {
log.error("Failed to create music persistence directory");
return;
}
}
Map<Long, GuildPlayer> reg = playerRegistry.getRegistry();
boolean isUpdate = code == ExitCodes.EXIT_CODE_UPDATE;
boolean isRestart = code == ExitCodes.EXIT_CODE_RESTART;
for (long gId : reg.keySet()) {
try {
GuildPlayer player = reg.get(gId);
String msg;
if (isUpdate) {
msg = I18n.get(player.getGuild()).getString("shutdownUpdating");
} else if (isRestart) {
msg = I18n.get(player.getGuild()).getString("shutdownRestarting");
} else {
msg = I18n.get(player.getGuild()).getString("shutdownIndef");
}
TextChannel activeTextChannel = player.getActiveTextChannel();
List<CompletableFuture> announcements = new ArrayList<>();
if (activeTextChannel != null && player.isPlaying()) {
announcements.add(CentralMessaging.message(activeTextChannel, msg).send(null));
}
for (Future announcement : announcements) {
try {
// 30 seconds is enough on patron boat
announcement.get(30, TimeUnit.SECONDS);
} catch (Exception ignored) {
}
}
JSONObject data = new JSONObject();
VoiceChannel vc = player.getCurrentVoiceChannel();
data.put("vc", vc != null ? vc.getId() : "0");
data.put("tc", activeTextChannel != null ? activeTextChannel.getId() : "");
data.put("isPaused", player.isPaused());
data.put("volume", Float.toString(player.getVolume()));
data.put("repeatMode", player.getRepeatMode());
data.put("shuffle", player.isShuffle());
if (player.getPlayingTrack() != null) {
data.put("position", player.getPosition());
}
ArrayList<JSONObject> identifiers = new ArrayList<>();
for (AudioTrackContext atc : player.getRemainingTracks()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
audioPlayerManager.encodeTrack(new MessageOutput(baos), atc.getTrack());
JSONObject ident = new JSONObject().put("message", Base64.encodeBase64String(baos.toByteArray())).put("user", atc.getUserId());
if (atc instanceof SplitAudioTrackContext) {
JSONObject split = new JSONObject();
SplitAudioTrackContext c = (SplitAudioTrackContext) atc;
split.put("title", c.getEffectiveTitle()).put("startPos", c.getStartPosition()).put("endPos", c.getStartPosition() + c.getEffectiveDuration());
ident.put("split", split);
}
identifiers.add(ident);
}
data.put("sources", identifiers);
try {
FileUtils.writeStringToFile(new File(dir, Long.toString(gId)), data.toString(), Charset.forName("UTF-8"));
} catch (IOException ex) {
if (activeTextChannel != null) {
CentralMessaging.message(activeTextChannel, MessageFormat.format(I18n.get(player.getGuild()).getString("shutdownPersistenceFail"), ex.getMessage())).send(null);
}
}
} catch (Exception ex) {
log.error("Error when saving persistence file", ex);
}
}
}
use of fredboat.audio.queue.SplitAudioTrackContext in project FredBoat by Frederikam.
the class AbstractPlayer method playTrack.
/**
* Plays the provided track.
* <p>
* Silently playing a track will not trigger the onPlayHook (which announces the track usually)
*/
private void playTrack(AudioTrackContext trackContext, boolean... silent) {
log.trace("playTrack({})", trackContext.getEffectiveTitle());
context = trackContext;
player.playTrack(trackContext.getTrack());
trackContext.getTrack().setPosition(trackContext.getStartPosition());
if (trackContext instanceof SplitAudioTrackContext) {
// Ensure we don't step over our bounds
log.info("Start: " + trackContext.getStartPosition() + " End: " + (trackContext.getStartPosition() + trackContext.getEffectiveDuration()));
trackContext.getTrack().setMarker(new TrackMarker(trackContext.getStartPosition() + trackContext.getEffectiveDuration(), new TrackEndMarkerHandler(this, trackContext)));
}
if (silent.length < 1 || !silent[0]) {
if (onPlayHook != null)
onPlayHook.accept(trackContext);
}
}
Aggregations