More correctly handle stream ranges
When transcoding, always use chunked transfers and report that ranges are not supported. When not transcoding, support returning ranges but only if requested.
This commit is contained in:
@@ -153,28 +153,45 @@ public class StreamController {
|
|||||||
playQueue.addFiles(true, file);
|
playQueue.addFiles(true, file);
|
||||||
player.setPlayQueue(playQueue);
|
player.setPlayQueue(playQueue);
|
||||||
|
|
||||||
if (settingsService.isEnableSeek() && !file.isVideo()) {
|
|
||||||
response.setIntHeader("ETag", file.getId());
|
|
||||||
response.setHeader("Accept-Ranges", "bytes");
|
|
||||||
}
|
|
||||||
|
|
||||||
TranscodingService.Parameters parameters = transcodingService.getParameters(file, player, maxBitRate,
|
TranscodingService.Parameters parameters = transcodingService.getParameters(file, player, maxBitRate,
|
||||||
preferredTargetFormat, null);
|
preferredTargetFormat, null);
|
||||||
long fileLength = getFileLength(parameters);
|
|
||||||
boolean isConversion = parameters.isDownsample() || parameters.isTranscode();
|
boolean isConversion = parameters.isDownsample() || parameters.isTranscode();
|
||||||
boolean estimateContentLength = ServletRequestUtils.getBooleanParameter(request,
|
boolean estimateContentLength = ServletRequestUtils.getBooleanParameter(request,
|
||||||
"estimateContentLength", false);
|
"estimateContentLength", false);
|
||||||
boolean isHls = ServletRequestUtils.getBooleanParameter(request, "hls", false);
|
boolean isHls = ServletRequestUtils.getBooleanParameter(request, "hls", false);
|
||||||
|
|
||||||
range = getRange(request, file);
|
// Wrangle response length and ranges.
|
||||||
if (settingsService.isEnableSeek() && range != null && !file.isVideo()) {
|
//
|
||||||
LOG.info("{}: Got HTTP range: {}", request.getRemoteAddr(), range);
|
// Support ranges as long as we're not transcoding; video is always assumed to transcode
|
||||||
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
if (isConversion || file.isVideo()) {
|
||||||
Util.setContentLength(response, range.isClosed() ? range.size() : fileLength - range.getFirstBytePos());
|
// Use chunked transfer; do not accept range requests
|
||||||
long lastBytePos = range.getLastBytePos() != null ? range.getLastBytePos() : fileLength - 1;
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
response.setHeader("Content-Range", "bytes " + range.getFirstBytePos() + "-" + lastBytePos + "/" + fileLength);
|
response.setHeader("Accept-Ranges", "none");
|
||||||
} else if (!isHls && (!isConversion || estimateContentLength)) {
|
} else {
|
||||||
Util.setContentLength(response, fileLength);
|
// Not transcoding, partial content permitted because we know the final size
|
||||||
|
long contentLength;
|
||||||
|
|
||||||
|
// If range was requested, respond in kind
|
||||||
|
range = getRange(request, file);
|
||||||
|
if (range != null) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
|
||||||
|
response.setHeader("Accept-Ranges", "bytes");
|
||||||
|
|
||||||
|
// Both ends are inclusive
|
||||||
|
long startByte = range.getFirstBytePos();
|
||||||
|
long endByte = range.isClosed() ? range.getLastBytePos() : file.getFileSize() - 1;
|
||||||
|
|
||||||
|
response.setHeader("Content-Range",
|
||||||
|
String.format("bytes %d-%d/%d", startByte, endByte, file.getFileSize()));
|
||||||
|
contentLength = endByte + 1 - startByte;
|
||||||
|
} else {
|
||||||
|
// No range was requested, give back the whole file
|
||||||
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
|
contentLength = file.getFileSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setIntHeader("ETag", file.getId());
|
||||||
|
Util.setContentLength(response, contentLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set content type of response
|
// Set content type of response
|
||||||
|
|||||||
Reference in New Issue
Block a user