前提:找到视频的m3u8文件地址
package com.main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String url = "https://youku163.zuida-bofang.com/20181001/16086_4fce2677/800k/hls/index.m3u8";
List<String> tsList = getTSPathByM3U8(url);
String basePath = url.substring(0, url.lastIndexOf("/") + 1);
for (String tsPath : tsList) {
download(basePath + tsPath);
}
mergeFile(System.getProperty("user.dir") + File.separator + "tmp");
}
/**
* 下载资源
*
* @param urlStr
*/
public static void download(String urlStr) {
try {
URL url = new URL(urlStr);
String urlPath = url.getPath();
String fileName = "";
if (urlPath.lastIndexOf("/") >= 0)
fileName = urlPath.substring(urlPath.lastIndexOf("/") + 1);
else
fileName = urlPath;
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置超时时间
connection.setConnectTimeout(60 * 1000);
// 连接成功,开始下载文件
if (connection.getResponseCode() == 200) {
// 在当前运行目录下建立临时目录,存放临时文件
File tmpDir = new File(System.getProperty("user.dir") + File.separator + "tmp");
if (!tmpDir.exists())
tmpDir.mkdir();
File file = new File(tmpDir.getAbsolutePath() + File.separator + fileName);
if (file.exists() && fileIsUsed(file)) {
// 文件存在且被占用
return;
} else {
file.createNewFile();
}
// 开始下载
InputStream is = connection.getInputStream();
int ContentLength = connection.getContentLength();
FileOutputStream fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int i, length = 0;
while ((i = is.read(buffer)) != -1) {
length += i;
System.out.println(fileName + "\t正在下载(" + length + "/" + ContentLength + ")");
fos.write(buffer);
}
fos.flush();
is.close();
fos.close();
System.out.println(fileName + "\t下载完成");
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 从m3u8文件中解析出ts文件位置
*
* @param m3u8_Path
* @return
*/
public static List<String> getTSPathByM3U8(String m3u8_Path) {
try {
System.out.println("开始访问m3u8文件并解析内容");
HttpURLConnection connection = (HttpURLConnection) new URL(m3u8_Path).openConnection();
// 设置超时时间
connection.setConnectTimeout(60 * 1000);
List<String> list = new ArrayList<String>();
String charSet = getCharSet(connection.getContentType());
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), charSet));
String line;
while ((line = br.readLine()) != null) {
if (line.contains("ts"))
list.add(line);
}
br.close();
System.out.println("m3u8文件解析成功");
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 合并ts文件
*
* @param dirPath
*/
public static void mergeFile(String dirPath) {
File dir = new File(dirPath);
if (!dir.exists() || !dir.isDirectory()) {
System.out.println("文件目录不存在或不是文件夹");
return;
}
File mergeFile = new File(dir.getParent() + File.separator + System.currentTimeMillis() + ".ts");
try {
mergeFile.createNewFile();
} catch (IOException e) {
System.out.println("创建合并文件失败");
}
File[] tsFiles = orderByName(dir.listFiles());
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mergeFile);
for (File file : tsFiles) {
fis = new FileInputStream(file);
int i = 0;
byte[] buffer = new byte[1024];
while ((i = fis.read(buffer)) != -1) {
fos.write(buffer, 0, i);
}
System.out.println(file.getName() + "合并成功");
}
fis.close();
fos.close();
System.out.println("------------------合并成功------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据文件名称进行文件的排序
*
* @param files
* @return
*/
private static File[] orderByName(File[] files) {
List<File> fileList = Arrays.asList(files);
Collections.sort(fileList, new Comparator<File>() {
@Override
public int compare(File f1, File f2) {
if (f1.isDirectory() && f2.isFile())
return -1;
if (f1.isFile() && f2.isDirectory())
return 1;
return f1.getName().compareTo(f2.getName());
}
});
return files;
}
/**
* 打印连接基本信息
*
* @param conn
*/
private void printConnInfo(HttpURLConnection conn) {
try {
System.out.println("状态码:" + conn.getResponseCode());
System.out.println("状态信息:" + conn.getResponseMessage());
} catch (IOException e) {
e.printStackTrace();
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("服务器时间:" + sdf.format(new Date(conn.getDate())));
System.out.println("服务器:" + conn.getHeaderField("Server"));
System.out.println("文件类型:" + conn.getContentType());
System.out.println("文件大小:" + conn.getContentLength());
URL url = conn.getURL();
System.out.println("网址:" + url.getHost());
System.out.println("路径:" + url.getPath());
String urlPath = url.getPath();
String fileName = "";
if (urlPath.lastIndexOf("/") >= 0)
fileName = urlPath.substring(urlPath.lastIndexOf("/") + 1);
else
fileName = urlPath;
System.out.println("文件名:" + fileName);
}
/**
* 获取字符编码
*
* @param str
* @return
*/
private static String getCharSet(String str) {
String charset = "UTF-8";
Pattern pattern = Pattern.compile("charset=\\S*");
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
charset = matcher.group().replace("charset=", "");
}
return charset;
}
/**
* 判断文件是否被占用
*
* @param file
* @return
*/
private static boolean fileIsUsed(File file) {
try {
RandomAccessFile raf = new RandomAccessFile(file, "rw");
raf.close();
System.out.println("文件未被使用");
return false;
} catch (Exception e) {
System.out.println("文件被占用");
}
return true;
}
}
本文介绍了如何通过获取视频的m3u8文件地址来下载TS视频片段,详细阐述了整个下载过程的前提和步骤。
2943

被折叠的 条评论
为什么被折叠?



