forked from j62/ctbrec
Fix server stuff for new recording path handling
This commit is contained in:
parent
4f526fd13e
commit
90192d9b8f
|
@ -230,5 +230,15 @@ public class JavaFxRecording extends Recording {
|
|||
delegate.setAbsoluteFile(absoluteFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return delegate.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String id) {
|
||||
delegate.setId(id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import java.time.format.DateTimeFormatter;
|
|||
import java.util.EnumSet;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -72,9 +71,6 @@ public class Recording implements Serializable {
|
|||
}
|
||||
|
||||
public String getId() {
|
||||
if (id == null) {
|
||||
id = UUID.randomUUID().toString();
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ public class NextGenLocalRecorder implements Recorder {
|
|||
private Recording createRecording(Download download) throws IOException {
|
||||
Model model = download.getModel();
|
||||
Recording rec = new Recording();
|
||||
rec.setId(UUID.randomUUID().toString());
|
||||
rec.setDownload(download);
|
||||
String recordingFile = download.getPath(model).replaceAll("\\\\", "/");
|
||||
File absoluteFile = new File(config.getSettings().recordingsDir, recordingFile);
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
@ -82,6 +83,10 @@ public class RecordingManager {
|
|||
if (recording.getStatus() == RECORDING || recording.getStatus() == GENERATING_PLAYLIST || recording.getStatus() == POST_PROCESSING) {
|
||||
recording.setStatus(WAITING);
|
||||
}
|
||||
if (recording.getId() == null) {
|
||||
recording.setId(UUID.randomUUID().toString());
|
||||
saveRecording(recording);
|
||||
}
|
||||
if (recordingExists(recording)) {
|
||||
recordings.add(recording);
|
||||
} else {
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.nio.file.Paths;
|
|||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -20,6 +22,8 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.Recording;
|
||||
import ctbrec.recorder.Recorder;
|
||||
|
||||
public class HlsServlet extends AbstractCtbrecServlet {
|
||||
|
||||
|
@ -27,50 +31,69 @@ public class HlsServlet extends AbstractCtbrecServlet {
|
|||
|
||||
private final Config config;
|
||||
|
||||
public HlsServlet(Config config) {
|
||||
private Recorder recorder;
|
||||
|
||||
public HlsServlet(Config config, Recorder recorder) {
|
||||
this.config = config;
|
||||
this.recorder = recorder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
|
||||
|
||||
String contextPath = getServletContext().getContextPath();
|
||||
String request = req.getRequestURI().substring(contextPath.length() + 5);
|
||||
Path recordingsDirPath = Paths.get(config.getSettings().recordingsDir).toAbsolutePath().normalize();
|
||||
Path requestedFilePath = recordingsDirPath.resolve(request).toAbsolutePath().normalize();
|
||||
|
||||
boolean isValidRequestedPath = requestedFilePath.startsWith(recordingsDirPath);
|
||||
if (isValidRequestedPath) {
|
||||
File requestedFile = requestedFilePath.toFile();
|
||||
File requestedFile = requestedFilePath.toFile();
|
||||
try {
|
||||
if (requestedFile.getName().equals("playlist.m3u8")) {
|
||||
try {
|
||||
boolean isRequestAuthenticated = checkAuthentication(req, req.getRequestURI());
|
||||
if (!isRequestAuthenticated) {
|
||||
writeResponse(resp, SC_UNAUTHORIZED, "{\"status\": \"error\", \"msg\": \"HMAC does not match\"}");
|
||||
return;
|
||||
}
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e1) {
|
||||
writeResponse(resp, SC_UNAUTHORIZED, "{\"status\": \"error\", \"msg\": \"Authentication failed\"}");
|
||||
boolean isRequestAuthenticated = checkAuthentication(req, req.getRequestURI());
|
||||
if (!isRequestAuthenticated) {
|
||||
writeResponse(resp, SC_UNAUTHORIZED, "{\"status\": \"error\", \"msg\": \"HMAC does not match\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
servePlaylist(req, resp, requestedFile);
|
||||
} else {
|
||||
if (requestedFile.exists()) {
|
||||
Enumeration<String> headerNames = req.getHeaderNames();
|
||||
while(headerNames.hasMoreElements()) {
|
||||
String header = headerNames.nextElement();
|
||||
LOG.trace("{}: {}", header, req.getHeader(header));
|
||||
}
|
||||
serveSegment(req, resp, requestedFile);
|
||||
String id = request.substring(0, request.indexOf('/'));
|
||||
Optional<Recording> rec = getRecordingById(id);
|
||||
if (rec.isPresent()) {
|
||||
servePlaylist(req, resp, rec.get().getAbsoluteFile());
|
||||
} else {
|
||||
error404(req, resp);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
String id = request.split("/")[0];
|
||||
Optional<Recording> rec = getRecordingById(id);
|
||||
if (rec.isPresent()) {
|
||||
File file = rec.get().getAbsoluteFile();
|
||||
if (LOG.isTraceEnabled()) {
|
||||
Enumeration<String> headerNames = req.getHeaderNames();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String header = headerNames.nextElement();
|
||||
LOG.trace("{}: {}", header, req.getHeader(header));
|
||||
}
|
||||
}
|
||||
serveSegment(req, resp, file);
|
||||
} else {
|
||||
error404(req, resp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
writeResponse(resp, SC_FORBIDDEN, "Stop it!");
|
||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException e1) {
|
||||
writeResponse(resp, SC_UNAUTHORIZED, "{\"status\": \"error\", \"msg\": \"Authentication failed\"}");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Recording> getRecordingById(String id) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
||||
return recorder.getRecordings().stream()
|
||||
.filter(r -> Objects.equals(id, r.getId()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private void writeResponse(HttpServletResponse resp, int code, String body) {
|
||||
try {
|
||||
resp.setStatus(code);
|
||||
|
@ -81,6 +104,7 @@ public class HlsServlet extends AbstractCtbrecServlet {
|
|||
}
|
||||
|
||||
private void error404(HttpServletRequest req, HttpServletResponse resp) {
|
||||
writeResponse(resp, SC_NOT_FOUND, "{\"status\": \"error\", \"msg\": \"Recording not found\"}");
|
||||
resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
@ -90,7 +114,9 @@ public class HlsServlet extends AbstractCtbrecServlet {
|
|||
}
|
||||
|
||||
private void servePlaylist(HttpServletRequest req, HttpServletResponse resp, File requestedFile) throws IOException {
|
||||
serveFile(req, resp, requestedFile, "application/x-mpegURL");
|
||||
LOG.debug("Serving playlist {}", requestedFile);
|
||||
File playlist = new File(requestedFile, "playlist.m3u8");
|
||||
serveFile(req, resp, playlist, "application/x-mpegURL");
|
||||
}
|
||||
|
||||
private void serveFile(HttpServletRequest req, HttpServletResponse resp, File file, String contentType) throws IOException {
|
||||
|
@ -103,6 +129,7 @@ public class HlsServlet extends AbstractCtbrecServlet {
|
|||
byte[] buffer = new byte[1024 * 100];
|
||||
long bytesLeft = range.to - range.from;
|
||||
resp.setContentLengthLong(bytesLeft);
|
||||
resp.addHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");
|
||||
if (range.set) {
|
||||
resp.setHeader("Content-Range", "bytes " + range.from + '-' + range.to + '/' + file.length());
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ public class HttpServer {
|
|||
holder = new ServletHolder(configServlet);
|
||||
defaultContext.addServlet(holder, "/config");
|
||||
|
||||
HlsServlet hlsServlet = new HlsServlet(this.config);
|
||||
HlsServlet hlsServlet = new HlsServlet(this.config, recorder);
|
||||
holder = new ServletHolder(hlsServlet);
|
||||
defaultContext.addServlet(holder, "/hls/*");
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
function play(recording) {
|
||||
let src = recording.singleFile ? '/hls' + recording.path : recording.playlist;
|
||||
let src = recording.singleFile ? '/hls/' + recording.id : recording.playlist;
|
||||
let hmacOfPath = CryptoJS.HmacSHA256(src, hmac);
|
||||
src = '..' + src;
|
||||
if(console) console.log("Path", src, "HMAC", hmacOfPath);
|
||||
|
@ -48,7 +48,7 @@ function play(recording) {
|
|||
}
|
||||
|
||||
function download(recording) {
|
||||
let src = recording.singleFile ? '/hls' + recording.path : recording.playlist;
|
||||
let src = recording.singleFile ? '/hls/' + recording.id : recording.playlist;
|
||||
let hmacOfPath = CryptoJS.HmacSHA256(src, hmac);
|
||||
src = '..' + src;
|
||||
if(console) console.log("Path", src, "HMAC", hmacOfPath);
|
||||
|
@ -77,7 +77,7 @@ function calculateSize(sizeInByte) {
|
|||
function isRecordingInArray(array, recording) {
|
||||
for ( let idx in array) {
|
||||
let r = array[idx];
|
||||
if (r.path === recording.path) {
|
||||
if (r.id === recording.id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -115,10 +115,10 @@ function syncRecordings(recordings) {
|
|||
recording.ko_progressString = ko.observable(recording.progress === -1 ? '' : recording.progress);
|
||||
recording.ko_size = ko.observable(calculateSize(recording.sizeInByte));
|
||||
recording.ko_status = ko.observable(recording.status);
|
||||
if (recording.path.endsWith('.mp4')) {
|
||||
recording.playlist = '/hls' + recording.path;
|
||||
if (recording.singleFile) {
|
||||
recording.playlist = '/hls/' + recording.id;
|
||||
} else {
|
||||
recording.playlist = '/hls' + recording.path + '/playlist.m3u8';
|
||||
recording.playlist = '/hls/' + recording.id + '/playlist.m3u8';
|
||||
}
|
||||
observableRecordingsArray.push(recording);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ function syncRecordings(recordings) {
|
|||
let recording = recordings[i];
|
||||
for ( let j in observableRecordingsArray()) {
|
||||
let r = observableRecordingsArray()[j];
|
||||
if (recording.path === r.path) {
|
||||
if (recording.id === r.id) {
|
||||
r.progress = recording.progress;
|
||||
r.sizeInByte = recording.sizeInByte;
|
||||
r.status = recording.status;
|
||||
|
|
Loading…
Reference in New Issue