This commit is contained in:
Minecon724 2024-12-19 16:26:45 +01:00
parent 29ed0b6a13
commit d1a405430e
Signed by: Minecon724
GPG key ID: 3CCC4D267742C8E8
9 changed files with 156 additions and 72 deletions

View file

@ -2,6 +2,7 @@ package eu.m724.musicPlugin;
import eu.m724.musicPlugin.file.AudioFileStorage; import eu.m724.musicPlugin.file.AudioFileStorage;
import eu.m724.musicPlugin.item.PortableMediaPlayer; import eu.m724.musicPlugin.item.PortableMediaPlayer;
import eu.m724.musicPlugin.item.PortableMediaPlayers;
import eu.m724.musicPlugin.item.Speakers; import eu.m724.musicPlugin.item.Speakers;
import eu.m724.musicPlugin.player.MusicPlayer; import eu.m724.musicPlugin.player.MusicPlayer;
import eu.m724.musicPlugin.file.AudioFile; import eu.m724.musicPlugin.file.AudioFile;
@ -88,7 +89,8 @@ public class MusicCommands implements CommandExecutor {
try (FileInputStream fis = new FileInputStream(file)) { try (FileInputStream fis = new FileInputStream(file)) {
var song = new AudioFile(fis); var song = new AudioFile(fis);
song.load(); song.load();
player.play(song); player.setAudio(song);
player.unpause();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -105,7 +107,7 @@ public class MusicCommands implements CommandExecutor {
sender.sendMessage("unapuised"); sender.sendMessage("unapuised");
} else if (command.getName().equals("pmp")) { } else if (command.getName().equals("pmp")) {
var p = (Player) sender; var p = (Player) sender;
var pmp = PortableMediaPlayer.fromItemStack(p.getItemInHand()); var pmp = PortableMediaPlayers.get(p.getItemInHand());
switch (args[0]) { switch (args[0]) {
case "info" -> { case "info" -> {
@ -123,7 +125,7 @@ public class MusicCommands implements CommandExecutor {
try (FileInputStream fis = new FileInputStream(file)) { try (FileInputStream fis = new FileInputStream(file)) {
var song = new AudioFile(fis); var song = new AudioFile(fis);
song.load(); song.load();
pmp.getMusicPlayer().play(song); pmp.play(song);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View file

@ -40,7 +40,8 @@ public class AudioFile {
frames += packet.getNumberOfFrames(); frames += packet.getNumberOfFrames();
} }
this.duration = frames / 50; this.duration = frames / 50; // a frame is 20 ms long so 20 * 50 is 1000
System.out.printf("audiop file has %s framrs\n", frames);
this.title = opus.getTags().getTitle(); this.title = opus.getTags().getTitle();
this.artist = opus.getTags().getArtist(); this.artist = opus.getTags().getArtist();

View file

@ -25,7 +25,7 @@ public class ItemEvents implements Listener {
if (event.getItem() == null) return; if (event.getItem() == null) return;
var player = PortableMediaPlayer.fromItemStack(event.getItem()); var player = PortableMediaPlayers.get(event.getItem());
if (player == null) return; if (player == null) return;
System.out.println("A player used"); System.out.println("A player used");
@ -61,18 +61,18 @@ public class ItemEvents implements Listener {
@EventHandler @EventHandler
public void onDrop(PlayerDropItemEvent event) { public void onDrop(PlayerDropItemEvent event) {
var item = PortableMediaPlayer.fromItemStack(event.getItemDrop().getItemStack()); var player = PortableMediaPlayers.get(event.getItemDrop().getItemStack());
if (item == null) return; if (player == null) return;
System.out.println("A playe rdropped"); System.out.println("A playe rdropped");
item.stop(); player.stop();
} }
@EventHandler @EventHandler
public void onPickup(EntityPickupItemEvent event) { public void onPickup(EntityPickupItemEvent event) {
var item = PortableMediaPlayer.fromItemStack(event.getItem().getItemStack()); var player = PortableMediaPlayers.get(event.getItem().getItemStack());
if (item == null) return; if (player == null) return;
System.out.println("A player puckuperd"); System.out.println("A player puckuperd");
@ -81,12 +81,12 @@ public class ItemEvents implements Listener {
public void onMove(InventoryMoveItemEvent event) { public void onMove(InventoryMoveItemEvent event) {
if (event.getDestination().getType() == InventoryType.PLAYER) { if (event.getDestination().getType() == InventoryType.PLAYER) {
var item = PortableMediaPlayer.fromItemStack(event.getItem()); var player = PortableMediaPlayers.get(event.getItem());
if (item == null) return; if (player == null) return;
System.out.println("A player storaged :(("); System.out.println("A player storaged :((");
item.stop(); player.stop();
} }
} }
} }

View file

@ -0,0 +1,33 @@
package eu.m724.musicPlugin.item;
import eu.m724.musicPlugin.file.AudioFile;
public class PlayedSong {
public final AudioFile file;
private int progress = 0;
private long started = -1;
public PlayedSong(AudioFile file) {
this.file = file;
}
public int getProgress() {
if (started == -1)
return progress;
return (int) (System.currentTimeMillis() - started) + progress;
}
public void pause() {
this.progress = getProgress();
this.started = -1;
}
public void unpause() {
this.started = System.currentTimeMillis();
}
public boolean paused() {
return started == -1;
}
}

View file

@ -1,7 +1,8 @@
package eu.m724.musicPlugin.item; package eu.m724.musicPlugin.item;
import eu.m724.musicPlugin.file.AudioFile;
import eu.m724.musicPlugin.item.speaker.Speaker; import eu.m724.musicPlugin.item.speaker.Speaker;
import eu.m724.musicPlugin.player.MovingMusicPlayer; import eu.m724.musicPlugin.player.MusicPlayer;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.NamespacedKey; import org.bukkit.NamespacedKey;
@ -28,6 +29,9 @@ public class PortableMediaPlayer {
public final boolean premium; public final boolean premium;
public final String engraving; public final String engraving;
private PlayedSong played;
private Speaker speaker;
PortableMediaPlayer(int id, int storageSeconds, int audioBitrate, boolean premium, String engraving) { PortableMediaPlayer(int id, int storageSeconds, int audioBitrate, boolean premium, String engraving) {
this.id = id; this.id = id;
this.storageSeconds = storageSeconds; this.storageSeconds = storageSeconds;
@ -40,29 +44,81 @@ public class PortableMediaPlayer {
return new PortableMediaPlayer(ThreadLocalRandom.current().nextInt(), 600, 32000, premium, engraving); return new PortableMediaPlayer(ThreadLocalRandom.current().nextInt(), 600, 32000, premium, engraving);
} }
public void stop() {
Speakers.speakers.remove(id).destroy();
getMusicPlayer().stop();
Speakers.players.remove(id);
}
public void setSpeaker(Speaker speaker) { public void setSpeaker(Speaker speaker) {
var linked = Speakers.speakers.get(id); if (speaker.equals(this.speaker))
if (speaker.equals(linked))
return; return;
if (linked != null) if (this.speaker != null) {
linked.destroy(); // no need to pause if no need to pause
this.speaker.setDestroyCallback(c -> {});
this.speaker.destroy();
}
var paused = getMusicPlayer().isPlaying(); speaker.setDestroyCallback(c -> {
speaker.setMusicPlayer(getMusicPlayer()); System.out.println("spekar rip");
speaker.setDestroyCallback(c -> this.onSpeakerDestroyed()); played.pause();
if (paused) getMusicPlayer().unpause(); });
Speakers.speakers.put(id, speaker);
this.speaker = speaker;
if (played != null && !played.paused()) {
unpause();
}
} }
public MovingMusicPlayer getMusicPlayer() { public void play(AudioFile audioFile) {
return Speakers.players.computeIfAbsent(id, m -> new MovingMusicPlayer()); if (speaker == null) return;
played = new PlayedSong(audioFile);
speaker.getMusicPlayer().setOnAction(action -> {
if (action == MusicPlayer.TrackAction.PAUSE) {
// track paused
System.out.println("Okay its paused");
played.pause();
} else if (action == MusicPlayer.TrackAction.UNPAUSE) { // track unpaused
System.out.println("Okay its unpaused");
played.unpause();
} else if (action == MusicPlayer.TrackAction.DURATION) { // track ended
System.out.println("Okay its ened");
next();
}
});
unpause();
}
void pause() {
System.out.println("pmp pase");
if (played == null || speaker == null) return;
System.out.println("pmp pasedd");
speaker.getMusicPlayer().pause();
}
void unpause() {
System.out.println("pmp unpase");
if (played == null || speaker == null) return;
System.out.println("pmp unpasedd");
speaker.getMusicPlayer().setAudio(played.file);
speaker.getMusicPlayer().seek(played.getProgress());
speaker.getMusicPlayer().unpause();
}
void stop() {
System.out.println("pmp stop");
if (speaker != null)
speaker.destroy();
this.played = null;
}
void next() {
System.out.println("pmp next");
this.played = null;
// TODO
} }
/* Item functions */ /* Item functions */

View file

@ -1,12 +1,10 @@
package eu.m724.musicPlugin.item; package eu.m724.musicPlugin.item;
import eu.m724.musicPlugin.item.speaker.Speaker; import eu.m724.musicPlugin.item.speaker.Speaker;
import eu.m724.musicPlugin.player.MovingMusicPlayer;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class Speakers { public class Speakers {
static Map<Integer, Speaker> speakers = new HashMap<>(); static Map<Integer, Speaker> speakers = new HashMap<>();
static Map<Integer, MovingMusicPlayer> players = new HashMap<>();
} }

View file

@ -1,6 +1,8 @@
package eu.m724.musicPlugin.item.speaker; package eu.m724.musicPlugin.item.speaker;
import eu.m724.musicPlugin.player.MovingMusicPlayer; import eu.m724.musicPlugin.player.MovingMusicPlayer;
import eu.m724.musicPlugin.player.MusicPlayer;
import eu.m724.musicPlugin.player.StaticMusicPlayer;
import org.bukkit.Location; import org.bukkit.Location;
import java.util.HashMap; import java.util.HashMap;
@ -14,7 +16,8 @@ public class BlockSpeaker extends Speaker {
} }
public static BlockSpeaker create(Location location) { public static BlockSpeaker create(Location location) {
if (speakers.containsKey(location)) return null; if (speakers.containsKey(location))
return null;
return speakers.compute(location, (k, v) -> new BlockSpeaker(location)); return speakers.compute(location, (k, v) -> new BlockSpeaker(location));
} }
@ -23,14 +26,10 @@ public class BlockSpeaker extends Speaker {
private final Location location; private final Location location;
public BlockSpeaker(Location location) { public BlockSpeaker(Location location) {
super(new StaticMusicPlayer(location));
this.location = location; this.location = location;
} }
@Override
void onSetMusicPlayer(MovingMusicPlayer musicPlayer) {
musicPlayer.moveTo(location);
}
@Override @Override
void onDestroy() { void onDestroy() {
speakers.remove(location); speakers.remove(location);

View file

@ -1,31 +1,23 @@
package eu.m724.musicPlugin.item.speaker; package eu.m724.musicPlugin.item.speaker;
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
import eu.m724.musicPlugin.file.AudioFile;
import eu.m724.musicPlugin.player.MovingMusicPlayer; import eu.m724.musicPlugin.player.MovingMusicPlayer;
import eu.m724.musicPlugin.player.MusicPlayer;
import java.util.function.Consumer; import java.util.function.Consumer;
public abstract class Speaker { public abstract class Speaker {
private MovingMusicPlayer musicPlayer; private final MusicPlayer musicPlayer;
private Consumer<Void> destroyCallback; private Consumer<Void> destroyCallback;
public MovingMusicPlayer getMusicPlayer() { protected Speaker(MusicPlayer musicPlayer) {
return musicPlayer;
}
public void setMusicPlayer(MovingMusicPlayer musicPlayer) {
if (musicPlayer.equals(this.musicPlayer)) return;
if (this.musicPlayer != null) {
musicPlayer.pause();
}
this.musicPlayer = musicPlayer; this.musicPlayer = musicPlayer;
onSetMusicPlayer(musicPlayer); musicPlayer.init();
} }
public void destroy() { public void destroy() {
this.musicPlayer.pause(); musicPlayer.stop();
this.musicPlayer = null;
onDestroy(); onDestroy();
destroyCallback.accept(null); destroyCallback.accept(null);
@ -35,6 +27,9 @@ public abstract class Speaker {
this.destroyCallback = consumer; this.destroyCallback = consumer;
} }
abstract void onSetMusicPlayer(MovingMusicPlayer musicPlayer); public MusicPlayer getMusicPlayer() {
return musicPlayer;
}
abstract void onDestroy(); abstract void onDestroy();
} }

View file

@ -3,7 +3,6 @@ package eu.m724.musicPlugin.player;
import de.maxhenkel.voicechat.api.VoicechatServerApi; import de.maxhenkel.voicechat.api.VoicechatServerApi;
import de.maxhenkel.voicechat.api.audiochannel.AudioChannel; import de.maxhenkel.voicechat.api.audiochannel.AudioChannel;
import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer; import de.maxhenkel.voicechat.api.audiochannel.AudioPlayer;
import de.maxhenkel.voicechat.api.audiochannel.LocationalAudioChannel;
import eu.m724.musicPlugin.Statics; import eu.m724.musicPlugin.Statics;
import eu.m724.musicPlugin.file.AudioFile; import eu.m724.musicPlugin.file.AudioFile;
@ -45,13 +44,15 @@ public abstract class MusicPlayer {
/* Playback control */ /* Playback control */
/** /**
* Starts playback of an audio file<br> * Sets audio file to play<br>
* If it's not loaded, it will be loaded synchronously. * If it's not loaded, it will be loaded synchronously.<br>
* The file is not rewinded. If you want to start from beginning, {@link MusicPlayer#seek(int)}
* After this, do {@link MusicPlayer#unpause()}
* *
* @see MusicPlayer#pause() * @see MusicPlayer#pause()
* @see MusicPlayer#stop() * @see MusicPlayer#stop()
*/ */
public void play(AudioFile audioFile) { public void setAudio(AudioFile audioFile) {
if (audioFile != null) if (audioFile != null)
this.audioFile = audioFile; this.audioFile = audioFile;
@ -60,21 +61,23 @@ public abstract class MusicPlayer {
if (!audioFile.isLoaded()) { if (!audioFile.isLoaded()) {
try { try {
System.out.println("Audio not already loaded, so I load it");
audioFile.load(); audioFile.load();
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
System.out.printf("Audio loaded it's %d seconds long, so I'm guessing %d frames\n", audioFile.getTrackDuration(), audioFile.getTrackDuration() * 50);
ready = true; ready = true;
playing = true;
unpause(); unpause();
} }
public void unpause() { public void unpause() {
if (!ready || !playing) return; if (!ready || playing) return;
System.out.println("Unapised"); System.out.println("playback unpaused");
var sa = new short[960]; var sa = new short[960];
var enc = audioFile.getEncoder(); var enc = audioFile.getEncoder();
@ -84,11 +87,11 @@ public abstract class MusicPlayer {
player.startPlaying(); player.startPlaying();
// TODO this may take a long time and it might glitch if it does // TODO this may take a long time and it might glitch if it does
onAction.accept(ready ? TrackAction.UNPAUSE : TrackAction.START); onAction.accept(TrackAction.UNPAUSE);
playing = false; playing = true;
System.out.println("unpaused"); System.out.println("playback unpaused now");
} }
/** /**
@ -123,8 +126,8 @@ public abstract class MusicPlayer {
private void stopPlayback(boolean pause) { private void stopPlayback(boolean pause) {
System.out.println("psued"); System.out.println("playback stopped");
playing = pause; playing = false;
ready = pause; ready = pause;
player.stopPlaying(); player.stopPlaying();
@ -134,9 +137,10 @@ public abstract class MusicPlayer {
} }
private void onStop() { private void onStop() {
if (playing) { // paused if (ready && !playing) { // paused
System.out.println("I detected pause"); System.out.println("I detected pause");
onAction.accept(TrackAction.PAUSE); onAction.accept(TrackAction.PAUSE);
playing = false;
} else if (ready) { // not paused and still playing } else if (ready) { // not paused and still playing
System.out.println("I detected end"); System.out.println("I detected end");
onAction.accept(TrackAction.DURATION); onAction.accept(TrackAction.DURATION);
@ -148,10 +152,6 @@ public abstract class MusicPlayer {
} }
public enum TrackAction { public enum TrackAction {
/**
* A new track started playing
*/
START,
/** /**
* Song stopped playing because it played * Song stopped playing because it played
*/ */