Skip to content

Commit 77a5584

Browse files
committed
Refactored Decoder into librespot-decoder-api
1 parent 2f1cda4 commit 77a5584

File tree

20 files changed

+182
-81
lines changed

20 files changed

+182
-81
lines changed

decoder-api/pom.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<!--
2+
~ Copyright 2021 devgianlu
3+
~
4+
~ Licensed under the Apache License, Version 2.0 (the "License");
5+
~ you may not use this file except in compliance with the License.
6+
~ You may obtain a copy of the License at
7+
~
8+
~ http://www.apache.org/licenses/LICENSE-2.0
9+
~
10+
~ Unless required by applicable law or agreed to in writing, software
11+
~ distributed under the License is distributed on an "AS IS" BASIS,
12+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
~ See the License for the specific language governing permissions and
14+
~ limitations under the License.
15+
-->
16+
17+
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
18+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
19+
<modelVersion>4.0.0</modelVersion>
20+
21+
<parent>
22+
<groupId>xyz.gianlu.librespot</groupId>
23+
<artifactId>librespot-java</artifactId>
24+
<version>1.5.6-SNAPSHOT</version>
25+
<relativePath>../pom.xml</relativePath>
26+
</parent>
27+
28+
<artifactId>librespot-decoder-api</artifactId>
29+
<packaging>jar</packaging>
30+
31+
<name>librespot-java decoder API</name>
32+
33+
<dependencies>
34+
<dependency>
35+
<groupId>xyz.gianlu.librespot</groupId>
36+
<artifactId>librespot-sink-api</artifactId>
37+
<version>${project.version}</version>
38+
</dependency>
39+
40+
<!-- Logging -->
41+
<dependency>
42+
<groupId>org.slf4j</groupId>
43+
<artifactId>slf4j-api</artifactId>
44+
<version>${slf4j-api.version}</version>
45+
</dependency>
46+
</dependencies>
47+
</project>

player/src/main/java/xyz/gianlu/librespot/player/decoders/Decoder.java renamed to decoder-api/src/main/java/xyz/gianlu/librespot/player/decoders/Decoder.java

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,27 @@
1919
import org.jetbrains.annotations.NotNull;
2020
import org.slf4j.Logger;
2121
import org.slf4j.LoggerFactory;
22-
import xyz.gianlu.librespot.audio.AbsChunkedInputStream;
23-
import xyz.gianlu.librespot.audio.GeneralAudioStream;
2422
import xyz.gianlu.librespot.player.mixing.output.OutputAudioFormat;
2523

2624
import java.io.Closeable;
2725
import java.io.IOException;
2826
import java.io.OutputStream;
2927

3028
/**
31-
* @author Gianlu
29+
* @author devgianlu
3230
*/
3331
public abstract class Decoder implements Closeable {
3432
public static final int BUFFER_SIZE = 2048;
3533
private static final Logger LOGGER = LoggerFactory.getLogger(Decoder.class);
36-
protected final AbsChunkedInputStream audioIn;
34+
protected final SeekableInputStream audioIn;
3735
protected final float normalizationFactor;
3836
protected final int duration;
39-
private final GeneralAudioStream audioFile;
4037
protected volatile boolean closed = false;
4138
protected int seekZero = 0;
4239
private OutputAudioFormat format;
4340

44-
public Decoder(@NotNull GeneralAudioStream audioFile, float normalizationFactor, int duration) {
45-
this.audioIn = audioFile.stream();
46-
this.audioFile = audioFile;
41+
public Decoder(@NotNull SeekableInputStream audioIn, float normalizationFactor, int duration) {
42+
this.audioIn = audioIn;
4743
this.duration = duration;
4844
this.normalizationFactor = normalizationFactor;
4945
}
@@ -106,14 +102,6 @@ public final int size() {
106102
return audioIn.size();
107103
}
108104

109-
public final int decodedLength() {
110-
return audioIn.decodedLength();
111-
}
112-
113-
public final int decryptTimeMs() {
114-
return audioFile.decryptTimeMs();
115-
}
116-
117105
public static class CannotGetTimeException extends Exception {
118106
public CannotGetTimeException(String message) {
119107
super(message);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright 2021 devgianlu
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package xyz.gianlu.librespot.player.decoders;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
22+
/**
23+
* @author devgianlu
24+
*/
25+
public abstract class SeekableInputStream extends InputStream {
26+
public abstract int size();
27+
28+
public abstract int position();
29+
30+
public abstract void seek(int seekZero) throws IOException;
31+
32+
public abstract long skip(long skip) throws IOException;
33+
34+
public abstract int read(byte[] buffer, int index, int length) throws IOException;
35+
36+
public abstract void close();
37+
38+
public abstract int decodedLength();
39+
}

lib/pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,24 @@
8282
</build>
8383

8484
<dependencies>
85+
<dependency>
86+
<groupId>xyz.gianlu.librespot</groupId>
87+
<artifactId>librespot-decoder-api</artifactId>
88+
<version>${project.version}</version>
89+
</dependency>
90+
91+
<!-- Audio -->
92+
<dependency>
93+
<groupId>org.jcraft</groupId>
94+
<artifactId>jorbis</artifactId>
95+
<version>0.0.17</version>
96+
</dependency>
97+
<dependency>
98+
<groupId>com.badlogicgames.jlayer</groupId>
99+
<artifactId>jlayer</artifactId>
100+
<version>1.0.2-gdx</version>
101+
</dependency>
102+
85103
<!-- Data -->
86104
<dependency>
87105
<groupId>com.google.protobuf</groupId>

lib/src/main/java/xyz/gianlu/librespot/audio/AbsChunkedInputStream.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
package xyz.gianlu.librespot.audio;
1818

1919
import org.jetbrains.annotations.NotNull;
20+
import xyz.gianlu.librespot.player.decoders.SeekableInputStream;
2021

2122
import java.io.IOException;
22-
import java.io.InputStream;
2323

2424
import static xyz.gianlu.librespot.audio.storage.ChannelManager.CHUNK_SIZE;
2525

2626
/**
27-
* @author Gianlu
27+
* @author devgianlu
2828
*/
29-
public abstract class AbsChunkedInputStream extends InputStream implements HaltListener {
29+
public abstract class AbsChunkedInputStream extends SeekableInputStream implements HaltListener {
3030
private static final int PRELOAD_AHEAD = 3;
3131
private static final int PRELOAD_CHUNK_RETRIES = 2;
3232
private static final int MAX_CHUNK_TRIES = 128;
@@ -82,10 +82,12 @@ public final synchronized void reset() {
8282
pos = mark;
8383
}
8484

85-
public final synchronized int pos() {
85+
@Override
86+
public final synchronized int position() {
8687
return pos;
8788
}
8889

90+
@Override
8991
public final synchronized void seek(int where) throws IOException {
9092
if (where < 0) throw new IllegalArgumentException();
9193
if (closed) throw new IOException("Stream is closed!");
@@ -260,6 +262,7 @@ public final void notifyChunkError(int index, @NotNull ChunkException ex) {
260262
}
261263
}
262264

265+
@Override
263266
public int decodedLength() {
264267
return decodedLength;
265268
}

lib/src/main/java/xyz/gianlu/librespot/audio/GeneralAudioStream.java renamed to lib/src/main/java/xyz/gianlu/librespot/audio/DecodedAudioStream.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222

2323
/**
24-
* @author Gianlu
24+
* @author devgianlu
2525
*/
26-
public interface GeneralAudioStream {
26+
public interface DecodedAudioStream {
2727
@NotNull
2828
AbsChunkedInputStream stream();
2929

lib/src/main/java/xyz/gianlu/librespot/audio/PlayableContentFeeder.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ private LoadedStream loadEpisode(@NotNull EpisodeId id, @NotNull AudioQualityPic
183183
}
184184
}
185185

186-
private static class FileAudioStream implements GeneralAudioStream {
186+
private static class FileAudioStream implements DecodedAudioStream {
187187
private static final Logger LOGGER = LoggerFactory.getLogger(FileAudioStream.class);
188188
private final File file;
189189
private final RandomAccessFile raf;
@@ -276,25 +276,25 @@ public int decryptTimeMs() {
276276

277277
public static class LoadedStream {
278278
public final MetadataWrapper metadata;
279-
public final GeneralAudioStream in;
279+
public final DecodedAudioStream in;
280280
public final NormalizationData normalizationData;
281281
public final Metrics metrics;
282282

283-
public LoadedStream(@NotNull Metadata.Track track, @NotNull GeneralAudioStream in, @Nullable NormalizationData normalizationData, @NotNull Metrics metrics) {
283+
public LoadedStream(@NotNull Metadata.Track track, @NotNull DecodedAudioStream in, @Nullable NormalizationData normalizationData, @NotNull Metrics metrics) {
284284
this.metadata = new MetadataWrapper(track, null, null);
285285
this.in = in;
286286
this.normalizationData = normalizationData;
287287
this.metrics = metrics;
288288
}
289289

290-
public LoadedStream(@NotNull Metadata.Episode episode, @NotNull GeneralAudioStream in, @Nullable NormalizationData normalizationData, @NotNull Metrics metrics) {
290+
public LoadedStream(@NotNull Metadata.Episode episode, @NotNull DecodedAudioStream in, @Nullable NormalizationData normalizationData, @NotNull Metrics metrics) {
291291
this.metadata = new MetadataWrapper(null, episode, null);
292292
this.in = in;
293293
this.normalizationData = normalizationData;
294294
this.metrics = metrics;
295295
}
296296

297-
private LoadedStream(@NotNull LocalId id, @NotNull GeneralAudioStream in) {
297+
private LoadedStream(@NotNull LocalId id, @NotNull DecodedAudioStream in) {
298298
this.metadata = new MetadataWrapper(null, null, id);
299299
this.in = in;
300300
this.normalizationData = null;

lib/src/main/java/xyz/gianlu/librespot/audio/cdn/CdnManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ void setUrl(@NotNull HttpUrl url) {
195195
}
196196
}
197197

198-
public class Streamer implements GeneralAudioStream, GeneralWritableStream {
198+
public class Streamer implements DecodedAudioStream, GeneralWritableStream {
199199
private final StreamId streamId;
200200
private final ExecutorService executorService = Executors.newCachedThreadPool(new NameThreadFactory((r) -> "cdn-async-" + r.hashCode()));
201201
private final SuperAudioFormat format;

player/src/main/java/xyz/gianlu/librespot/player/decoders/AudioQuality.java renamed to lib/src/main/java/xyz/gianlu/librespot/audio/decoders/AudioQuality.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package xyz.gianlu.librespot.player.decoders;
17+
package xyz.gianlu.librespot.audio.decoders;
1818

1919
import com.spotify.metadata.Metadata.AudioFile;
2020
import org.jetbrains.annotations.NotNull;

player/src/main/java/xyz/gianlu/librespot/player/decoders/Decoders.java renamed to lib/src/main/java/xyz/gianlu/librespot/audio/decoders/Decoders.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
* limitations under the License.
1515
*/
1616

17-
package xyz.gianlu.librespot.player.decoders;
17+
package xyz.gianlu.librespot.audio.decoders;
1818

1919
import org.jetbrains.annotations.NotNull;
2020
import org.jetbrains.annotations.Nullable;
2121
import org.slf4j.Logger;
2222
import org.slf4j.LoggerFactory;
23-
import xyz.gianlu.librespot.audio.GeneralAudioStream;
2423
import xyz.gianlu.librespot.audio.format.SuperAudioFormat;
24+
import xyz.gianlu.librespot.player.decoders.Decoder;
25+
import xyz.gianlu.librespot.player.decoders.SeekableInputStream;
2526

2627
import java.util.*;
2728

@@ -41,7 +42,7 @@ private Decoders() {
4142
}
4243

4344
@Nullable
44-
public static Decoder initDecoder(@NotNull SuperAudioFormat format, @NotNull GeneralAudioStream audioFile, float normalizationFactor, int duration) {
45+
public static Decoder initDecoder(@NotNull SuperAudioFormat format, @NotNull SeekableInputStream audioIn, float normalizationFactor, int duration) {
4546
Set<Class<? extends Decoder>> set = decoders.get(format);
4647
if (set == null) return null;
4748

@@ -50,7 +51,7 @@ public static Decoder initDecoder(@NotNull SuperAudioFormat format, @NotNull Gen
5051

5152
try {
5253
Class<? extends Decoder> clazz = opt.get();
53-
return clazz.getConstructor(GeneralAudioStream.class, float.class, int.class).newInstance(audioFile, normalizationFactor, duration);
54+
return clazz.getConstructor(SeekableInputStream.class, float.class, int.class).newInstance(audioIn, normalizationFactor, duration);
5455
} catch (ReflectiveOperationException ex) {
5556
LOGGER.error("Failed initializing Codec instance for {}", format, ex);
5657
return null;

0 commit comments

Comments
 (0)