手机腾讯视频离线缓存ts格式文件合并为完整视频
程序员文章站
2024-01-03 11:58:04
...
写这边文章主要是记个笔记,方便日后使用。
功能背景:很多老人都喜欢听戏。我爷爷突然问我能不能帮他下载点戏曲,于是我用手机帮忙搜了下,发现腾讯视频上有很多戏曲,而且也可以离线缓存,我就说可以。然而缓存下来后当我将找到的缓存文件弄到电脑上时,发现几百Mb的视频被有序的分割为了上千个ts格式的文件。于是我在网上想找个视频合并的工具,然并卵,都不好用。身为程序猿的我决定用代码解决问题。
离线缓存文件目录:
每个目录都是一个完整的视频。
二级目录:
二级目录下就是被拆开的一个个ts视频文件:
将二级目录下的所有ts文件合并为一个就是完整视频了,下面贴代码:
/**
* 二级文件目录排序规则 文件名:a0138xioutk.322011.hls_0_29 a0138xioutk.322011.hls_1020_1049
*/
public class DirectoryCompare implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
int num1 = subNum(o1);
int num2 = subNum(o2);
return num1-num2;
}
public static int subNum(String directoryName) {
int index = directoryName.lastIndexOf("_");
//没匹配到“_” 说明不符合文件名规定,返回int最大值
if (index==-1) {
return Integer.MAX_VALUE;
}
String subsNum = directoryName.substring(index+1);
return Integer.valueOf(subsNum);
}
}
public class MergeUtil {
private static final Logger log = LoggerFactory.getLogger(MergeUtil.class);
/**
* 二级目录的批量合并
*
* @param filePath
*/
public static void videoMergeForDirectoryLv2(String filePath, String targetPath) {
File file = new File(filePath);
//输入流
FileInputStream fis = null;
//输出流
FileOutputStream fos = null;
int len;
//一次读取2M数据,将读取到的数据保存到byte字节数组中
byte[] bytes = new byte[2 * 1024 * 1024];
//判断该路径文件或文件夹是否存在
if (!file.exists()) {
//不存在退出
log.info("路径不存在");
return;
}
//判断是否为文件夹
boolean isDirectory = file.isDirectory();
if (!isDirectory) {
log.info("路径不是文件目录!");
return;
}
//获取目录下的所有文件或文件夹,然后按照文件后缀降序排序
String[] fileList = file.list();
Arrays.sort(fileList, new DirectoryCompare());
try {
fos = new FileOutputStream(targetPath+file.getName()+".ts");
//遍历一级目录下列表
for (String s : fileList) {
//判断是否为二级目录,不是目录直接跳过
File fileLv2 = new File(file, s);
if (!fileLv2.isDirectory()) {
continue;
}
//获取二级目录下列表,然后降序排序
String[] fileListLv2 = fileLv2.list();
Arrays.sort(fileListLv2, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
String num1 = o1.substring(0, o1.lastIndexOf("."));
String num2 = o2.substring(0, o2.lastIndexOf("."));
return Integer.valueOf(num1) - Integer.valueOf(num2);
}
});
//遍历二级目录
for (String s1 : fileListLv2) {
//创建文件输入流
fis = new FileInputStream(new File(fileLv2, s1));
len=0;
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len);//bytes从指定字节数组写入。bytes:数据中的起始偏移量,len:写入的字数。
}
fis.close();
}
fos.flush();
}
System.out.println("合并完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
if (fis != null) {
fis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class Merge {
public static void main(String[] args) {
//一级目录路径
String path = "F:/新建文件夹/z0726wuq3en.322002.hls";
//合并后的文件路径,合并后的文件名为:一级目录的字符串名.ts,如:z0726wuq3en.322002.hls.ts
String targetPath = "F:/剪辑过的花鼓戏MP3/";
MergeUtil.videoMergeForDirectoryLv2(path,targetPath);
}
}
设定好一级目录和合并后的文件路径就ok了。