forked from j62/ctbrec
Improve segment download retry code
This commit is contained in:
parent
6cc8fd9cc2
commit
a33d3045c1
|
@ -41,6 +41,8 @@ import okhttp3.Request;
|
|||
import okhttp3.Response;
|
||||
|
||||
public class DashDownload extends AbstractDownload {
|
||||
private static final String CONTENT_LENGTH = "Content-Length";
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DashDownload.class);
|
||||
|
||||
private int audioCounter = 0;
|
||||
|
@ -139,16 +141,18 @@ public class DashDownload extends AbstractDownload {
|
|||
|
||||
private int downloadInitChunksForVideoAndAudio(boolean isVideo, MPDtype mpd, SegmentTemplateType segmentTemplate, RepresentationType representation)
|
||||
throws IOException {
|
||||
int loadedFileCount = 0;
|
||||
if (isVideo && !videoInitLoaded || !isVideo && !audioInitLoaded) {
|
||||
String initialization = segmentTemplate.getInitializationAttribute();
|
||||
initialization = initialization.replaceAll("\\$RepresentationID\\$", representation.getId());
|
||||
URL initUrl = new URL(new URL(mpd.getLocation().get(0)), initialization);
|
||||
File file = download(downloadDir.toFile().getCanonicalPath(), initUrl, isVideo);
|
||||
setInitState(isVideo, file);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
if (file != null) {
|
||||
setInitState(isVideo, file);
|
||||
loadedFileCount++;
|
||||
}
|
||||
}
|
||||
return loadedFileCount;
|
||||
}
|
||||
|
||||
private void setInitState(boolean isVideo, File file) {
|
||||
|
@ -177,34 +181,34 @@ public class DashDownload extends AbstractDownload {
|
|||
.header("Connection", "keep-alive")
|
||||
.build(); // @formatter:on
|
||||
int tries = 1;
|
||||
try (Response response = httpClient.execute(request)) {
|
||||
InputStream in = response.body().byteStream();
|
||||
String absFile = url.getFile();
|
||||
String prefix = isVideo ? "video" : "audio";
|
||||
int c = isVideo ? videoCounter++ : audioCounter++;
|
||||
File segmentFile = new File(dir, prefix + '_' + df.format(c) + '_' + new File(absFile).getName());
|
||||
while (tries <= 10) {
|
||||
if (!segmentFile.exists() || segmentFile.length() == 0) {
|
||||
if (tries == 10) {
|
||||
LOG.debug("Loading segment, try {}, {} {} {}", tries, response.code(), response.headers().values("Content-Length"), url);
|
||||
} else {
|
||||
LOG.trace("Loading segment, try {}, {} {} {}", tries, response.code(), response.headers().values("Content-Length"), url);
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(segmentFile)) {
|
||||
byte[] b = new byte[1024];
|
||||
int len = -1;
|
||||
while ((len = in.read(b)) >= 0) {
|
||||
out.write(b, 0, len);
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
while (tries <= 10) {
|
||||
try (Response response = httpClient.execute(request)) {
|
||||
if (!response.isSuccessful()) {
|
||||
LOG.trace("Loading segment failed, try {}, {} size:{} {}", tries, response.code(), response.headers().values(CONTENT_LENGTH), url);
|
||||
tries++;
|
||||
waitSomeTime(tries * 80);
|
||||
} else {
|
||||
break;
|
||||
InputStream in = response.body().byteStream();
|
||||
String absFile = url.getFile();
|
||||
String prefix = isVideo ? "video" : "audio";
|
||||
int c = isVideo ? videoCounter++ : audioCounter++;
|
||||
File segmentFile = new File(dir, prefix + '_' + df.format(c) + '_' + new File(absFile).getName());
|
||||
if (!segmentFile.exists() || segmentFile.length() == 0) {
|
||||
try (FileOutputStream out = new FileOutputStream(segmentFile)) {
|
||||
byte[] b = new byte[1024];
|
||||
int len = -1;
|
||||
while ((len = in.read(b)) >= 0) {
|
||||
out.write(b, 0, len);
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
return segmentFile;
|
||||
}
|
||||
tries++;
|
||||
}
|
||||
return segmentFile;
|
||||
}
|
||||
LOG.warn("Loading segment finally failed after {} tries {}", --tries, url);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -266,16 +270,7 @@ public class DashDownload extends AbstractDownload {
|
|||
for (PeriodType period : periods) {
|
||||
List<AdaptationSetType> videoStreams = new ArrayList<>();
|
||||
List<AdaptationSetType> audioStreams = new ArrayList<>();
|
||||
|
||||
List<AdaptationSetType> adaptationSets = period.getAdaptationSet();
|
||||
for (AdaptationSetType adaptationSet : adaptationSets) {
|
||||
String mimeType = adaptationSet.getMimeType();
|
||||
if (mimeType.equalsIgnoreCase("video/mp4")) {
|
||||
videoStreams.add(adaptationSet);
|
||||
} else if (mimeType.equalsIgnoreCase("audio/mp4")) {
|
||||
audioStreams.add(adaptationSet);
|
||||
}
|
||||
}
|
||||
splitAdaptionSets(period.getAdaptationSet(), videoStreams, audioStreams);
|
||||
|
||||
downloadDir.toFile().mkdirs();
|
||||
|
||||
|
@ -290,12 +285,23 @@ public class DashDownload extends AbstractDownload {
|
|||
|
||||
if (downloaded == 0) {
|
||||
LOG.trace("No new segments - Sleeping a bit");
|
||||
waitSomeTime();
|
||||
waitSomeTime(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void splitAdaptionSets(List<AdaptationSetType> adaptationSets, List<AdaptationSetType> videoStreams, List<AdaptationSetType> audioStreams) {
|
||||
for (AdaptationSetType adaptationSet : adaptationSets) {
|
||||
String mimeType = adaptationSet.getMimeType();
|
||||
if (mimeType.equalsIgnoreCase("video/mp4")) {
|
||||
videoStreams.add(adaptationSet);
|
||||
} else if (mimeType.equalsIgnoreCase("audio/mp4")) {
|
||||
audioStreams.add(adaptationSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AdaptationSetType chooseBestVideo(List<AdaptationSetType> videoStreams) {
|
||||
AdaptationSetType best = null;
|
||||
int maxHeight = config.getSettings().maximumResolution;
|
||||
|
@ -373,9 +379,9 @@ public class DashDownload extends AbstractDownload {
|
|||
* Causes the current thread to sleep for a short amount of time. This is used to slow down retries, if something is wrong with the playlist. E.g. HTTP 403
|
||||
* or 404
|
||||
*/
|
||||
private void waitSomeTime() {
|
||||
private void waitSomeTime(long ms) {
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
Thread.sleep(ms);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue