{"id":13908607,"url":"https://github.com/JeffMony/VideoDownloader","last_synced_at":"2025-07-18T07:31:43.953Z","repository":{"id":40761374,"uuid":"249930751","full_name":"JeffMony/VideoDownloader","owner":"JeffMony","description":"支持下载队列，支持M3U8视频、MP4视频等，支持M3U8合并为MP4视频。","archived":false,"fork":false,"pushed_at":"2023-11-14T16:18:21.000Z","size":24214,"stargazers_count":460,"open_issues_count":26,"forks_count":121,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-11-25T17:46:24.257Z","etag":null,"topics":["downloadqueue","m3u8-downloader","m3u8downloader","m3u8merge","videocache","videodownload"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JeffMony.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-03-25T08:59:39.000Z","updated_at":"2024-11-25T05:27:27.000Z","dependencies_parsed_at":"2023-11-14T17:38:42.193Z","dependency_job_id":null,"html_url":"https://github.com/JeffMony/VideoDownloader","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/JeffMony/VideoDownloader","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffMony%2FVideoDownloader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffMony%2FVideoDownloader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffMony%2FVideoDownloader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffMony%2FVideoDownloader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JeffMony","download_url":"https://codeload.github.com/JeffMony/VideoDownloader/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JeffMony%2FVideoDownloader/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265720600,"owners_count":23817269,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["downloadqueue","m3u8-downloader","m3u8downloader","m3u8merge","videocache","videodownload"],"created_at":"2024-08-06T23:02:51.617Z","updated_at":"2025-07-18T07:31:43.573Z","avatar_url":"https://github.com/JeffMony.png","language":"Java","funding_links":[],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"# VideoDownloader\n#### 视频下载SDK功能\n\u003e * 下载整视频，如mp4/mkv/mov/3gp等视频\n\u003e * 下载HLS，即M3U8视频\n\u003e * M3U8 视频下载完成，会生成一个本地的local.m3u8文件\n\u003e * 视频下载完成，可以点击播放视频文件\n\u003e * 视频下载数据库记录视频下载信息\n\u003e * 增加视频下载队列\n\u003e * 增加M3U8合并为MP4的功能\n\u003e * 可以定制下载视频的标题和封面\n\u003e * 增加视频下载的group-name  \n\n#### 版本更新\n##### 5.8.0\n\u003e * 解决下载成功回调多次的问题\n\u003e * 解决ffmpeg中合并出现pts异常的问题,测试用例是:https://vod7.wenshibaowenbei.com/20210514/g79ixT00/index.m3u8\n##### 5.7.0\n\u003e * 解决合并时的HLS 支持hls-allowed_extensions ALL\n##### 5.6.0\n\u003e * 裁剪ffmpeg库，从10M降至1M\n\u003e * 优化TS合并逻辑\n\u003e * 提供armeabi-v7a   arm64-v8a   x86   x86_86四种so库\n##### 5.5.0\n\u003e * 增加视频下载的分组名\n##### 5.4.0\n\u003e * 可以定制视频下载的封面和标题\n##### 5.3.0\n\u003e * 优化M3U8合并为MP4的过程，解决时间戳不连续导致的合并失败的问题\n\u003e * 优化视频下载成功率\n##### 4.2.0\n\u003e * 优化TS合并逻辑\n##### 4.1.0\n\u003e * M3U8文件下载完成后合并为MP4文件\n\u003e * 优化部分HTTPS链接下载失败的问题\n##### 3.0.0\n\u003e * 解决部分M3U8视频下载失败的问题\n\u003e * 更新playersdk版本\n\u003e * 优化fileName和filePath问题\n\n在build.gradle中引入\n```\nallprojects {\n    repositories {\n\t    maven { url 'https://jitpack.io' }\n\t}\n}\n```\n\n在demo中直接引用\n```\ndependencies {\n    implementation 'com.github.JeffMony:VideoDownloader:5.8.0'\n}\n```\n\n如果需要使用M3U8合并为MP4的功能，还需要额外引入(因为这个包有点大，如果需要就引入吧)\n```\ndependencies {\n    implementation 'com.github.JeffMony:JeffFFmpegDemo:1.6.0'\n}\n```\n\n如果想使用的合并库小一点.也可以使用较小的库,可以裁减很大的包\n```\ndependencies {\n    implementation 'com.github.JeffMony:JeffM3U8Lib:1.2.0'\n}\n```\n\n#### 视频下载SDK接入\u003cbr\u003e\n##### 1.应用启动的时候注册download config\n```\nFile file = VideoDownloadUtils.getVideoCacheDir(this);\nif (!file.exists()) {\n    file.mkdir();\n}\nVideoDownloadConfig config = new VideoDownloadManager.Build(this)\n    .setCacheRoot(file)\n    .setUrlRedirect(true)\n    .setTimeOut(DownloadConstants.READ_TIMEOUT, DownloadConstants.CONN_TIMEOUT)\n    .setConcurrentCount(DownloadConstants.CONCURRENT)\n    .setIgnoreCertErrors(true)\n    .setShouldM3U8Merged(true)\n    .buildConfig();\nVideoDownloadManager.getInstance().initConfig(config);\n```\n##### 2.注册download listener回调，这个回调只要注册一次就行了，是全局回调\n```\nVideoDownloadManager.getInstance().setGlobalDownloadListener(mListener);\n\nprivate DownloadListener mListener = new DownloadListener() {\n\n    @Override\n    public void onDownloadDefault(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadPending(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadPrepare(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadStart(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadProgress(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadSpeed(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadPause(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadError(VideoTaskItem item) {}\n\n    @Override\n    public void onDownloadSuccess(VideoTaskItem item) {}\n};\n```\nVideoTaskItem中信息介绍\n```\npublic class VideoTaskItem implements Cloneable {\n\n    private String mUrl;                 //下载视频的url\n    private long mDownloadCreateTime;    //下载创建的时间\n    private int mTaskState;              //当前任务的状态\n    private String mMimeType;            // 视频url的mime type\n    private String mFinalUrl;            //30x跳转之后的url\n    private int mErrorCode;              //当前任务下载错误码\n    private int mVideoType;              //当前文件类型\n    private M3U8 mM3U8;                  //M3U8结构,如果非M3U8,则为null\n    private int mTotalTs;                //当前M3U8的总分片\n    private int mCurTs;                  //当前M3U8已缓存的分片\n    private float mSpeed;                //当前下载速度, getSpeedString 函数可以将速度格式化\n    private float mPercent;              //当前下载百分比, 0 ~ 100,是浮点数\n    private long mDownloadSize;          //已下载大小, getDownloadSizeString 函数可以将大小格式化\n    private long mTotalSize;             //文件总大小, M3U8文件无法准确获知\n    private String mFileHash;            //文件名的md5\n    private String mSaveDir;             //保存视频文件的文件目录名\n    private boolean mIsCompleted;        //是否下载完成\n    private boolean mIsInDatabase;       //是否存到数据库中\n    private long mLastUpdateTime;        //上一次更新数据库的时间\n    private String mFileName;            //文件名\n    private String mFilePath;            //文件完整路径(包括文件名)\n    private boolean mPaused;\n\n}\n```\n\nVideoTaskState下载状态信息介绍\n```\npublic class VideoTaskState {\n    public static final int DEFAULT = 0;//默认状态\n    public static final int PENDING = -1;//下载排队\n    public static final int PREPARE = 1;//下载准备中\n    public static final int START = 2;  //开始下载\n    public static final int DOWNLOADING = 3;//下载中\n    public static final int PROXYREADY = 4; //视频可以边下边播\n    public static final int SUCCESS = 5;//下载完成\n    public static final int ERROR = 6;//下载出错\n    public static final int PAUSE = 7;//下载暂停\n    public static final int ENOSPC = 8;//空间不足\n}\n```\n##### 3.获取当前的下载任务\n```\nVideoDownloadManager.getInstance().fetchDownloadItems(IDownloadInfosCallback callback)\n\npublic interface IDownloadInfosCallback {\n    void onDownloadInfos(List\u003cVideoTaskItem\u003e items);\n}\n```\n接口返回的List\u003cVideoTaskItem\u003e就是当前正在下载的任务\n\n##### 4.启动下载\n```\nVideoDownloadManager.getInstance().startDownload(item);\n```\n##### 5.暂停下载\n```\nVideoDownloadManager.getInstance().pauseDownloadTask(item.getUrl());\n```\n##### 6.恢复下载\n```\nVideoDownloadManager.getInstance().pauseDownloadTask(item.getUrl());\n```\n##### 7.删除下载任务\n```\nVideoDownloadManager.getInstance().deleteVideoTask(String videoUrl, boolean shouldDeleteSourceFile)\n```\n##### 8.全部暂停\n```\nVideoDownloadManager.getInstance().pauseDownloadTask(List\u003cString\u003e urlList)\n```\n\n##### 9.M3U8合并接口\n```\n        VideoProcessManager.getInstance().mergeTs(inputFilePath, outputFilePath, new IM3U8MergeListener() {\n            @Override\n            public void onMergedFinished() {\n                LogUtils.i(TAG, \"onMergedFinished\");\n                Toast.makeText(VideoMergeActivity.this, \"合并成功\", Toast.LENGTH_SHORT).show();\n            }\n\n            @Override\n            public void onMergeFailed(Exception e) {\n                LogUtils.i(TAG, \"onMergeFailed, e=\" + e.getMessage());\n                Toast.makeText(VideoMergeActivity.this, \"合并失败\", Toast.LENGTH_SHORT).show();\n            }\n        });\n```\n\n##### 功能示意\n![](./files/test1.jpg)![](./files/test2.jpg)![](./files/test3.jpg)\n\n欢迎关注我的公众号JeffMony，我会持续为你带来音视频---算法---Android---python 方面的知识分享\u003cbr\u003e\n![](./files/JeffMony.jpg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJeffMony%2FVideoDownloader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJeffMony%2FVideoDownloader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJeffMony%2FVideoDownloader/lists"}