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> requestUtils = new HttpRequestUtils<>(); Response 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 responseData) { List 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 command = buildDownloadCommand(videoEntity); // 开始下载 SystemControlUtils.startProcess(command); } catch (Exception e) { log.error("下载视频失败,视频标题: {}", videoEntity.getTitle(), e); } }); }); } /** * 构建下载命令 * * @param videoEntity 视频实体 * @return 命令列表 */ private static List buildDownloadCommand(VideoEntity videoEntity) { List 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); } } }