Skip to content
Permalink
Browse files

增加立即恢复任务的接口,正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。如果希望调用恢复接口,马上进入执行队列,需要…

…调用`resume(true)`这个重载方法。

修复一个非分块模式下,无法恢复下载的问题
增加M3U8加密密钥的下载地址转换器 #522
  • Loading branch information
AriaLyy committed Nov 27, 2019
1 parent c9c00c3 commit c4cc804c67cfe37108b1eef32d37c2329eb79939
Showing with 151 additions and 38 deletions.
  1. +2 −2 Aria/src/main/java/com/arialyy/aria/core/command/AbsCmdFactory.java
  2. +0 −8 Aria/src/main/java/com/arialyy/aria/core/command/AbsNormalCmd.java
  3. +2 −2 Aria/src/main/java/com/arialyy/aria/core/command/NormalCmdFactory.java
  4. +16 −2 Aria/src/main/java/com/arialyy/aria/core/command/StartCmd.java
  5. +11 −1 Aria/src/main/java/com/arialyy/aria/core/common/AbsNormalTarget.java
  6. +8 −0 Aria/src/main/java/com/arialyy/aria/core/common/controller/INormalFeature.java
  7. +17 −3 Aria/src/main/java/com/arialyy/aria/core/common/controller/NormalController.java
  8. +13 −0 Aria/src/main/java/com/arialyy/aria/core/download/m3u8/M3U8Option.java
  9. +6 −1 DEV_LOG.md
  10. +1 −0 HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java
  11. +10 −2 M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java
  12. +14 −0 M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8TaskOption.java
  13. +2 −1 PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java
  14. +32 −0 PublicComponent/src/main/java/com/arialyy/aria/core/processor/IKeyUrlConverter.java
  15. +8 −8 PublicComponent/src/main/java/com/arialyy/aria/util/CommonUtil.java
  16. +1 −1 app/src/main/assets/aria_config.xml
  17. +2 −2 app/src/main/java/com/arialyy/simple/core/download/HttpDownloadModule.java
  18. +2 −1 app/src/main/java/com/arialyy/simple/core/download/SingleTaskActivity.java
  19. +4 −4 app/src/main/java/com/arialyy/simple/core/download/mutil/DownloadAdapter.java
@@ -15,6 +15,7 @@
*/
package com.arialyy.aria.core.command;

import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;

/**
@@ -25,8 +26,7 @@

/**
* @param entity 下载实体
* @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link
* ICmd#TASK_TYPE_UPLOAD}
* {@link ITask#DOWNLOAD}、{@link ITask#DOWNLOAD_GROUP}、{@link ITask#UPLOAD}
*/
public abstract CMD createCmd(TASK_ENTITY entity, int type, int taskType);
}
@@ -157,14 +157,6 @@ void resumeTask() {
mQueue.resumeTask(task);
}

/**
* 启动指定任务
*
* @param task 指定任务
*/
void startTask(AbsTask task) {
mQueue.startTask(task);
}

/**
* 从队列中获取任务
@@ -16,6 +16,7 @@

package com.arialyy.aria.core.command;

import com.arialyy.aria.core.task.ITask;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;

/**
@@ -83,8 +84,7 @@ public static NormalCmdFactory getInstance() {
* @param entity 下载实体
* @param type 命令类型{@link #TASK_CREATE}、{@link #TASK_START}、{@link #TASK_CANCEL}、{@link
* #TASK_STOP}、{@link #TASK_HIGHEST_PRIORITY}、{@link #TASK_STOP_ALL}、{@link #TASK_RESUME_ALL}
* @param taskType {@link ICmd#TASK_TYPE_DOWNLOAD}、{@link ICmd#TASK_TYPE_DOWNLOAD_GROUP}、{@link
* ICmd#TASK_TYPE_UPLOAD}
* @param taskType {@link ITask#DOWNLOAD}、{@link ITask#DOWNLOAD_GROUP}、{@link ITask#UPLOAD}
*/
public AbsNormalCmd createCmd(AbsTaskWrapper entity, int type, int taskType) {
switch (type) {
@@ -27,12 +27,22 @@
/**
* Created by lyy on 2016/8/22. 开始命令 队列模型{@link QueueMod#NOW}、{@link QueueMod#WAIT}
*/
final class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {
final public class StartCmd<T extends AbsTaskWrapper> extends AbsNormalCmd<T> {

private boolean newStart = false;

StartCmd(T entity, int taskType) {
super(entity, taskType);
}

/**
* 立即执行任务
* @param newStart true 立即执行任务,无论执行队列是否满了
*/
public void setNewStart(boolean newStart) {
this.newStart = newStart;
}

@Override public void executeCmd() {
if (!canExeCmd) return;
if (!NetUtils.isConnected(AriaManager.getInstance().getAPP())) {
@@ -71,7 +81,11 @@
startTask();
}
} else {
sendWaitState(task);
if (newStart){
startTask();
}else {
sendWaitState(task);
}
}
}
} else {
@@ -150,7 +150,17 @@ public void stop() {
*/
@Override
public void resume() {
getController().resume();
resume(false);
}

/**
* 正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。
* 如果希望调用恢复接口,马上进入执行队列,需要使用该方法
*
* @param newStart true 立即将任务恢复到执行队列中
*/
@Override public void resume(boolean newStart) {
getController().resume(newStart);
}

/**
@@ -30,6 +30,14 @@
*/
void resume();

/**
* 正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。
* 如果希望调用恢复接口,马上进入执行队列,需要使用该方法
*
* @param newStart true 立即将任务恢复到执行队列中
*/
void resume(boolean newStart);

/**
* 删除任务
*/
@@ -16,11 +16,12 @@
package com.arialyy.aria.core.common.controller;

import com.arialyy.aria.core.command.CancelCmd;
import com.arialyy.aria.core.command.CmdHelper;
import com.arialyy.aria.core.command.NormalCmdFactory;
import com.arialyy.aria.core.command.StartCmd;
import com.arialyy.aria.core.event.EventMsgUtil;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.core.command.CmdHelper;

/**
* 启动控制器
@@ -49,10 +50,23 @@ public void stop() {
*/
@Override
public void resume() {
resume(false);
}

/**
* 正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。
* 如果希望调用恢复接口,马上进入执行队列,需要使用该方法
*
* @param newStart true 立即将任务恢复到执行队列中
*/
@Override public void resume(boolean newStart) {
if (checkConfig()) {
StartCmd cmd =
(StartCmd) CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
checkTaskType());
cmd.setNewStart(newStart);
EventMsgUtil.getDefault()
.post(CmdHelper.createNormalCmd(getTaskWrapper(), NormalCmdFactory.TASK_START,
checkTaskType()));
.post(cmd);
}
}

@@ -17,6 +17,7 @@

import com.arialyy.aria.core.common.BaseOption;
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
import com.arialyy.aria.core.processor.IKeyUrlConverter;
import com.arialyy.aria.core.processor.ITsMergeHandler;
import com.arialyy.aria.util.CheckUtil;
import com.arialyy.aria.util.ComponentUtil;
@@ -31,6 +32,7 @@
private int bandWidth;
private ITsMergeHandler mergeHandler;
private IBandWidthUrlConverter bandWidthUrlConverter;
private IKeyUrlConverter keyUrlConverter;

M3U8Option() {
super();
@@ -88,4 +90,15 @@ public OP setBandWidthUrlConverter(IBandWidthUrlConverter bandWidthUrlConverter)
this.bandWidthUrlConverter = bandWidthUrlConverter;
return (OP) this;
}

/**
* M3U8 密钥url转换器,对于某些服务器,密钥的下载地址是被加密的,因此需要使用该方法将被加密的密钥解密成可被识别的http地址
*
* @param keyUrlConverter {@link IKeyUrlConverter}
*/
public OP setKeyUrlConverter(IKeyUrlConverter keyUrlConverter) {
CheckUtil.checkMemberClass(keyUrlConverter.getClass());
this.keyUrlConverter = keyUrlConverter;
return (OP) this;
}
}
@@ -1,6 +1,11 @@
## 开发日志
+ v_3.7.8-pre-1(2019/11/20)
+ v_3.7.8
- fix bug https://github.com/AriaLyy/Aria/issues/526
- fix bug https://github.com/AriaLyy/Aria/issues/533
- fix bug https://github.com/AriaLyy/Aria/issues/535
- 修复ftp无法完成下载的问题
- 增加立即恢复任务的接口,正常来说,当执行队列满时,调用恢复任务接口,只能将任务放到缓存队列中。如果希望调用恢复接口,马上进入执行队列,需要调用`resume(true)`这个重载方法。
- 增加M3U8加密密钥的下载地址转换器 https://github.com/AriaLyy/Aria/issues/522
+ v_3.7.7 (2019/11/20)
- 修复ftp无法完成下载的问题
- 修复一个http下载崩溃的问题
@@ -24,6 +24,7 @@
import com.arialyy.aria.http.ConnectionHelp;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.BufferedRandomAccessFile;
import com.arialyy.aria.util.FileUtil;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -26,6 +26,7 @@
import com.arialyy.aria.core.download.M3U8Entity;
import com.arialyy.aria.core.inf.OnFileInfoCallback;
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
import com.arialyy.aria.core.processor.IKeyUrlConverter;
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
import com.arialyy.aria.core.wrapper.ITaskWrapper;
import com.arialyy.aria.exception.M3U8Exception;
@@ -127,7 +128,7 @@ private void handleConnect(HttpURLConnection conn) throws IOException {
File indexFile = new File(indexPath);
if (!indexFile.exists()) {
FileUtil.createFile(indexPath);
}else {
} else {
//FileUtil.deleteFile(indexPath);
}
fos = new FileOutputStream(indexFile);
@@ -353,7 +354,14 @@ private void downloadKey(M3U8Entity info) {
} else {
return;
}
URL url = ConnectionHelp.handleUrl(info.keyUrl, mHttpOption);

IKeyUrlConverter keyUrlConverter = mM3U8Option.getKeyUrlConverter();
String keyUrl = info.keyUrl;
if (keyUrlConverter != null) {
keyUrl = keyUrlConverter.convert(keyUrl);
}

URL url = ConnectionHelp.handleUrl(keyUrl, mHttpOption);
conn = ConnectionHelp.handleConnection(url, mHttpOption);
ConnectionHelp.setConnectParam(mHttpOption, conn);
conn.setConnectTimeout(mConnectTimeOut);
@@ -17,6 +17,7 @@

import com.arialyy.aria.core.inf.ITaskOption;
import com.arialyy.aria.core.processor.IBandWidthUrlConverter;
import com.arialyy.aria.core.processor.IKeyUrlConverter;
import com.arialyy.aria.core.processor.ILiveTsUrlConverter;
import com.arialyy.aria.core.processor.ITsMergeHandler;
import com.arialyy.aria.core.processor.IVodTsUrlConverter;
@@ -103,6 +104,19 @@
*/
private boolean generateIndexFile = false;

/**
* 加密密钥的解密处理器
*/
private SoftReference<IKeyUrlConverter> keyUrlConverter;

public IKeyUrlConverter getKeyUrlConverter() {
return keyUrlConverter == null ? null : keyUrlConverter.get();
}

public void setKeyUrlConverter(IKeyUrlConverter keyUrlConverter) {
this.keyUrlConverter = new SoftReference<>(keyUrlConverter);
}

public boolean isGenerateIndexFile() {
return generateIndexFile;
}
@@ -63,7 +63,8 @@ public void handleMultiRecord() {
fileExists = true;
}
// 处理文件被删除的情况
if (fileExists) {
if (!fileExists) {
ALog.w(TAG, String.format("文件【%s】被删除,重新分配线程区间", mTaskRecord.filePath));
for (int i = 0; i < mTaskRecord.threadNum; i++) {
long startL = i * blockSize, endL = (i + 1) * blockSize;
ThreadRecord tr = mTaskRecord.threadRecords.get(i);
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.arialyy.aria.core.processor;

import com.arialyy.aria.core.inf.IEventHandler;

/**
* M3U8 密钥下载地址处理器,可用于解密被加密的密钥的下载地址
*/
public interface IKeyUrlConverter extends IEventHandler {

/**
* 将被加密的密钥下载地址转换为可使用的http下载地址
*
* @param keyUrl 加密的url地址
* @return 可正常访问的http地址
*/
String convert(String keyUrl);
}
@@ -71,15 +71,15 @@ public static boolean checkSqlExpression(String... expression) {
ALog.e(TAG, "sql语句表达式不能为null");
return false;
}
if (expression.length == 1) {
ALog.e(TAG, String.format("表达式需要写入参数,参数信息:%s", Arrays.toString(expression)));
return false;
}
//if (expression.length == 1) {
// ALog.e(TAG, String.format("表达式需要写入参数,参数信息:%s", Arrays.toString(expression)));
// return false;
//}
String where = expression[0];
if (!where.contains("?")) {
ALog.e(TAG, String.format("请在where语句的'='后编写?,参数信息:%s", Arrays.toString(expression)));
return false;
}
//if (!where.contains("?")) {
// ALog.e(TAG, String.format("请在where语句的'='后编写?,参数信息:%s", Arrays.toString(expression)));
// return false;
//}
Pattern pattern = Pattern.compile("\\?");
Matcher matcher = pattern.matcher(where);
int count = 0;
@@ -32,7 +32,7 @@
3、只对新的多线程下载任务有效
4、只对多线程的任务有效
-->
<useBlock value="true"/>
<useBlock value="false"/>

<!--设置下载线程数,下载线程数不能小于1
注意:
@@ -51,8 +51,8 @@
//String url = AppUtil.getConfigValue(context, HTTP_URL_KEY, defUrl);
//String url =
// "http://sdkdown.muzhiwan.com/openfile/2019/05/21/com.netease.tom.mzw_5ce3ef8754d05.apk";
//String url = "http://image.totwoo.com/totwoo-TOTWOO-v3.5.6.apk";
String url = "https://imtt.dd.qq.com/16891/apk/70BFFDB05AB8686F2A4CF3E07588A377.apk?fsname=com.tencent.tmgp.speedmobile_1.16.0.33877_1160033877.apk&csr=1bbd";
String url = "http://image.totwoo.com/totwoo-TOTWOO-v3.5.6.apk";
//String url = "https://imtt.dd.qq.com/16891/apk/70BFFDB05AB8686F2A4CF3E07588A377.apk?fsname=com.tencent.tmgp.speedmobile_1.16.0.33877_1160033877.apk&csr=1bbd";
//String url = "https://ss1.baidu.com/-4o3dSag_xI4khGko9WTAnF6hhy/image/h%3D300/sign=a9e671b9a551f3dedcb2bf64a4eff0ec/4610b912c8fcc3cef70d70409845d688d53f20f7.jpg";
String filePath = AppUtil.getConfigValue(context, HTTP_PATH_KEY, defFilePath);

@@ -276,8 +276,9 @@ public void onClick(View view) {
if (Aria.download(this).load(mTaskId).isRunning()) {
Aria.download(this).load(mTaskId).stop();
} else {
mUrl = "http://sdkdown.muzhiwan.com/openfile/2019/07/11/com.netease.syfz.mzw_5d26f8d9cee27.apk";
Aria.download(this).load(mTaskId)
.updateUrl("http://sdkdown.muzhiwan.com/openfile/2019/07/11/com.netease.syfz.mzw_5d26f8d9cee27.apk")
.updateUrl(mUrl)
.resume();
}
break;
@@ -307,17 +307,17 @@ private void resume(AbsEntity entity) {
switch (entity.getTaskType()) {
case ITaskWrapper.D_FTP:
//Aria.download(getContext()).loadFtp((DownloadEntity) entity).login("lao", "123456").create();
Aria.download(getContext()).loadFtp(entity.getId()).resume();
Aria.download(getContext()).loadFtp(entity.getId()).resume(true);
break;
case ITaskWrapper.D_FTP_DIR:
Aria.download(getContext()).loadFtpDir(entity.getId()).resume();
Aria.download(getContext()).loadFtpDir(entity.getId()).resume(true);
break;
case ITaskWrapper.D_HTTP:
case ITaskWrapper.M3U8_VOD:
Aria.download(getContext()).load(entity.getId()).resume();
Aria.download(getContext()).load(entity.getId()).resume(true);
break;
case ITaskWrapper.DG_HTTP:
Aria.download(getContext()).loadGroup(entity.getId()).resume();
Aria.download(getContext()).loadGroup(entity.getId()).resume(true);
break;
}
}

0 comments on commit c4cc804

Please sign in to comment.
You can’t perform that action at this time.