栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

java 解析m3u8的实例

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java 解析m3u8的实例

使用java线程池批量下载m3u8合并mp4.

看了线程池的demo,然后就想下载文件试试。

代码未必规范,多多建议。

大家可以自行修改,满足自己的需求。

还需要深入学习一下线程池。

给俺个星星⭐,可好 = =

m3u8 链接下载

下载m3u8文件,找到内部的链接

下载内部的m3u8,提取所有的ts链接

线程池批量下载。

当前针对于 ok、zuida 资源 进行下载测试。

运行步骤:

将ffmpeg 和 当前代码放在同一目录

更换M3U8_URL的地址(下载啥就放啥)

文件路径

然后直接运行就ok 了。

M3u8Download.java

package cn.lacknb.test.threaddownload;

import java.io.*;

import java.net.MalformedURLException;

import java.net.URL;

import java.net.URLConnection;

import java.util.ArrayList;

import java.util.List;

import java.util.UUID;

import java.util.concurrent.*;

public class M3u8Download {

private static final String M3U8_URL = "https://yuledy.helanzuida.com/20201204/15904_c1fcf83a/index.m3u8";

public static final String DOWNLOAD_PATH = "G:\work\video\";

private static final String FILE_PATH = DOWNLOAD_PATH + "tmp.m3u8";

private static final String TMP_NAME = "tmp.txt";

public static void main(String[] args) {

try {

// 创建父级文件夹

createParentDirs();

// 下载外层m3u8 url

downloadFile(M3U8_URL);

String content = readFile(FILE_PATH);

System.out.println(content);

String realUrl = M3U8_URL.split("index")[0] + content;

System.out.println("realUrl: " + realUrl);

// 下载内层m3u8 url

downloadFile(realUrl);

content = readFile(FILE_PATH);

// 获取所有的ts, 并合并 url

List urls = mergeUrl(content, realUrl);

// 生成tmp.txt, 用于合并视频

createMergeVideoTmp(content);

//            urls.forEach(System.out::println);

ExecutorService executorService = Executors.newFixedThreadPool(12);

urls.forEach( url -> {

executorService.execute(new TsDownload(url));

});

//            // 关闭线程池,等待任务结束。

executorService.shutdown();

while (!executorService.isTerminated()) {

System.out.println("任务下载中");

try {

TimeUnit.SECONDS.sleep(1);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// 任务下载完毕后

mergeVideo(content, UUID.randomUUID().toString());

// 删除ts文件

deleteTsFile(content);

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

public static void downloadFile (String m3u8Url) throws IOException {

System.out.println("下载地址:" + m3u8Url);

URL url = new URL(m3u8Url);

URLConnection conn = url.openConnection();

File f = new File(FILE_PATH);

if (f.exists()) {

f.delete();

}

RandomAccessFile file = new RandomAccessFile(FILE_PATH, "rw");

InputStream inputStream = conn.getInputStream();

byte[] buffer = new byte[1024];

int hasRead = 0;

while ((hasRead = inputStream.read(buffer)) != -1) {

file.write(buffer, 0, hasRead);

}

file.close();

inputStream.close();

}

public static String readFile (String path) {

System.out.println("读取文件地址:" + path);

StringBuilder builder = new StringBuilder();

try {

RandomAccessFile randomAccessFile = new RandomAccessFile(path, "r");

String content = null;

while ((content = randomAccessFile.readLine()) != null) {

if (!content.startsWith("#")) {

builder.append(content + "n");

}

}

randomAccessFile.close();

return builder.toString();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return builder.toString();

}

public static List mergeUrl(String content, String realUrl) {

String baseUrl = realUrl.split("index")[0];

String[] split = content.split("n");

List urls = new ArrayList<>();

for (String str : split) {

urls.add(baseUrl + str);

}

return urls;

}

public static void createMergeVideoTmp (String content) {

String[] tsNames = content.split("n");

File file = new File(M3u8Download.DOWNLOAD_PATH + TMP_NAME);

if (file.exists()) {

file.delete();

}

try {

RandomAccessFile randomAccessFile = new RandomAccessFile(M3u8Download.DOWNLOAD_PATH + TMP_NAME, "rw");

for (String tsName : tsNames) {

randomAccessFile.write(("file '" + tsName + "'n").getBytes());

}

randomAccessFile.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

public static void mergeVideo (String content, String filename) {

System.out.println("开始合并视频....");

File file = new File(M3u8Download.DOWNLOAD_PATH + TMP_NAME);

if (!file.exists()) {

createMergeVideoTmp(content);

}

String path = M3u8Download.DOWNLOAD_PATH.replaceAll("\\", "/");

// 合并视频的命令

try {

Process process = Runtime.getRuntime().exec(String.format("ffmpeg.exe -f concat -safe 0 -i %s -c copy %s" +

".mp4",

path + TMP_NAME, path + filename));

final InputStream is1 = process.getInputStream();

new Thread(new Runnable(){

@Override

public void run() {

BufferedReader br = new BufferedReader(new InputStreamReader(is1));

try {

String outputLine = null;

while((outputLine=br.readLine())!= null) {

System.out.println(outputLine);

}

}catch (IOException e) {

e.printStackTrace();

}

}

}).start();

InputStream is2 = process.getErrorStream();

BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));

StringBuilder buf = new StringBuilder();

String line = null;

while((line = br2.readLine()) != null) {

System.out.println(line);

buf.append(line);

};

System.out.println("result:" + buf);

while (br2.readLine() != null) {

System.out.println(br2);

}

try {

process.waitFor();

}catch (InterruptedException e){

e.printStackTrace();

}

int i = process.exitValue();

System.out.println( process.exitValue());

} catch (IOException e) {

e.printStackTrace();

} finally {

file.delete();

}

}

public static void deleteTsFile (String content) {

String[] tsNames = content.split("n");

for (int i = 0; i < tsNames.length; i++) {

System.out.println(DOWNLOAD_PATH + tsNames[i]);

File file = new File(DOWNLOAD_PATH, tsNames[i]);

if (file.exists()) {

System.out.println("删除成功  文件 =====> " + tsNames[i]);

file.delete();

}

}

}

public static void createParentDirs () {

File file = new File(DOWNLOAD_PATH);

if (!file.exists()) {

file.mkdirs();

}

}

}

class TsDownload implements Runnable {

private String downloadUrl;

private String filename;

public TsDownload () {

}

public TsDownload(String downloadUrl) {

this.downloadUrl = downloadUrl;

String[] split = downloadUrl.split("/");

this.filename = split[split.length - 1];

}

@Override

public void run() {

URL url = null;

try {

url = new URL(this.downloadUrl);

System.out.println(Thread.currentThread().getName() + " 正在下载 " + this.filename);

URLConnection conn = url.openConnection();

RandomAccessFile file = new RandomAccessFile(M3u8Download.DOWNLOAD_PATH + this.filename, "rw");

InputStream inputStream = conn.getInputStream();

byte[] buffer = new byte[1024];

int hasRead = 0;

while ((hasRead = inputStream.read(buffer)) != -1) {

file.write(buffer, 0, hasRead);

}

file.close();

inputStream.close();

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

teambition网盘的直链下载

这个demo,在网上找的下载,照着改了改。

感觉效果不是太好。

链接有是效性。

MainDownload.java

package cn.lacknb.test.threaddownload;

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.RandomAccessFile;

import java.net.*;

import java.util.List;

import java.util.Map;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class MainDownload {

public static void main(String[] args) {

try {

String downloadUrl = "https://data-hz-pds.teambition.net/5fccd7c403ca7a0ca34e456189672403e98832a3%2F5fccd7c43bd9aea8576b478693fd7885b1af775a?response-content-disposition=attachment%3B%20filename%2A%3DUTF-8%27%27%25E9%25BE%2599%25E7%258F%25A0%2520%25EF%25BC%259A%25E7%25AC%25AC101%25E9%259B%2586%2520%25E6%25AD%25A6%25E9%2581%2593%25E4%25BC%259A%25E7%25BB%2593%25E6%259D%259F.mp4&x-oss-access-key-id=LTAIsE5mAn2F493Q&x-oss-expires=1607754425&x-oss-signature=pFgGtR1LcdhJkgaXuwb4WCzkoUdFT5lArWXuJNvcRmg%3D&x-oss-signature-version=OSS2";

File file = new File(FileDownload.PATH);

if (!file.exists()) {

file.mkdirs();

}

URL url = new URL(downloadUrl);

URLConnection conn = url.openConnection();

// b -> kb > mb

int contentLength = conn.getContentLength();

Map> headerFields = conn.getHeaderFields();

//            for (String key : headerFields.keySet()) {

//                System.out.println(key + "  =====  " + headerFields.get(key));

//            }

List strings = headerFields.get("Content-Disposition");

String[] split = strings.get(0).split("''");

String filename = split[split.length - 1];

filename = URLDecoder.decode(filename);

System.out.println(filename);

//            RandomAccessFile file = new RandomAccessFile("G:\work\test.mp4", "rw");

//            file.setLength(contentLength);

//            file.close();

System.out.println("total mb size: " + StaticConstant.transMb(contentLength));

int concurrentThreadSize = 6;  // 设置6个线程同时下载

int threadFileSize = contentLength / concurrentThreadSize + 1;  // 每个线程块所负责的大小

ExecutorService executorService = Executors.newFixedThreadPool(concurrentThreadSize);

for (int i = 0; i < concurrentThreadSize; i++) {

//                FileDownload fileDownload = new FileDownload(i * threadFileSize, threadFileSize, downloadUrl, filename);

//                new Thread(fileDownload).start();

executorService.execute(new FileDownload(i * threadFileSize, threadFileSize, downloadUrl, filename));

}

executorService.shutdown();

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

class StaticConstant {

public static String transMb (long size) {

long mb = size / 1024 / 1024;

return String.valueOf(mb) + " MB";

}

}

class FileDownload implements Runnable {

public static final String PATH = "G:\work\";

private int order;  // 所负责 文件块的第一个下标

private RandomAccessFile randomAccessFile;  // 所负责的文件

private int fileSize;  // 所负责的总大小

String url;

private int nowFileSize = 0;  // 当前所完成的大小。

private String filename;

public FileDownload() {

}

public FileDownload(int order, int fileSize, String url, String filename) {

this.order = order;

this.url = url;

this.fileSize = fileSize;

this.filename = filename;

}

@Override

public void run() {

try {

URL url = new URL(this.url);

System.out.println(Thread.currentThread().getName() + "正在运行....");

URLConnection urlConnection = url.openConnection();

urlConnection.setConnectTimeout(1000);

InputStream inputStream = urlConnection.getInputStream();

inputStream.skip(order);

randomAccessFile = new RandomAccessFile(PATH + this.filename, "rw") ;

randomAccessFile.seek(order);

byte[] buffer = new byte[1024];

int hasRead = 0;

while (nowFileSize < fileSize && (hasRead = inputStream.read(buffer)) != -1) {

randomAccessFile.write(buffer, 0, hasRead);

nowFileSize += hasRead;

System.out.println(String.format("%s ======= 还剩下 %s 没下载完", Thread.currentThread().getName(),

StaticConstant.transMb(fileSize - nowFileSize)));

}

randomAccessFile.close();

inputStream.close();

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

System.out.println(Thread.currentThread().getName() + " ===== 下载完毕。");

}

}

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/985430.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号