a few more features

This commit is contained in:
overflowerror 2016-09-08 21:32:39 +02:00
parent 1ca1e784ff
commit 57a6fab13f
24 changed files with 820 additions and 45 deletions

View file

@ -2,14 +2,21 @@ package net.persei.dionysus;
import javax.sound.midi.MidiUnavailableException;
import net.persei.dionysus.commands.Command;
import net.persei.dionysus.commands.MusicPlayCommand;
import net.persei.dionysus.commands.ResetContextCommand;
import net.persei.dionysus.commands.SetContextCommand;
import net.persei.dionysus.commands.VideoPlayCommand;
import net.persei.dionysus.events.Event;
import net.persei.dionysus.exceptions.LibrariesNotFoundException;
import net.persei.dionysus.managers.Command;
import net.persei.dionysus.managers.CommandManager;
import net.persei.dionysus.managers.Event;
import net.persei.dionysus.managers.Context;
import net.persei.dionysus.managers.MidiManager;
import net.persei.dionysus.managers.MidiSource;
import net.persei.dionysus.managers.MusicManager;
import net.persei.dionysus.managers.PlayerManager;
import net.persei.dionysus.managers.Sequence;
import net.persei.dionysus.managers.VideoManager;
import net.persei.dionysus.players.PlayerType;
import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.discovery.NativeDiscovery;
@ -24,9 +31,12 @@ public class Main {
throw new LibrariesNotFoundException();
System.out.println(LibVlc.INSTANCE.libvlc_get_version());
System.out.println("Adding players...");
PlayerManager.getInstance().create(PlayerType.Video, "TestVideo", true);
PlayerManager.getInstance().create(PlayerType.Audio, "TestAudio", true);
System.out.println("Instancing video manager...");
VideoManager videoManager = new VideoManager("MainVideoManager");
PlayerManager.getInstance().create(PlayerType.Video, "primary", true);
System.out.println("Instancing music manager...");
MusicManager musicManager = new MusicManager("MainMusicManager");
System.out.println("Instancing command manager...");
CommandManager commandManager = new CommandManager();
@ -34,32 +44,33 @@ public class Main {
MidiManager midiManager = new MidiManager(commandManager);
System.out.println("Adding commands...");
commandManager.addCommand(new Sequence().append(new Event(MidiSource.LAUNCHPAD, true, 0, 0, 0, 0)),
new Command() {
@Override
public String getName() {
return "Test Command";
}
@Override
public void execute() {
PlayerManager.getInstance().getByName("TestVideo").playFile("test.mp4");
System.out.println("Hallo Welt");
}
});
commandManager.addCommand(new Sequence().append(new Event(MidiSource.LAUNCHPAD, true, 0, 1, 0, 0))
.append(new Event(MidiSource.LAUNCHPAD, true, 0, 2, 0, 0)), new Command() {
@Override
public String getName() {
return "Test Sequence Command";
}
Sequence contextSequence = new Sequence().append(new Event(MidiSource.LAUNCHPAD, true, 0, 8, 7, 0));
Sequence resetContext = new Sequence().append(new Event(MidiSource.LAUNCHPAD, true, 0, 8, 6, 0));
@Override
public void execute() {
PlayerManager.getInstance().getByName("TestAudio").playFile("test.mp3");
System.out.println("Sequence Test");
}
});
Context musicContext = new Context().append(new Event(MidiSource.LAUNCHPAD, true, 0, 8, 0, 0));
Context fxContext = new Context().append(new Event(MidiSource.LAUNCHPAD, true, 0, 8, 1, 0));
Context videoContext = new Context().append(new Event(MidiSource.LAUNCHPAD, true, 0, 8, 2, 0));
Context unusedContext = new Context().append(new Event(MidiSource.LAUNCHPAD, true, 0, 8, 3, 0));
commandManager.addCommand(resetContext, new ResetContextCommand("ResetContext", commandManager));
commandManager.addCommand(new Sequence(contextSequence).append(musicContext),
new SetContextCommand("MusicContext", commandManager, musicContext));
commandManager.addCommand(new Sequence(contextSequence).append(fxContext),
new SetContextCommand("FXContext", commandManager, fxContext));
commandManager.addCommand(new Sequence(contextSequence).append(videoContext),
new SetContextCommand("VideoContext", commandManager, videoContext));
commandManager.addCommand(new Sequence(contextSequence).append(unusedContext),
new SetContextCommand("UnusedContext", commandManager, unusedContext));
commandManager.addCommand(new Sequence(musicContext).append(new Event(MidiSource.LAUNCHPAD, true, 0, 0, 7, 0)),
new MusicPlayCommand("Play_Merlins's_Study", musicManager,
"resources/audio/camelot/Merlin's Study.mp3"));
commandManager.addCommand(new Sequence(videoContext).append(new Event(MidiSource.LAUNCHPAD, true, 0, 0, 6, 0)),
new VideoPlayCommand("Show_Mountains", videoManager, "primary",
"resources/video/mountains.mp4", true));
System.out.println("Adding shutdown hook...");
Runtime.getRuntime().addShutdownHook(new Thread() {

View file

@ -0,0 +1,16 @@
package net.persei.dionysus.commands;
public abstract class Command {
public abstract void execute();
public abstract String getName();
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!obj.getClass().equals(this.getClass()))
return false;
Command command = (Command) obj;
if (!command.getName().equals(this.getName()))
return false;
return true;
}
}

View file

@ -0,0 +1,70 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.MusicManager;
public class MusicCommand extends Command {
private String name;
private MusicCommandType type;
private MusicManager musicManager;
private String file;
private long duration;
private boolean loop;
public MusicCommand(String name, MusicManager musicManager, MusicCommandType type, String file, long duration, boolean loop) {
this.name = name;
this.musicManager = musicManager;
this.type = type;
this.file = file;
this.duration = duration;
this.loop = loop;
}
public MusicCommand(String name) {
this.name = name;
}
@Override
public void execute() {
switch (type) {
case change:
musicManager.change(file, duration, loop);
break;
case pause:
musicManager.pause();
break;
case play:
musicManager.play(file, duration, loop);
break;
case stop:
musicManager.stop(duration);
break;
default:
break;
}
}
@Override
public String getName() {
return name;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!obj.getClass().equals(this.getClass()))
return false;
MusicCommand command = (MusicCommand) obj;
if (!command.getName().equals(this.getName()))
return false;
if (command.type != type)
return false;
if (command.duration != duration)
return false;
if (command.file != null && !command.file.equals(file))
return false;
if (command.loop != loop)
return false;
return true;
}
}

View file

@ -0,0 +1,5 @@
package net.persei.dionysus.commands;
public enum MusicCommandType {
play, change, stop, pause
}

View file

@ -0,0 +1,18 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.MusicManager;
public class MusicPlayCommand extends MusicCommand {
public MusicPlayCommand(String name, MusicManager musicManager, String file) {
this(name, musicManager, file, 0);
}
public MusicPlayCommand(String name, MusicManager musicManager, String file, long duration) {
this(name, musicManager, file, duration, true);
}
public MusicPlayCommand(String name, MusicManager musicManager, String file, long duration,
boolean loop) {
super(name, musicManager, MusicCommandType.play, file, duration, loop);
}
}

View file

@ -0,0 +1,13 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.CommandManager;
import net.persei.dionysus.managers.Context;
import net.persei.dionysus.managers.Sequence;
public class ResetContextCommand extends SetContextCommand {
public ResetContextCommand(String name, CommandManager commandManager) {
super(name, commandManager, new Context());
}
}

View file

@ -0,0 +1,30 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.CommandManager;
import net.persei.dionysus.managers.Context;
import net.persei.dionysus.managers.Sequence;
public class SetContextCommand extends Command {
private String name;
private CommandManager commandManager;
private Context context;
public SetContextCommand(String name, CommandManager commandManager, Context context) {
this.name = name;
this.commandManager = commandManager;
this.context = context;
}
@Override
public void execute() {
if (!commandManager.getContext().equals(context))
commandManager.setContext(context);
}
@Override
public String getName() {
return name;
}
}

View file

@ -0,0 +1,5 @@
package net.persei.dionysus.commands;
public enum SoundFXComanndType {
play, stop
}

View file

@ -0,0 +1,56 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.MusicManager;
import net.persei.dionysus.managers.SoundFXManager;
public class SoundFXCommand extends Command {
private String name;
private SoundFXComanndType type;
private SoundFXManager soundManager;
private String file;
public SoundFXCommand(String name, SoundFXManager soundManager, MusicCommandType type, String file) {
this.name = name;
this.soundManager = soundManager;
this.file = file;
}
public SoundFXCommand(String name) {
this.name = name;
}
@Override
public void execute() {
switch (type) {
case play:
soundManager.play(file);
break;
case stop:
soundManager.stopAll();
break;
default:
break;
}
}
@Override
public String getName() {
return name;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!obj.getClass().equals(this.getClass()))
return false;
SoundFXCommand command = (SoundFXCommand) obj;
if (!command.getName().equals(this.getName()))
return false;
if (command.type != type)
return false;
if (command.file != null && !command.file.equals(file))
return false;
return true;
}
}

View file

@ -0,0 +1,69 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.VideoManager;
public class VideoCommand extends Command {
private String name;
private VideoManager videoManager;
private VideoCommandType type;
private String playerName;
private String file;
private boolean loop;
public VideoCommand(String name, VideoCommandType type, VideoManager videoManager, String playerName, String file,
boolean loop) {
this.name = name;
this.type = type;
this.videoManager = videoManager;
this.file = file;
this.playerName = playerName;
this.loop = loop;
}
@Override
public void execute() {
switch (type) {
case pause:
videoManager.pause(playerName);
break;
case play:
if (file == null)
videoManager.play(playerName);
else
videoManager.play(playerName, file, loop);
break;
case stop:
videoManager.stop(playerName);
break;
default:
break;
}
}
@Override
public String getName() {
return name;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!obj.getClass().equals(this.getClass()))
return false;
VideoCommand command = (VideoCommand) obj;
if (!command.getName().equals(this.getName()))
return false;
if (command.type != type)
return false;
if (command.file != null && !command.file.equals(file))
return false;
if (command.loop != loop)
return false;
if (!command.playerName.equals(playerName))
return false;
return true;
}
}

View file

@ -0,0 +1,5 @@
package net.persei.dionysus.commands;
public enum VideoCommandType {
play, stop, pause
}

View file

@ -0,0 +1,11 @@
package net.persei.dionysus.commands;
import net.persei.dionysus.managers.VideoManager;
public class VideoPlayCommand extends VideoCommand {
public VideoPlayCommand(String name, VideoManager videoManager, String playerName,
String file, boolean loop) {
super(name, VideoCommandType.play, videoManager, playerName, file, loop);
}
}

View file

@ -0,0 +1,81 @@
package net.persei.dionysus.events;
import net.persei.dionysus.managers.MidiSource;
public class Event {
static private boolean velocitySensitive = false;
private MidiSource source;
private boolean press;
private int channel;
private int x;
public MidiSource getSource() {
return source;
}
public boolean isPress() {
return press;
}
public int getChannel() {
return channel;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getV() {
return v;
}
private int y;
private int v;
public Event(MidiSource source, boolean press, int channel, int x, int y, int v) {
this.source = source;
this.press = press;
this.channel = channel;
this.x = x;
this.y = y;
this.v = v;
}
public static boolean isVelocitySensitive() {
return velocitySensitive;
}
public static void setVelocitySensitive(boolean velocitySensitive) {
Event.velocitySensitive = velocitySensitive;
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (!(obj instanceof Event))
return false;
Event event = (Event) obj;
if (event.source != source)
return false;
if (event.press != press)
return false;
if (event.channel != channel)
return false;
if (event.x != x)
return false;
if (event.y != y)
return false;
if (velocitySensitive)
if (event.v != v)
return false;
return true;
}
public String toString() {
return (press ? "press" : "release") + " on " + source + " x:" + x + ", y:" + y + ", v:" + v;
}
}

View file

@ -0,0 +1,11 @@
package net.persei.dionysus.events;
import net.persei.dionysus.managers.MidiSource;
public class LaunchpadEvent extends Event {
public LaunchpadEvent(boolean press, int x, int y) {
super(MidiSource.LAUNCHPAD, press, 0, x, y, 0);
}
}

View file

@ -3,6 +3,9 @@ package net.persei.dionysus.managers;
import java.util.LinkedList;
import java.util.List;
import net.persei.dionysus.commands.Command;
import net.persei.dionysus.events.Event;
public class CommandManager {
static private class CommandTuple {
public final Sequence sequence;
@ -12,17 +15,50 @@ public class CommandManager {
this.sequence = sequence;
this.command = command;
}
public boolean equals(Object obj) {
if (!(obj instanceof CommandTuple))
return false;
CommandTuple ct = (CommandTuple) obj;
if (!sequence.equals(ct.sequence))
return false;
if (!command.equals(ct.command))
return false;
return true;
}
}
private List<CommandTuple> commands = new LinkedList<>();
private List<CommandTuple> executedCommands = new LinkedList<>();
private Sequence sequence = new Sequence();
public Sequence getSequence() {
return sequence;
}
public Context getContext() {
return context;
}
private Context context = new Context();
private Context nextContext = null;
private long lastChange = 0;
static private long maxInterval = 1 * 1000;
public long getLastChange() {
return lastChange;
}
public void setContext(Context context) {
this.nextContext = context;
}
static public long maxInterval = 1 * 1000;
public boolean registerEvent(Event event) {
if (System.currentTimeMillis() - lastChange > maxInterval)
sequence = new Sequence();
if (System.currentTimeMillis() - lastChange > maxInterval) {
sequence = new Sequence(context);
executedCommands = new LinkedList<>();
}
sequence.add(event);
lastChange = System.currentTimeMillis();
return checkForCommand();
@ -38,11 +74,17 @@ public class CommandManager {
break;
}
if (check) {
if (executedCommands.contains(ct))
continue;
System.out.println("Executing " + ct.command.getName() + "...");
ct.command.execute();
executedCommands.add(ct);
result = true;
}
}
if (nextContext != null)
context = nextContext;
nextContext = null;
return result;
}

View file

@ -0,0 +1,18 @@
package net.persei.dionysus.managers;
import net.persei.dionysus.events.Event;
public class Context extends Sequence {
public Context append(Event event) {
add(event);
return this;
}
public Context append(Context context) {
addAll(context);
return this;
}
public Context append(Sequence sequence) {
addAll(sequence);
return this;
}
}

View file

@ -10,10 +10,13 @@ import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiMessage;
import javax.sound.midi.MidiDevice.Info;
import net.persei.dionysus.events.Event;
public class MidiManager {
private CommandManager commandManager;
@ -37,10 +40,10 @@ public class MidiManager {
transmitter.setReceiver(new MPD18Listener());
continue;
}
if (info.getName().contains("S")) {
if (info.getName().contains("S ")) {
System.out.println("Found Launchpad: " + info.getName());
if (device.getMaxTransmitters() == 0)
continue;
if (device.getMaxTransmitters() != 0) {
System.out.println("... transmitter");
if (!device.isOpen())
device.open();
devices.add(device);
@ -48,8 +51,17 @@ public class MidiManager {
transmitter.setReceiver(new LaunchpadListener());
continue;
}
if (device.getMaxReceivers() != 0) {
System.out.println("... receiver");
if (!device.isOpen())
device.open();
devices.add(device);
continue;
}
}
System.out.println("Found nothing: " + info.getName());
}
feedbackSequence();
}
public static final int MIDI_NOTE_OFF = 0x80;
@ -101,4 +113,81 @@ public class MidiManager {
System.out.println(press + " on " + source + ": " + x + ", " + y + " - " + v);
commandManager.registerEvent(new Event(source, press, channel, x, y, v));
}
public void feedbackSequence() {
MidiDevice launchpadTmp = null;
for (MidiDevice device : devices) {
if (device.getDeviceInfo().getName().contains("S ")) {
if (device.getMaxReceivers() == 0) {
System.out.println("Launchpad found, but no receivers. " + device.getDeviceInfo().getName());
continue;
}
launchpadTmp = device;
break;
}
}
if (launchpadTmp == null)
return;
final MidiDevice launchpad = launchpadTmp;
Receiver receiver;
try {
receiver = launchpad.getReceiver();
} catch (MidiUnavailableException e) {
e.printStackTrace();
return;
}
new Thread() {
public void run() {
try {
while (true) {
List<Event> events = new Sequence(commandManager.getSequence());
List<Event> context = commandManager.getContext();
for (Event event : context) {
if (events.contains(event))
events.remove(event);
}
int intensity = 0x03
- (int) ((3.0 * (System.currentTimeMillis() - commandManager.getLastChange())
/ CommandManager.maxInterval));
clearLaunchpad(launchpad);
for (Event event : context) {
setLaunchpad(launchpad, event.getX(), event.getY(), 0x00, 0x03);
}
if (intensity > 0) {
for (Event event : events) {
setLaunchpad(launchpad, event.getX(), event.getY(), intensity, 0x00);
}
}
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
private void clearLaunchpad(MidiDevice launchpad) {
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 8; j++) {
setLaunchpad(launchpad, i, j, 0, 0);
}
}
}
private void setLaunchpad(MidiDevice launchpad, int x, int y, int r, int g) {
ShortMessage message = new ShortMessage();
try {
message.setMessage(((r | g) != 0) ? MIDI_NOTE_ON : MIDI_NOTE_OFF, 0, ((y & 0x07) << 4) | (x & 0x0F),
(r & 0x03) | ((g & 0x03) << 4));
launchpad.getReceiver().send(message, System.currentTimeMillis());
} catch (InvalidMidiDataException e) {
e.printStackTrace();
} catch (MidiUnavailableException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,116 @@
package net.persei.dionysus.managers;
import net.persei.dionysus.players.AudioPlayer;
import net.persei.dionysus.players.PlayerType;
import uk.co.caprica.vlcj.player.MediaPlayer;
public class MusicManager {
static private int BASE_VOLUME = 100;
private String name;
private AudioPlayer[] crossfadePlayers = new AudioPlayer[2];
private boolean[] isPlaying = new boolean[2];
public MusicManager(String name) {
this.name = name;
PlayerManager playerManager = PlayerManager.getInstance();
crossfadePlayers[0] = (AudioPlayer) playerManager.create(PlayerType.Audio, "MusicPlayer_" + name + "_fade0");
crossfadePlayers[1] = (AudioPlayer) playerManager.create(PlayerType.Audio, "MusicPlayer_" + name + "_fade1");
}
public void play(String file, long fadeduration, boolean loop) {
change(file, fadeduration, loop);
}
public void change(String file, long fadeduration, boolean loop) {
if (!isPlaying[0]) {
// use 0
stopPlayer(1, fadeduration);
startPlayer(0, file, fadeduration, loop);
} else if (!isPlaying[1]) {
// use 2
stopPlayer(0, fadeduration);
startPlayer(1, file, fadeduration, loop);
} else {
// no player is applicable
}
}
public void stop(long fadeduration) {
for (int i = 0; i < crossfadePlayers.length; i++)
stopPlayer(i, fadeduration);
}
public void pause() {
// TODO resume
for (AudioPlayer player : crossfadePlayers)
player.pause();
}
private void startPlayer(int playerId, String file, long fadeduration, boolean loop) {
new Thread() {
public void run() {
setPlaying(playerId, true);
MediaPlayer player = crossfadePlayers[playerId].getMediaPlayer();
crossfadePlayers[playerId].playFile(file);
crossfadePlayers[playerId].setLoop(loop);
if (fadeduration == 0) {
player.setVolume(BASE_VOLUME);
return;
}
player.setVolume(0);
int targetVolume = BASE_VOLUME;
int sourceVolume = 0;
int stepsPerSecond = 10;
int numberOfSteps = (int) ((fadeduration * stepsPerSecond) / 1000);
int msPerStep = (int) (fadeduration / numberOfSteps);
int incrementPerStep = (sourceVolume - targetVolume) / numberOfSteps;
try {
for (int i = 0; i < numberOfSteps; i++) {
player.setVolume(player.getVolume() + incrementPerStep);
Thread.sleep(msPerStep);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
private synchronized void setPlaying(int playerId, boolean playing) {
isPlaying[playerId] = playing;
}
private void stopPlayer(int playerId, long fadeduration) {
new Thread() {
public void run() {
if (!crossfadePlayers[playerId].isPlaying())
return;
MediaPlayer player = crossfadePlayers[playerId].getMediaPlayer();
int targetVolume = 0;
int sourceVolume = player.getVolume();
int stepsPerSecond = 10;
int numberOfSteps = (int) ((fadeduration * stepsPerSecond) / 1000);
int msPerStep = (int) (fadeduration / numberOfSteps);
int decrementPerStep = (sourceVolume - targetVolume) / numberOfSteps;
try {
for (int i = 0; i < numberOfSteps; i++) {
player.setVolume(player.getVolume() - decrementPerStep);
Thread.sleep(msPerStep);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
setPlaying(playerId, false);
crossfadePlayers[playerId].stop();
}
}.start();
}
}

View file

@ -2,9 +2,24 @@ package net.persei.dionysus.managers;
import java.util.LinkedList;
import net.persei.dionysus.events.Event;
public class Sequence extends LinkedList<Event> {
public Sequence(Sequence context) {
super(context);
}
public Sequence() {
super();
}
public Sequence append(Event event) {
add(event);
return this;
}
public Sequence append(Sequence sequence) {
addAll(sequence);
return this;
}
}

View file

@ -0,0 +1,35 @@
package net.persei.dionysus.managers;
import java.util.LinkedList;
import java.util.List;
import net.persei.dionysus.players.AudioPlayer;
import net.persei.dionysus.players.PlayerType;
public class SoundFXManager {
private String name;
private List<AudioPlayer> players = new LinkedList<>();
public SoundFXManager(String name) {
this.name = name;
}
public void play(String file) {
for (AudioPlayer player : players) {
if (player.isPlaying())
continue;
player.playFile(file);
return;
}
AudioPlayer player = (AudioPlayer) PlayerManager.getInstance().create(PlayerType.Audio,
"FXPlayer_" + name + "_" + players.size());
players.add(player);
player.playFile(file);
}
public void stopAll() {
for (AudioPlayer player : players) {
player.stop();
}
}
}

View file

@ -0,0 +1,37 @@
package net.persei.dionysus.managers;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import net.persei.dionysus.players.VideoPlayer;
public class VideoManager {
private String name;
private PlayerManager playerManager = PlayerManager.getInstance();
public VideoManager(String name) {
this.name = name;
}
public VideoPlayer getVideoPlayer(String name) {
return (VideoPlayer) playerManager.getByName(name);
}
public void play(String name, String file, boolean loop) {
getVideoPlayer(name).playFile(file);
getVideoPlayer(name).setLoop(loop);
}
public void play(String name) {
getVideoPlayer(name).play();
}
public void stop(String name) {
getVideoPlayer(name).stop();
}
public void pause(String name) {
getVideoPlayer(name).pause();
}
}

View file

@ -42,4 +42,14 @@ public class AudioPlayer implements Player {
public String getName() {
return name;
}
@Override
public void stop() {
getMediaPlayer().stop();
}
@Override
public boolean isPlaying() {
return getMediaPlayer().isPlaying();
}
}

View file

@ -6,6 +6,8 @@ public interface Player {
boolean isLoop();
void playFile(String file);
void play();
boolean isPlaying();
void stop();
void pause();
void setLoop(boolean loop);
MediaPlayer getMediaPlayer();

View file

@ -85,4 +85,14 @@ public class VideoPlayer extends JFrame implements Player {
public String getName() {
return name;
}
@Override
public void stop() {
getMediaPlayer().stop();
}
@Override
public boolean isPlaying() {
return getMediaPlayer().isPlaying();
}
}