Commit 86500002 authored by yanxia54's avatar yanxia54

Merge branch 'master' of http://git.tbd.yanzuoguang.com/yzg/yzg-util into xy

parents b005cd9b 77349a9a
package com.yanzuoguang.media;
import com.yanzuoguang.util.helper.HttpHelper;
import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* m3mu文件下载
*
* @author 颜佐光
*/
public class HlsDownloader {
public static Pattern pattern = Pattern.compile(".*ts");
/**
* 下载uuid
*/
private String uuid;
/**
* 源地址
*/
private String originUrlPath;
/**
*
*/
private String preUrlPath;
/**
* 文件根目录
*/
private String rootPath;
/**
*
*/
private String fileName;
/**
* 当前视频 ts 文件存储临时目录
*/
private String folderPath;
/**
* 线程数量
*/
private int threadQuantity = 10;
public HlsDownloader(String originUrlPath, String preUrlPath, String rootPath) {
this.uuid = UUID.randomUUID().toString().replaceAll("-", "");
this.originUrlPath = originUrlPath;
this.preUrlPath = preUrlPath;
this.rootPath = rootPath;
this.fileName = uuid + ".mp4";
this.folderPath = rootPath + File.separator + uuid;
File file = new File(folderPath);
if (!file.exists()) {
file.mkdirs();
}
}
public int getThreadQuantity() {
return threadQuantity;
}
public void setThreadQuantity(int threadQuantity) {
this.threadQuantity = threadQuantity;
}
public String download(boolean isAsync) throws Exception {
String indexStr = getIndexFile();
List urlList = analysisIndex(indexStr);
HashMap<Integer, String> keyFileMap = new HashMap<>();
if (isAsync) {
downLoadIndexFileAsync(urlList, keyFileMap);
while (keyFileMap.size() < urlList.size()) {
//System.out.println("当前下载数量"+keyFileMap.size());
Thread.sleep(3000);
}
} else {
keyFileMap = downLoadIndexFile(urlList);
}
return composeFile(keyFileMap);
}
/* 下载索引文件 */
public String getIndexFile() throws Exception {
URL url = new URL(originUrlPath);
String content = "";
for (int i = 0; i < 4; i++) { //这里的循环是当下载直播流的时候,一次下载只能有一个ts文件,这里我循环了四次,下载四个ts文件,在合成视频。
//下载资源
try {
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
System.err.println(in.readLine());
String line;
while ((line = in.readLine()) != null) {
content += line + "\n";
}
in.close();
} catch (Exception e) {
System.err.println("错误为:");
System.err.println(e);
}
}
return content;
}
/* 解析索引文件 */
public List analysisIndex(String content) throws Exception {
List<String> list = new ArrayList<String>();
Matcher ma = pattern.matcher(content);
while (ma.find()) {
list.add(ma.group());
}
return list;
}
/* 下载视频片段 */
public HashMap downLoadIndexFile(List<String> urlList) {
HashMap<Integer, String> keyFileMap = new HashMap<>();
for (int i = 0; i < urlList.size(); i++) {
String subUrlPath = urlList.get(i);
String fileOutPath = folderPath + File.separator + i + ".ts";
keyFileMap.put(i, fileOutPath);
try {
HttpHelper.downToLocal(preUrlPath + subUrlPath, fileOutPath);
System.out.println("成功:" + (i + 1) + "/" + urlList.size());
} catch (Exception e) {
System.err.println("失败:" + (i + 1) + "/" + urlList.size());
}
}
return keyFileMap;
}
public void downLoadIndexFileAsync(List<String> urlList, HashMap<Integer, String> keyFileMap) throws Exception {
int downloadForEveryThread = (urlList.size() + threadQuantity - 1) / threadQuantity;
if (downloadForEveryThread == 0) {
downloadForEveryThread = urlList.size();
}
for (int i = 0; i < urlList.size(); i += downloadForEveryThread) {
int startIndex = i;
int endIndex = i + downloadForEveryThread - 1;
if (endIndex >= urlList.size()) {
endIndex = urlList.size() - 1;
}
new DownloadThread(urlList, startIndex, endIndex, keyFileMap).start();
}
}
/**
* 视频片段合成
*
* @param keyFileMap 文件段列表
* @return
* @throws Exception
*/
private String composeFile(HashMap<Integer, String> keyFileMap) throws Exception {
if (keyFileMap.isEmpty()) {
return null;
}
// todo: 输出文件,需要封装成函数
String fileOutPath = rootPath + File.separator + fileName;
// 订单输出文件流
try (FileOutputStream fileOutputStream = new FileOutputStream(new File(fileOutPath))) {
// 按照顺序遍历文件缓存
int size = keyFileMap.size();
for (int i = 0; i < size; i++) {
// 获取当前的 ts 文件
File file = new File(keyFileMap.get(i));
if (!file.exists()) {
continue;
}
// 读取文件
FileInputStream fis = new FileInputStream(file);
// 定义文件缓存
byte[] bytes = new byte[1024];
// 读取的文件长度
int length = 0;
// 读取来源文件
while ((length = fis.read(bytes)) != -1) {
// 写入目标文件
fileOutputStream.write(bytes, 0, length);
}
}
}
return fileName;
}
/**
* 下载线程
*/
private class DownloadThread extends Thread {
/**
* 下载地址列表
*/
private List<String> urlList;
/**
* 开始索引
*/
private int startIndex;
/**
* 结束索引
*/
private int endIndex;
/**
* 本地存储缓存地址
*/
private HashMap<Integer, String> keyFileMap;
/**
* 构造函数
*
* @param urlList
* @param startIndex
* @param endIndex
* @param keyFileMap
*/
public DownloadThread(List<String> urlList, int startIndex, int endIndex, HashMap<Integer, String> keyFileMap) {
this.urlList = urlList;
this.startIndex = startIndex;
this.endIndex = endIndex;
this.keyFileMap = keyFileMap;
}
@Override
public void run() {
for (int i = startIndex; i <= endIndex; i++) {
// 获取源文件地址
String subUrlPath = urlList.get(i);
// 获取生成的地址
String fileOutPath = folderPath + File.separator + i + ".ts";
// 写入生成地址到文件列表
keyFileMap.put(i, fileOutPath);
try {
// 下载服务器文件
HttpHelper.downToLocal(preUrlPath + subUrlPath, fileOutPath);
// 判断文件是否下载成功
System.out.println(String.format("message", "成功", keyFileMap.size()));
} catch (Exception e) {
// 判断文件是否下载失败
System.err.println(String.format("message", "失败", keyFileMap.size()));
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment