У меня есть служба, которая выполняет следующие действия:
1) Получить параметр от пользователя (http get)
2) Вернуть видео файл пользователю в качестве ответа
3) Мой код:
@GET
@Path("/test")
public Response test(@QueryParam("url") final String videoUrl) {
final CrawlerResult result = this.crawlerService.crawl(videoUrl);
if (result.isSuccess()) {
final StreamingOutput fileStream = this.crawlerService.videoAsStream(result.getResult());
return Response.ok(fileStream, MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition", "attachment; filename = movie.mp4")
.build();
} else {
return Response.status(Response.Status.NOT_ACCEPTABLE)
.entity(result)
.build();
}
}
И CrawlerService:
@Override
public StreamingOutput videoAsStream(final String videoUrl) {
try {
final URL url = new URL(videoUrl);
return output -> {
output.write(IOUtils.toByteArray(url));
output.flush();
};
} catch (final MalformedURLException e) {
log.error("Url exception for url {}",videoUrl);
throw new UncheckedIOException(e);
}
}
Как вы видите, я беру URL-адрес, создаю объект URL, затем записываю URL-адрес в StreamingOutput, используя IOUTILS.
Это отлично работает для коротких видео, но если видео слишком длинное, пользователь ждет ответа около 5 минут.
Можно ли как-нибудь переписать мою логику?
Я подтверждаю данный URL
@SMA проблема с этой строкой кода output.write(IOUtils.toByteArray(url)); Она слишком долго выполняется для длинных фильмов
Вот где вы передаете байты обратно клиенту? Это также будет зависеть от того, как быстро клиенты получат потоковые данные.
@SMA return Response.ok(fileStream, MediaType.APPLICATION_OCTET_STREAM)
Если вы используете output.write(IOUtils.toByteArray(url));, значит, вы не транслируете. Сначала вы конвертируете все данные в байтовый массив, а затем отправляете его получателю за один раз. Перестань.




Наконец я нашел решение Я заменяю
output.write(IOUtils.toByteArray(url));
output.flush();
К
return output -> {
IOUtils.copy(url.openConnection().getInputStream(),output);
output.flush();
output.close();
};
Вы уже транслируете, так что все должно быть в порядке. Что ты здесь делаешь
final CrawlerResult result = this.crawlerService.crawl(videoUrl);?