forked from j62/ctbrec
Implement splitting for hlsdl downloads
This commit is contained in:
parent
8e22112603
commit
1baa216150
|
@ -2,12 +2,42 @@ package ctbrec.recorder.download;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import ctbrec.Settings;
|
||||||
|
import ctbrec.recorder.download.hls.CombinedSplittingStrategy;
|
||||||
|
import ctbrec.recorder.download.hls.NoopSplittingStrategy;
|
||||||
|
import ctbrec.recorder.download.hls.SizeSplittingStrategy;
|
||||||
|
import ctbrec.recorder.download.hls.TimeSplittingStrategy;
|
||||||
|
|
||||||
public abstract class AbstractDownload implements Download {
|
public abstract class AbstractDownload implements Download {
|
||||||
|
|
||||||
protected Instant startTime;
|
protected Instant startTime;
|
||||||
|
protected transient SplittingStrategy splittingStrategy;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Instant getStartTime() {
|
public Instant getStartTime() {
|
||||||
return startTime;
|
return startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected SplittingStrategy initSplittingStrategy(Settings settings) {
|
||||||
|
SplittingStrategy strategy;
|
||||||
|
switch (settings.splitStrategy) {
|
||||||
|
case TIME:
|
||||||
|
strategy = new TimeSplittingStrategy();
|
||||||
|
break;
|
||||||
|
case SIZE:
|
||||||
|
strategy = new SizeSplittingStrategy();
|
||||||
|
break;
|
||||||
|
case TIME_OR_SIZE:
|
||||||
|
SplittingStrategy timeSplittingStrategy = new TimeSplittingStrategy();
|
||||||
|
SplittingStrategy sizeSplittingStrategy = new SizeSplittingStrategy();
|
||||||
|
strategy = new CombinedSplittingStrategy(timeSplittingStrategy, sizeSplittingStrategy);
|
||||||
|
break;
|
||||||
|
case DONT:
|
||||||
|
default:
|
||||||
|
strategy = new NoopSplittingStrategy();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
strategy.init(settings);
|
||||||
|
return strategy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ import com.iheartradio.m3u8.data.TrackData;
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.Recording.State;
|
import ctbrec.Recording.State;
|
||||||
import ctbrec.Settings;
|
|
||||||
import ctbrec.UnknownModel;
|
import ctbrec.UnknownModel;
|
||||||
import ctbrec.io.BandwidthMeter;
|
import ctbrec.io.BandwidthMeter;
|
||||||
import ctbrec.io.HttpClient;
|
import ctbrec.io.HttpClient;
|
||||||
|
@ -52,7 +51,6 @@ import ctbrec.io.HttpException;
|
||||||
import ctbrec.recorder.PlaylistGenerator.InvalidPlaylistException;
|
import ctbrec.recorder.PlaylistGenerator.InvalidPlaylistException;
|
||||||
import ctbrec.recorder.download.AbstractDownload;
|
import ctbrec.recorder.download.AbstractDownload;
|
||||||
import ctbrec.recorder.download.HttpHeaderFactory;
|
import ctbrec.recorder.download.HttpHeaderFactory;
|
||||||
import ctbrec.recorder.download.SplittingStrategy;
|
|
||||||
import ctbrec.recorder.download.StreamSource;
|
import ctbrec.recorder.download.StreamSource;
|
||||||
import ctbrec.sites.Site;
|
import ctbrec.sites.Site;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
@ -69,7 +67,6 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
|
||||||
protected Model model = new UnknownModel();
|
protected Model model = new UnknownModel();
|
||||||
protected transient LinkedBlockingQueue<Runnable> downloadQueue = new LinkedBlockingQueue<>(50);
|
protected transient LinkedBlockingQueue<Runnable> downloadQueue = new LinkedBlockingQueue<>(50);
|
||||||
protected transient ExecutorService downloadThreadPool = new ThreadPoolExecutor(0, 5, 20, TimeUnit.SECONDS, downloadQueue, createThreadFactory());
|
protected transient ExecutorService downloadThreadPool = new ThreadPoolExecutor(0, 5, 20, TimeUnit.SECONDS, downloadQueue, createThreadFactory());
|
||||||
protected transient SplittingStrategy splittingStrategy;
|
|
||||||
protected State state = State.UNKNOWN;
|
protected State state = State.UNKNOWN;
|
||||||
private int playlistEmptyCount = 0;
|
private int playlistEmptyCount = 0;
|
||||||
|
|
||||||
|
@ -238,27 +235,4 @@ public abstract class AbstractHlsDownload extends AbstractDownload {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SplittingStrategy initSplittingStrategy(Settings settings) {
|
|
||||||
SplittingStrategy strategy;
|
|
||||||
switch (settings.splitStrategy) {
|
|
||||||
case TIME:
|
|
||||||
strategy = new TimeSplittingStrategy();
|
|
||||||
break;
|
|
||||||
case SIZE:
|
|
||||||
strategy = new SizeSplittingStrategy();
|
|
||||||
break;
|
|
||||||
case TIME_OR_SIZE:
|
|
||||||
SplittingStrategy timeSplittingStrategy = new TimeSplittingStrategy();
|
|
||||||
SplittingStrategy sizeSplittingStrategy = new SizeSplittingStrategy();
|
|
||||||
strategy = new CombinedSplittingStrategy(timeSplittingStrategy, sizeSplittingStrategy);
|
|
||||||
break;
|
|
||||||
case DONT:
|
|
||||||
default:
|
|
||||||
strategy = new NoopSplittingStrategy();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
strategy.init(settings);
|
|
||||||
return strategy;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -48,15 +49,34 @@ public class HlsdlDownload extends AbstractDownload {
|
||||||
this.model = model;
|
this.model = model;
|
||||||
String fileSuffix = config.getSettings().ffmpegFileSuffix;
|
String fileSuffix = config.getSettings().ffmpegFileSuffix;
|
||||||
targetFile = config.getFileForRecording(model, fileSuffix, startTime);
|
targetFile = config.getFileForRecording(model, fileSuffix, startTime);
|
||||||
// TODO splittingStrategy = initSplittingStrategy(config.getSettings());
|
splittingStrategy = initSplittingStrategy(config.getSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() throws IOException {
|
public void start() throws IOException {
|
||||||
try {
|
try {
|
||||||
running = true;
|
running = true;
|
||||||
Thread.currentThread().setName("Download " + model.getName());
|
String threadName = "Download " + model.getName();
|
||||||
|
Thread.currentThread().setName(threadName);
|
||||||
Files.createDirectories(targetFile.getParentFile().toPath());
|
Files.createDirectories(targetFile.getParentFile().toPath());
|
||||||
|
|
||||||
|
Thread splittingMonitor = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
while (running) {
|
||||||
|
if (splittingStrategy.splitNecessary(HlsdlDownload.this)) {
|
||||||
|
LOG.debug("splitting strategy {} triggered split", splittingStrategy.getClass().getSimpleName());
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
TimeUnit.SECONDS.sleep(1);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
splittingMonitor.setName(threadName + " splitter");
|
||||||
|
splittingMonitor.setDaemon(true);
|
||||||
|
splittingMonitor.start();
|
||||||
|
|
||||||
Hlsdl hlsdl = new Hlsdl.Builder()
|
Hlsdl hlsdl = new Hlsdl.Builder()
|
||||||
.logOutput(config.getSettings().loghlsdlOutput)
|
.logOutput(config.getSettings().loghlsdlOutput)
|
||||||
.onStarted(p -> hlsdlProcess = p)
|
.onStarted(p -> hlsdlProcess = p)
|
||||||
|
|
Loading…
Reference in New Issue