Refactor output streaming for readability
The core loop was put together confusingly; this encapsulates the process of constructing an OutputStream and reformats some.
This commit is contained in:
@@ -208,49 +208,32 @@ public class StreamController {
|
|||||||
|
|
||||||
status = statusService.createStreamStatus(player);
|
status = statusService.createStreamStatus(player);
|
||||||
|
|
||||||
in = new PlayQueueInputStream(player, status, maxBitRate, preferredTargetFormat, videoTranscodingSettings, transcodingService,
|
in = new PlayQueueInputStream(player, status, maxBitRate, preferredTargetFormat, videoTranscodingSettings,
|
||||||
audioScrobblerService, mediaFileService, searchService);
|
transcodingService, audioScrobblerService, mediaFileService, searchService);
|
||||||
OutputStream out = RangeOutputStream.wrap(response.getOutputStream(), range);
|
|
||||||
|
|
||||||
// Enabled SHOUTcast, if requested.
|
try (OutputStream out = makeOutputStream(request, response, range, isSingleFile, player, settingsService)) {
|
||||||
boolean isShoutCastRequested = "1".equals(request.getHeader("icy-metadata"));
|
final int BUFFER_SIZE = 2048;
|
||||||
if (isShoutCastRequested && !isSingleFile) {
|
byte[] buf = new byte[BUFFER_SIZE];
|
||||||
response.setHeader("icy-metaint", "" + ShoutCastOutputStream.META_DATA_INTERVAL);
|
|
||||||
response.setHeader("icy-notice1", "This stream is served using Airsonic");
|
|
||||||
response.setHeader("icy-notice2", "Airsonic - Free media streamer");
|
|
||||||
response.setHeader("icy-name", "Airsonic");
|
|
||||||
response.setHeader("icy-genre", "Mixed");
|
|
||||||
response.setHeader("icy-url", "https://airsonic.github.io/");
|
|
||||||
out = new ShoutCastOutputStream(out, player.getPlayQueue(), settingsService);
|
|
||||||
}
|
|
||||||
|
|
||||||
final int BUFFER_SIZE = 2048;
|
while (!status.terminated()) {
|
||||||
byte[] buf = new byte[BUFFER_SIZE];
|
if (player.getPlayQueue().getStatus() == PlayQueue.Status.STOPPED) {
|
||||||
|
|
||||||
while (true) {
|
|
||||||
|
|
||||||
// Check if stream has been terminated.
|
|
||||||
if (status.terminated()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player.getPlayQueue().getStatus() == PlayQueue.Status.STOPPED) {
|
|
||||||
if (isPodcast || isSingleFile) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
sendDummy(buf, out);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
int n = in.read(buf);
|
|
||||||
if (n == -1) {
|
|
||||||
if (isPodcast || isSingleFile) {
|
if (isPodcast || isSingleFile) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
sendDummy(buf, out);
|
sendDummy(buf, out);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out.write(buf, 0, n);
|
|
||||||
|
int n = in.read(buf);
|
||||||
|
if (n == -1) {
|
||||||
|
if (isPodcast || isSingleFile) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
sendDummy(buf, out);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.write(buf, 0, n);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -283,6 +266,31 @@ public class StreamController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct an appropriate output stream based on the request.
|
||||||
|
* <p>
|
||||||
|
* This is responsible for limiting the output to the given range (if not null) and injecting Shoutcast metadata
|
||||||
|
* into the stream if requested.
|
||||||
|
*/
|
||||||
|
private OutputStream makeOutputStream(HttpServletRequest request, HttpServletResponse response, HttpRange range,
|
||||||
|
boolean isSingleFile, Player player, SettingsService settingsService)
|
||||||
|
throws IOException {
|
||||||
|
OutputStream out = RangeOutputStream.wrap(response.getOutputStream(), range);
|
||||||
|
|
||||||
|
// Enabled SHOUTcast, if requested.
|
||||||
|
boolean isShoutCastRequested = "1".equals(request.getHeader("icy-metadata"));
|
||||||
|
if (isShoutCastRequested && !isSingleFile) {
|
||||||
|
response.setHeader("icy-metaint", "" + ShoutCastOutputStream.META_DATA_INTERVAL);
|
||||||
|
response.setHeader("icy-notice1", "This stream is served using Airsonic");
|
||||||
|
response.setHeader("icy-notice2", "Airsonic - Free media streamer");
|
||||||
|
response.setHeader("icy-name", "Airsonic");
|
||||||
|
response.setHeader("icy-genre", "Mixed");
|
||||||
|
response.setHeader("icy-url", "https://airsonic.github.io/");
|
||||||
|
out = new ShoutCastOutputStream(out, player.getPlayQueue(), settingsService);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
private void setContentDuration(HttpServletResponse response, MediaFile file) {
|
private void setContentDuration(HttpServletResponse response, MediaFile file) {
|
||||||
if (file.getDurationSeconds() != null) {
|
if (file.getDurationSeconds() != null) {
|
||||||
response.setHeader("X-Content-Duration", String.format("%.1f", file.getDurationSeconds().doubleValue()));
|
response.setHeader("X-Content-Duration", String.format("%.1f", file.getDurationSeconds().doubleValue()));
|
||||||
|
|||||||
Reference in New Issue
Block a user