134 lines
4.8 KiB
Java
134 lines
4.8 KiB
Java
|
package cn.bunny.video;
|
|||
|
|
|||
|
import cn.bunny.video.dao.Response;
|
|||
|
import cn.bunny.video.dao.VideoEntity;
|
|||
|
import cn.bunny.video.utils.HttpRequestUtils;
|
|||
|
import cn.bunny.video.utils.SystemControlUtils;
|
|||
|
import io.micrometer.common.util.StringUtils;
|
|||
|
import org.slf4j.Logger;
|
|||
|
import org.slf4j.LoggerFactory;
|
|||
|
|
|||
|
import java.time.Duration;
|
|||
|
import java.time.Instant;
|
|||
|
import java.util.ArrayList;
|
|||
|
import java.util.List;
|
|||
|
import java.util.concurrent.ExecutorService;
|
|||
|
import java.util.concurrent.Executors;
|
|||
|
import java.util.concurrent.TimeUnit;
|
|||
|
|
|||
|
public class VideoDownloadVersion2 {
|
|||
|
private static final Logger log = LoggerFactory.getLogger(VideoDownloadVersion2.class);
|
|||
|
|
|||
|
// 当前下载页
|
|||
|
private static final Integer currentPage = 7;
|
|||
|
|
|||
|
// 线程池个数
|
|||
|
private static final Integer threadPoolSize = 10;
|
|||
|
|
|||
|
// 下载目录
|
|||
|
private static final String DOWNLOAD_DIR = "G:\\video\\";
|
|||
|
|
|||
|
// 视频下载URL基础部分
|
|||
|
private static final String BASE_URL = "https://mjfh136.cyou/view/videoList/1637462276570050562/";
|
|||
|
|
|||
|
// 开始线程池
|
|||
|
private static final ExecutorService executorService = Executors.newFixedThreadPool(threadPoolSize);
|
|||
|
|
|||
|
public static void main(String[] args) {
|
|||
|
Instant start = Instant.now();
|
|||
|
try {
|
|||
|
String url = BASE_URL + currentPage + "/80";
|
|||
|
HttpRequestUtils<Response<VideoEntity>> requestUtils = new HttpRequestUtils<>();
|
|||
|
Response<VideoEntity> responseData = requestUtils.requestGET(url);
|
|||
|
|
|||
|
// 接收到返回信息
|
|||
|
downloadVideoList(responseData);
|
|||
|
|
|||
|
// 执行完成后播放音乐
|
|||
|
shutdownExecutorService();
|
|||
|
|
|||
|
// 计算程序运行时间
|
|||
|
Instant end = Instant.now();
|
|||
|
Duration duration = Duration.between(start, end);
|
|||
|
long minutes = duration.toMinutes();
|
|||
|
long seconds = duration.minusMinutes(minutes).getSeconds();
|
|||
|
log.info("程序运行时间:{} 分钟 {} 秒", minutes, seconds);
|
|||
|
|
|||
|
} catch (Exception exception) {
|
|||
|
log.error("下载过程中发生异常", exception);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 下载视频列表内容
|
|||
|
*
|
|||
|
* @param responseData 返回一页的数据响应
|
|||
|
*/
|
|||
|
private static void downloadVideoList(Response<VideoEntity> responseData) {
|
|||
|
List<VideoEntity> videoEntities = responseData.getData().getList();
|
|||
|
|
|||
|
// 使用并行流代替传统的流操作,并且进行命令的预构建
|
|||
|
videoEntities.parallelStream()
|
|||
|
.filter(videoEntity -> videoEntity.getPlayUrl().contains("http"))
|
|||
|
.peek(videoEntity -> {
|
|||
|
if (StringUtils.isBlank(videoEntity.getVideoTag())) {
|
|||
|
videoEntity.setVideoTag(videoEntity.getVideoTypeTitle());
|
|||
|
}
|
|||
|
})
|
|||
|
.forEach(videoEntity -> {
|
|||
|
executorService.submit(() -> {
|
|||
|
try {
|
|||
|
String videoTitle = videoEntity.getTitle().trim();
|
|||
|
String videoUrl = videoEntity.getPlayUrl();
|
|||
|
|
|||
|
log.info("开始下载视频:{},URL:{}", videoTitle, videoUrl);
|
|||
|
|
|||
|
List<String> command = buildDownloadCommand(videoEntity);
|
|||
|
|
|||
|
// 开始下载
|
|||
|
SystemControlUtils.startProcess(command);
|
|||
|
} catch (Exception e) {
|
|||
|
log.error("下载视频失败,视频标题: {}", videoEntity.getTitle(), e);
|
|||
|
}
|
|||
|
});
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 构建下载命令
|
|||
|
*
|
|||
|
* @param videoEntity 视频实体
|
|||
|
* @return 命令列表
|
|||
|
*/
|
|||
|
private static List<String> buildDownloadCommand(VideoEntity videoEntity) {
|
|||
|
List<String> command = new ArrayList<>();
|
|||
|
command.add("N_m3u8DL-CLI");
|
|||
|
command.add("\"" + videoEntity.getPlayUrl() + "\"");
|
|||
|
command.add("--workDir");
|
|||
|
command.add("\"" + DOWNLOAD_DIR + videoEntity.getVideoTag() + "\"");
|
|||
|
command.add("--saveName");
|
|||
|
command.add("\"" + videoEntity.getTitle().trim() + "\"");
|
|||
|
command.add("--enableDelAfterDone");
|
|||
|
command.add("--enableBinaryMerge");
|
|||
|
command.add("--enableMuxFastStart");
|
|||
|
|
|||
|
return command;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 优雅地关闭线程池
|
|||
|
*/
|
|||
|
private static void shutdownExecutorService() {
|
|||
|
try {
|
|||
|
executorService.shutdown();
|
|||
|
if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
|
|||
|
executorService.shutdownNow();
|
|||
|
}
|
|||
|
SystemControlUtils.playMusic();
|
|||
|
} catch (InterruptedException e) {
|
|||
|
executorService.shutdownNow();
|
|||
|
Thread.currentThread().interrupt();
|
|||
|
log.error("线程池等待超时,强制关闭线程池", e);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|