diff --git a/README.md b/README.md
index 99c3862..d852172 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,13 @@
-# Java-stream-player
-Java Audio Controller Library with (seek,start,stop,pause,play,restart features)
-
-This is a continuation and full improvement of [JavaZoom BasicPlayer](http://www.javazoom.net/jlgui/api.html)
-
[](https://github.com/goxr3plus/java-stream-player/releases)
[](http://hits.dwyl.io/goxr3plus/java-stream-player)
+# Java-stream-player
+Java Audio Controller Library with (skip,skipTo,start,stop,pause,play,restart features)
+This is the next version of [JavaZoom BasicPlayer](http://www.javazoom.net/jlgui/api.html)
+
### What audio formats it supports?
It supports **WAV, AU, AIFF, MP3, OGG VORBIS, FLAC, MONKEY's AUDIO and SPEEX audio formats** , using some external libraries . Although more will be added in future releases.
@@ -33,26 +32,6 @@ https://jitpack.io/private#goxr3plus/java-stream-player
```
-## Java Audio Tutorials and API's by GOXR3PLUS STUDIO
- - **Spectrum Analyzers**
- - [Java-Audio-Wave-Spectrum-API](https://github.com/goxr3plus/Java-Audio-Wave-Spectrum-API)
- 
- - [Jave Spectrum Analyzers from Audio](https://github.com/goxr3plus/Java-Spectrum-Analyser-Tutorials)
- - [Capture Audio from Microphone and make complex spectrum analyzers](https://github.com/goxr3plus/Java-Microphone-Audio-Spectrum-Analyzers-Tutorial)
-
- - **Java multiple audio formats player**
- - [Java-stream-player](https://github.com/goxr3plus/java-stream-player)
-
- - **Speech Recognition/Translation/Synthenizers**
- - [Java Speech Recognition/Translation/Synthesizer based on Google Cloud Services](https://github.com/goxr3plus/java-google-speech-api)
- - [Java-Speech-Recognizer-Tutorial--Calculator](https://github.com/goxr3plus/Java-Speech-Recognizer-Tutorial--Calculator)
- - [Java+MaryTTS=Java Text To Speech](https://github.com/goxr3plus/Java-Text-To-Speech-Tutorial)
- - [Java Speech Recognition Program based on Google Cloud Services ](https://github.com/goxr3plus/Java-Google-Speech-Recognizer)
- - [Java Google Text To Speech](https://github.com/goxr3plus/Java-Google-Text-To-Speech)
- - [Full Google Translate Support using Java](https://github.com/goxr3plus/java-google-translator)
- - [Professional Java Google Desktop Translator](https://github.com/goxr3plus/Java-Google-Desktop-Translator)
-
-
Example usage :
``` JAVA
@@ -71,123 +50,145 @@ import com.goxr3plus.streamplayer.stream.StreamPlayerException;
*/
public class Main extends StreamPlayer implements StreamPlayerListener {
- private final String audioAbsolutePath = "Logic - Ballin [Bass Boosted].mp3";
-
- /**
- * Constructor
- */
- public Main() {
-
- try {
+ private final String audioAbsolutePath = "Logic - Ballin [Bass Boosted].mp3";
- // Register to the Listeners
- addStreamPlayerListener(this);
+ /**
+ * Constructor
+ */
+ public Main() {
- // Open a File
- // open(new File("...")) //..Here must be the file absolute path
- // open(INPUTSTREAM)
- // open(AUDIOURL)
+ try {
- // Example
- open(new File(audioAbsolutePath));
+ // Register to the Listeners
+ addStreamPlayerListener(this);
- //Seek by bytes
- //seekBytes(500000L);
+ // Open a File
+ // open(new File("...")) //..Here must be the file absolute path
+ // open(INPUTSTREAM)
+ // open(AUDIOURL)
- //Seek +x seconds starting from the current position
- seekSeconds(15);
- seekSeconds(15);
+ // Example
+ open(new File(audioAbsolutePath));
- /* Seek starting from the begginning of the audio */
- //seekTo(200);
+ // Seek by bytes
+ // seekBytes(500000L);
- // Play it
- play();
- //pause();
+ // Seek +x seconds starting from the current position
+ seekSeconds(15);
+ seekSeconds(15);
- } catch (final Exception ex) {
- ex.printStackTrace();
- }
+ /* Seek starting from the begginning of the audio */
+ // seekTo(200);
- }
+ // Play it
+ play();
+ // pause();
- @Override
- public void opened(final Object dataSource, final Map properties) {
+ } catch (final Exception ex) {
+ ex.printStackTrace();
+ }
- }
+ }
- @Override
- public void progress(final int nEncodedBytes, final long microsecondPosition, final byte[] pcmData,final Map properties) {
+ @Override
+ public void opened(final Object dataSource, final Map properties) {
-// System.out.println("Encoded Bytes : " + nEncodedBytes);
+ }
- // Current time position in seconds:) by GOXR3PLUS STUDIO
- // This is not the more precise way ...
- // in XR3Player i am using different techniques .
- //https://github.com/goxr3plus/XR3Player
- // Just for demostration purposes :)
- // I will add more advanced techniques with milliseconds , microseconds , hours
- // and minutes soon
+ @Override
+ public void progress(final int nEncodedBytes, final long microsecondPosition, final byte[] pcmData,
+ final Map properties) {
- // .MP3 OR .WAV
- final String extension = "mp3"; //THE SAMPLE Audio i am using is .MP3 SO ... :)
+ // System.out.println("Encoded Bytes : " + nEncodedBytes);
- long totalBytes = getTotalBytes();
- if ("mp3".equals(extension) || "wav".equals(extension)) {
+ // Current time position in seconds:) by GOXR3PLUS STUDIO
+ // This is not the more precise way ...
+ // in XR3Player i am using different techniques .
+ // https://github.com/goxr3plus/XR3Player
+ // Just for demostration purposes :)
+ // I will add more advanced techniques with milliseconds , microseconds , hours
+ // and minutes soon
- // Calculate the progress until now
- double progress = (nEncodedBytes > 0 && totalBytes > 0)
- ? (nEncodedBytes * 1.0f / totalBytes * 1.0f)
- : -1.0f;
-// System.out.println(progress*100+"%");
+ // .MP3 OR .WAV
+ final String extension = "mp3"; // THE SAMPLE Audio i am using is .MP3 SO ... :)
- System.out.println("Seconds : " + (int) (microsecondPosition / 1000000) + " s " + "Progress: [ " + progress * 100 + " ] %");
+ long totalBytes = getTotalBytes();
+ if ("mp3".equals(extension) || "wav".equals(extension)) {
+ // Calculate the progress until now
+ double progress = (nEncodedBytes > 0 && totalBytes > 0) ? (nEncodedBytes * 1.0f / totalBytes * 1.0f)
+ : -1.0f;
+ // System.out.println(progress*100+"%");
- // .WHATEVER MUSIC FILE*
- } else {
- //System.out.println("Current time is : " + (int) (microsecondPosition / 1000000) + " seconds");
- }
+ System.out.println("Seconds : " + (int) (microsecondPosition / 1000000) + " s " + "Progress: [ "
+ + progress * 100 + " ] %");
+ // .WHATEVER MUSIC FILE*
+ } else {
+ // System.out.println("Current time is : " + (int) (microsecondPosition /
+ // 1000000) + " seconds");
+ }
- }
+ }
- @Override
- public void statusUpdated(final StreamPlayerEvent streamPlayerEvent) {
+ @Override
+ public void statusUpdated(final StreamPlayerEvent streamPlayerEvent) {
- // Player status
- final Status status = streamPlayerEvent.getPlayerStatus();
- //System.out.println(streamPlayerEvent.getPlayerStatus());
+ // Player status
+ final Status status = streamPlayerEvent.getPlayerStatus();
+ // System.out.println(streamPlayerEvent.getPlayerStatus());
- //Examples
+ // Examples
- if (status == Status.OPENED) {
+ if (status == Status.OPENED) {
- } else if (status == Status.OPENING) {
+ } else if (status == Status.OPENING) {
- } else if (status == Status.RESUMED) {
+ } else if (status == Status.RESUMED) {
- } else if (status == Status.PLAYING) {
+ } else if (status == Status.PLAYING) {
- } else if (status == Status.STOPPED) {
+ } else if (status == Status.STOPPED) {
- } else if (status == Status.SEEKING) {
+ } else if (status == Status.SEEKING) {
- } else if (status == Status.SEEKED) {
+ } else if (status == Status.SEEKED) {
- }
+ }
- //etc... SEE XR3PLAYER https://github.com/goxr3plus/XR3Player for advanced examples
- }
+ // etc... SEE XR3PLAYER https://github.com/goxr3plus/XR3Player for advanced
+ // examples
+ }
- public static void main(final String[] args) {
- new Main();
- }
+ public static void main(final String[] args) {
+ new Main();
+ }
}
```
+## Java Audio Tutorials and API's by GOXR3PLUS STUDIO
+ - **Spectrum Analyzers**
+ - [Java-Audio-Wave-Spectrum-API](https://github.com/goxr3plus/Java-Audio-Wave-Spectrum-API)
+ 
+ - [Jave Spectrum Analyzers from Audio](https://github.com/goxr3plus/Java-Spectrum-Analyser-Tutorials)
+ - [Capture Audio from Microphone and make complex spectrum analyzers](https://github.com/goxr3plus/Java-Microphone-Audio-Spectrum-Analyzers-Tutorial)
+
+ - **Java multiple audio formats player**
+ - [Java-stream-player](https://github.com/goxr3plus/java-stream-player)
+
+ - **Speech Recognition/Translation/Synthenizers**
+ - [Java Speech Recognition/Translation/Synthesizer based on Google Cloud Services](https://github.com/goxr3plus/java-google-speech-api)
+ - [Java-Speech-Recognizer-Tutorial--Calculator](https://github.com/goxr3plus/Java-Speech-Recognizer-Tutorial--Calculator)
+ - [Java+MaryTTS=Java Text To Speech](https://github.com/goxr3plus/Java-Text-To-Speech-Tutorial)
+ - [Java Speech Recognition Program based on Google Cloud Services ](https://github.com/goxr3plus/Java-Google-Speech-Recognizer)
+ - [Java Google Text To Speech](https://github.com/goxr3plus/Java-Google-Text-To-Speech)
+ - [Full Google Translate Support using Java](https://github.com/goxr3plus/java-google-translator)
+ - [Professional Java Google Desktop Translator](https://github.com/goxr3plus/Java-Google-Desktop-Translator)
+
+
+
---
### Looking for a ffmpeg wrapper in Java ?
diff --git a/pom.xml b/pom.xml
index c0f4f2a..fc849b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.github.goxr3plus
@@ -13,7 +13,7 @@
1.8
1.8
UTF-8
- 5.5.1
+ 5.1.1
@@ -165,6 +165,13 @@
test
+
+
+ org.mockito
+ mockito-junit-jupiter
+ 3.0.0
+ test
+
diff --git a/src/main/java/com/goxr3plus/streamplayer/application/AnotherDemoApplication.java b/src/main/java/com/goxr3plus/streamplayer/application/AnotherDemoApplication.java
new file mode 100644
index 0000000..5bd49e8
--- /dev/null
+++ b/src/main/java/com/goxr3plus/streamplayer/application/AnotherDemoApplication.java
@@ -0,0 +1,74 @@
+package com.goxr3plus.streamplayer.application;
+
+import com.goxr3plus.streamplayer.enums.Status;
+import com.goxr3plus.streamplayer.stream.StreamPlayer;
+import com.goxr3plus.streamplayer.stream.StreamPlayerEvent;
+import com.goxr3plus.streamplayer.stream.StreamPlayerListener;
+
+import java.io.File;
+import java.util.Map;
+
+/**
+ * @author GOXR3PLUS
+ *
+ */
+public class AnotherDemoApplication {
+
+ private final String audioFileName = "Logic - Ballin [Bass Boosted].mp3";
+
+ private StreamPlayer streamPlayer;
+ private StreamPlayerListener listener;
+
+ public AnotherDemoApplication(StreamPlayer streamPlayer) {
+ this.streamPlayer = streamPlayer;
+ this.listener = new AnotherStreamPlayerListener(audioFileName, streamPlayer);
+
+ }
+
+
+ void start() {
+ try {
+
+ // Register to the Listeners
+ streamPlayer.addStreamPlayerListener(listener);
+
+ // Open a File
+ // open(new File("...")) //..Here must be the file absolute path
+ // open(INPUTSTREAM)
+ // open(AUDIOURL)
+
+ // Example
+ streamPlayer.open(new File(audioFileName));
+
+ //Seek by bytes
+ //seekBytes(500000L);
+
+ //Seek +x seconds starting from the current position
+ streamPlayer.seekSeconds(15); // forward 15 seconds
+ streamPlayer.seekSeconds(15); // forward 15 seconds again
+
+ /* Seek starting from the begginning of the audio */
+ //seekTo(200);
+
+ // Play it
+ streamPlayer.play();
+ //pause();
+
+ } catch (final Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+
+
+
+
+ private String getExtension(String audioFileName) {
+ return audioFileName.split("\\.(?=[^.]+$)")[1];
+ }
+
+
+// public static void main(final String[] args) {
+// new AnotherDemoApplication();
+// }
+
+}
diff --git a/src/main/java/com/goxr3plus/streamplayer/application/AnotherMain.java b/src/main/java/com/goxr3plus/streamplayer/application/AnotherMain.java
new file mode 100644
index 0000000..d8bfdb0
--- /dev/null
+++ b/src/main/java/com/goxr3plus/streamplayer/application/AnotherMain.java
@@ -0,0 +1,15 @@
+package com.goxr3plus.streamplayer.application;
+
+import com.goxr3plus.streamplayer.stream.StreamPlayer;
+import com.goxr3plus.streamplayer.stream.StreamPlayerListener;
+
+public class AnotherMain {
+ public static void main(String[] args) {
+
+ final StreamPlayer streamPlayer = new StreamPlayer();
+ final AnotherDemoApplication application = new AnotherDemoApplication(streamPlayer);
+ application.start();
+
+ }
+
+}
diff --git a/src/main/java/com/goxr3plus/streamplayer/application/AnotherStreamPlayerListener.java b/src/main/java/com/goxr3plus/streamplayer/application/AnotherStreamPlayerListener.java
new file mode 100644
index 0000000..2b27805
--- /dev/null
+++ b/src/main/java/com/goxr3plus/streamplayer/application/AnotherStreamPlayerListener.java
@@ -0,0 +1,88 @@
+package com.goxr3plus.streamplayer.application;
+
+import com.goxr3plus.streamplayer.enums.Status;
+import com.goxr3plus.streamplayer.stream.StreamPlayer;
+import com.goxr3plus.streamplayer.stream.StreamPlayerEvent;
+import com.goxr3plus.streamplayer.stream.StreamPlayerListener;
+
+import java.util.Map;
+
+class AnotherStreamPlayerListener implements StreamPlayerListener {
+
+ private final String audioFileName;
+ private StreamPlayer streamPlayer;
+
+
+ public AnotherStreamPlayerListener(String audioFileName, StreamPlayer streamPlayer) {
+ this.audioFileName = audioFileName;
+ this.streamPlayer = streamPlayer;
+ }
+
+ /**
+ * It is called when the StreamPlayer open(Object object) method is called.
+ *
+ * @param dataSource the data source
+ * @param properties the properties
+ */
+ @Override
+ public void opened(Object dataSource, Map properties) {
+ System.out.println("The StreamPlayer was opened.");
+ }
+
+ /**
+ * Is called several times per second when StreamPlayer run method is
+ * running.
+ *
+ * @param nEncodedBytes the n encoded bytes
+ * @param microsecondPosition the microsecond position
+ * @param pcmData the pcm data
+ * @param properties the properties
+ */
+ @Override
+ public void progress(int nEncodedBytes, long microsecondPosition, byte[] pcmData, Map properties) {
+
+ String extension = getExtension(audioFileName);
+
+
+ long totalBytes = streamPlayer.getTotalBytes();
+ if ("mp3".equals(extension) || "wav".equals(extension)) {
+
+ // Calculate the progress until now
+ double progress = (nEncodedBytes > 0 && totalBytes > 0)
+ ? ((double) nEncodedBytes / (double)totalBytes )
+ : -1.0d;
+
+ // TODO: Understand why the nEncodedBytes doesn't update each call of progress.
+
+ System.out.println("Seconds : " + (int) (microsecondPosition / 1000000) + " s " + "Progress: [ " + progress * 100 + " ] %");
+ final String message = String.format("Time: %.1f s, Progress: %.2f %%, encoded %d of %d bytes.",
+ microsecondPosition / 1000000d,
+ progress * 100d,
+ nEncodedBytes,
+ totalBytes);
+ System.out.println(message);
+ }
+
+
+ }
+
+ /**
+ * Is called every time the status of the StreamPlayer changes.
+ *
+ * @param event the event
+ */
+ @Override
+ public void statusUpdated(StreamPlayerEvent event) {
+ // Player status
+ final Status status = event.getPlayerStatus();
+
+ // Do different things depending on the status.
+ // See XR3PLAYER https://github.com/goxr3plus/XR3Player for advanced examples
+
+ }
+
+ private String getExtension(String audioFileName) {
+ return audioFileName.split("\\.(?=[^.]+$)")[1];
+ }
+
+}
diff --git a/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayer.java b/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayer.java
index a2b644f..0bd6935 100644
--- a/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayer.java
+++ b/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayer.java
@@ -742,7 +742,7 @@ else if (previousStatus == Status.PAUSED) {
* @param seconds Seconds to Skip
*/
//todo not finished needs more validations
- public long seekSeconds(int seconds) throws Exception {
+ public long seekSeconds(int seconds) throws StreamPlayerException {
int durationInSeconds = this.getDurationInSeconds();
//Validate
@@ -774,7 +774,7 @@ public long seekSeconds(int seconds) throws Exception {
*
* @param seconds Seconds to Skip
*/
- public long seekTo(int seconds) throws Exception {
+ public long seekTo(int seconds) throws StreamPlayerException {
int durationInSeconds = this.getDurationInSeconds();
//Validate
@@ -800,11 +800,11 @@ public long seekTo(int seconds) throws Exception {
// seek(bytes);
// }
- private void validateSeconds(int seconds, int durationInSeconds) throws Exception {
+ private void validateSeconds(int seconds, int durationInSeconds) {
if (seconds < 0) {
- throw new Exception("Trying to skip negative seconds ");
+ throw new UnsupportedOperationException("Trying to skip negative seconds ");
} else if (seconds >= durationInSeconds) {
- throw new Exception("Trying to skip with seconds {" + seconds + "} > maximum {" + durationInSeconds + "}");
+ throw new UnsupportedOperationException("Trying to skip with seconds {" + seconds + "} > maximum {" + durationInSeconds + "}");
}
}
diff --git a/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayerEventLauncher.java b/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayerEventLauncher.java
index 525c4bf..b6766c9 100644
--- a/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayerEventLauncher.java
+++ b/src/main/java/com/goxr3plus/streamplayer/stream/StreamPlayerEventLauncher.java
@@ -73,7 +73,7 @@ public StreamPlayerEventLauncher(Object source, Status playerStatus, int encoded
}
@Override
- public String call() throws Exception {
+ public String call() {
// Notify all the listeners that the state has been updated
if (listeners != null) {
listeners.forEach(listener -> listener
diff --git a/src/test/java/com/goxr3plus/streamplayer/stream/StreamPlayerTest.java b/src/test/java/com/goxr3plus/streamplayer/stream/StreamPlayerTest.java
new file mode 100644
index 0000000..815da0e
--- /dev/null
+++ b/src/test/java/com/goxr3plus/streamplayer/stream/StreamPlayerTest.java
@@ -0,0 +1,44 @@
+package com.goxr3plus.streamplayer.stream;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import java.io.File;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+class StreamPlayerTest {
+
+ @Test
+ @DisplayName("Demonstration of spying")
+ void demonstrationOfSpyng() throws StreamPlayerException {
+
+ final File audioFile = new File("Logic - Ballin [Bass Boosted].mp3");
+
+ // Setup the spy
+ final StreamPlayer streamPlayer = new StreamPlayer();
+ final StreamPlayer spy = spy(streamPlayer);
+
+ // Execute & verify
+
+ // Call open, via the spy
+ spy.open(audioFile);
+
+ // verify that getEncodedStreamPosition is called exactly two times
+ verify(spy, times(2)).getEncodedStreamPosition();
+
+ // Call play, via the spy
+ spy.play();
+
+ // Verify that getEncodedStreamPosition is now called 3 times (the 2 previous times + one more time)
+ verify(spy, times(3)).getEncodedStreamPosition();
+
+ spy.stop();
+ // Verify that there are in total 4 calls of getEncodedStreamPosition after the player is stopped.
+ verify(spy, times(4)).getEncodedStreamPosition();
+
+ // We can only spy on public methods.
+ // TODO: Look into initAudioInputStream, and check if we really need to call getEncodedStreamPosition() twice.
+ }
+}
\ No newline at end of file