Git Product home page Git Product logo

m3u8downloader's Introduction

M3U8Downloader

M3U8下载器,支持多线程下载、断点续传、后台下载、本地播放解决方案、m3u8加密解决方案

依赖

allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}
	
dependencies {
	        compile 'com.github.Jay-Goo:M3U8Downloader:V1.0.8'
	}

用法

配置

  • default Config:
M3U8DownloaderConfig
                .build(getApplicationContext())
                .setSaveDir(dirPath)
                ;
  • Custom Config:
M3U8DownloaderConfig
                .build(getApplicationContext())
                .setSaveDir(dirPath)
                .setConnTimeout(10000)
                .setReadTimeout(10000)
                .setThreadCount(3)
                .setDebugMode(true)
                ;

单例

M3U8Downloader.getInstance()

下载

download(String url)

暂停

pause(String url)

取消任务、取消任务并删除文件缓存

cancel(String url)

cancelAndDelete(final String url, final OnDeleteTaskListener listener)

下载监听

        M3U8Downloader.getInstance().setOnM3U8DownloadListener(onM3U8DownloadListener);

private OnM3U8DownloadListener onM3U8DownloadListener = new OnM3U8DownloadListener() {

        @Override
        public void onDownloadItem(M3U8Task task, long itemFileSize, int totalTs, int curTs) {
            super.onDownloadItem(task, itemFileSize, totalTs, curTs);
            //下载切片监听,非UI线程
        }

        @Override
        public void onDownloadSuccess(M3U8Task task) {
            super.onDownloadSuccess(task);
            //下载成功
        }

        @Override
        public void onDownloadPending(M3U8Task task) {
            super.onDownloadPending(task);
            //加入队列,任务挂起
        }

        @Override
        public void onDownloadPause(M3U8Task task) {
            super.onDownloadPause(task);
            //任务暂停
        }

        @Override
        public void onDownloadProgress(final M3U8Task task) {
            super.onDownloadProgress(task);
            //下载进度,非UI线程
        }

        @Override
        public void onDownloadPrepare(final M3U8Task task) {
            super.onDownloadPrepare(task);
            //准备下载
        }

        @Override
        public void onDownloadError(final M3U8Task task, Throwable errorMsg) {
            super.onDownloadError(task, errorMsg);
            //下载错误,非UI线程
        }

    };

M3U8Task

    private String url; //下载链接
    private int state = M3U8TaskState.DEFAULT; //下载状态
    private long speed; //下载速度
    private float progress; //下载进度
    private M3U8 m3U8; //下载成功后得到

加密

加密后视频切片文件名乱序,并移除后缀。

//设置密匙
M3U8Downloader.getInstance().setEncryptKey(encryptKey);
//获取随机密匙
AES128Utils.getAESKey()

更多加密解密 M3U8EncryptHelper

本地播放

普通未加密请使用 M3U8HttpServer

加密解密请使用 M3U8EncryptHelper

具体使用样例参考 FullScreenActivity

联系我

  • Email: [email protected]
  • QQ Group: 573830030 有时候工作很忙没空看邮件和Issue,大家可以通过QQ群联系我

一杯咖啡

大家都知道开源是件很辛苦的事情,这个项目也是我工作之余完成的,平时工作很忙,但大家提的需求基本上我都尽量满足,如果这个项目帮助你节省了大量时间,你很喜欢,你可以给我一杯咖啡的鼓励,不在于钱多钱少,关键是你的这份鼓励所带给我的力量~

致谢

huangdali - M3U8Manger

m3u8downloader's People

Contributors

jinjiegu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

m3u8downloader's Issues

加密后的视频如何下载

看到readme里面有关于加密的处理方式
但是我走普通的下载流程,下载加密的m3u8可以下载,但是无法播放!
是下载加密的m3u8需要走其他流程吗 ?

下载问题

首先这个项目非棒,非常感谢! 下载超过4M 时会出错,不支持多个任务同时下载?

部分M3U8网址路径301 Moved Permanently问题

修改MUtils文件parseIndex()方法

public static M3U8 parseIndex(String url) throws IOException {
String urlName = url;
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
String newUrl = urlName;

    Map<String, List<String>> map = conn.getHeaderFields();

    // 遍历所有的响应头字段
    for (String key : map.keySet()) {
        System.out.println(key + "--->" + map.get(key).get(0));
        if ("Location".equals(key)) {
            //获取新地址
            newUrl = map.get(key).get(0);
            System.out.println("newUrl--->" +newUrl);
            break;
        }
    }
    // 重新实例化url对象
    realUrl = new URL(newUrl);
    // 重新打开和URL之间的连接
    conn = realUrl.openConnection();

    // 建立实际的连接
    conn.connect();

    InputStream in = conn.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in,encoding));
    String basepath = url;

    if (url.contains("?")) {
        basepath = url.substring(0, url.lastIndexOf("?"));
    }
    basepath = basepath.substring(0, basepath.lastIndexOf("/") + 1);

    M3U8 ret = new M3U8();
    ret.setBasePath(basepath);

    String line;
    float seconds = 0;
    while ((line = reader.readLine()) != null) {
        if (line.startsWith("#")) {
            if (line.startsWith("#EXTINF:")) {
                line = line.substring(8);
                if (line.endsWith(",")) {
                    line = line.substring(0, line.length() - 1);
                }
                seconds = Float.parseFloat(line);
            }
            continue;
        }
        if (line.endsWith("m3u8")) {
            return parseIndex(basepath + line);
        }
        ret.addTs(new M3U8Ts(line, seconds));
        seconds = 0;
    }
    reader.close();

    return ret;
}
  • M3U8DownloadTask文件的startDownload()方法

    executor.execute(new Runnable() {
             @Override
             public void run() {
    
                 File file;
                 try {
                     String fileName = M3U8EncryptHelper.encryptFileName(encryptKey, m3U8Ts.obtainEncodeTsFileName());
                     file = new File(dir + File.separator + fileName);
                 } catch (Exception e) {
                     file = new File(dir + File.separator + m3U8Ts.getUrl());
                 }
    
                 if (!file.exists()) {//下载过的就不管了
                     String urlName = m3U8Ts.obtainFullUrl(basePath);
                     FileOutputStream fos = null;
                     InputStream inputStream = null;
                     try {
                         URL url = new URL(m3U8Ts.obtainFullUrl(basePath));
    
                         String newUrl = urlName;
                         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    
                         conn.setConnectTimeout(connTimeout);
                         conn.setReadTimeout(readTimeout);
    
                         Map<String, List<String>> map = conn.getHeaderFields();
                         // 遍历所有的响应头字段
                         for (String key : map.keySet()) {
                             System.out.println(key + "--->" + map.get(key).get(0));
                             if ("Location".equals(key)) {
                                 //获取新地址
                                 newUrl = map.get(key).get(0);
                                 System.out.println("newUrl--->" +newUrl);
                                 break;
                             }
                         }
                         // 重新实例化url对象
                         url = new URL(newUrl);
                         // 重新打开和URL之间的连接
                         conn = (HttpURLConnection) url.openConnection();
    
                         // 建立实际的连接
                         conn.connect();
    
                         if (conn.getResponseCode() == 200) {
                             if (isStartDownload){
                                 isStartDownload = false;
                                 mHandler.sendEmptyMessage(WHAT_ON_START_DOWNLOAD);
                             }
                             inputStream = conn.getInputStream();
                             fos = new FileOutputStream(file);//会自动创建文件
                             int len = 0;
                             byte[] buf = new byte[8 * 1024 * 1024];
                             while ((len = inputStream.read(buf)) != -1) {
                                 curLength += len;
                                 fos.write(buf, 0, len);//写入流中
                             }
                         } else {
                             handlerError(new Throwable(String.valueOf(conn.getResponseCode())));
                         }
                     } catch (MalformedURLException e) {
                         handlerError(e);
                     } catch (IOException e) {
                         handlerError(e);
                     } catch (Exception e) {
                         handlerError(e);
                     }
                     finally
                     {//关流
                         if (inputStream != null) {
                             try {
                                 inputStream.close();
                             } catch (IOException e) {
                             }
                         }
                         if (fos != null) {
                             try {
                                 fos.close();
                             } catch (IOException e) {
                             }
                         }
                     }
    
                     itemFileSize = file.length();
                     m3U8Ts.setFileSize(itemFileSize);
                     mHandler.sendEmptyMessage(WHAT_ON_PROGRESS);
                     curTs++;
                 }else {
                     curTs ++;
                     itemFileSize = file.length();
                     m3U8Ts.setFileSize(itemFileSize);
                 }
             }
         });
    

M3u8 的解析有问题

目前代码只能下载 Media playlist 不能支持 Master playlist 下载,是否打算支持?

哥哥。

可以指定下载多少个ts吗?
可以指定从多少秒开始,到多少秒结束。进行下载吗?

How to add a request header?

How to add a request header for a download request?
I tried adding addRequestProperty("name", "www.com") to HttpURLConnection conn to M3U8Downloader.java but that didn't work

conn.addRequestProperty("name", "www.com");

Any help is really appreciated

解析M3U8文件时,发现个BUG

parseIndex方法,以及Ts:

if (line.endsWith("m3u8")) {
    if(line.startsWith("/")) { // 取根路径
         return parseIndex(contactUrl(domainPath,line));
     } else { // 继承上一路径
        return parseIndex(contactUrl(basePath,line));
     }
 }

How to use header?

How to download a video with request headers? Is there a way to headers for download request?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.