parent
1469ca1cea
commit
b052ef6642
@ -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.download.m3u8; |
||||||
|
|
||||||
|
/** |
||||||
|
* M3U8 bandWidth 码率url转换器,对于某些服务器,返回的ts地址可以是相对地址,也可能是处理过的, |
||||||
|
* 对于这种情况,你需要使用url转换器将地址转换为可正常访问的http地址 |
||||||
|
*/ |
||||||
|
public interface IBandWidthUrlConverter { |
||||||
|
|
||||||
|
/** |
||||||
|
* 转换码率地址为可用的http地址,对于某些服务器,返回的切片信息有可能是相对地址,也可能是处理过的, |
||||||
|
* 对于这种情况,你需要使用url转换器将地址转换为可正常访问的http地址 |
||||||
|
* |
||||||
|
* @param bandWidthUrl 原始码率地址 |
||||||
|
* @return 可正常访问的http地址 |
||||||
|
*/ |
||||||
|
String convert(String bandWidthUrl); |
||||||
|
} |
@ -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.download.m3u8; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* Ts文件合并处理,如果你希望使用自行处理ts文件的合并,你可以实现该接口 |
||||||
|
*/ |
||||||
|
public interface ITsMergeHandler { |
||||||
|
|
||||||
|
/** |
||||||
|
* 合并ts文件 |
||||||
|
* |
||||||
|
* @param tsPath ts文件列表 |
||||||
|
* @return {@code true} 合并成功 |
||||||
|
*/ |
||||||
|
boolean merge(List<String> tsPath); |
||||||
|
} |
@ -1,140 +0,0 @@ |
|||||||
///*
|
|
||||||
// * 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.download.m3u8;
|
|
||||||
//
|
|
||||||
//import android.os.Bundle;
|
|
||||||
//import android.os.Looper;
|
|
||||||
//import android.os.Message;
|
|
||||||
//import com.arialyy.aria.core.common.IThreadState;
|
|
||||||
//import com.arialyy.aria.core.common.TaskRecord;
|
|
||||||
//import com.arialyy.aria.core.download.DTaskWrapper;
|
|
||||||
//import com.arialyy.aria.core.inf.IEventListener;
|
|
||||||
//import com.arialyy.aria.exception.BaseException;
|
|
||||||
//import com.arialyy.aria.util.ALog;
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// * M3U8线程状态管理
|
|
||||||
// */
|
|
||||||
//public class M3U8ThreadStateManager implements IThreadState {
|
|
||||||
// private final String TAG = "M3U8ThreadStateManager";
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 任务状态回调
|
|
||||||
// */
|
|
||||||
// private IEventListener mListener;
|
|
||||||
// private int mThreadNum; // 启动的线程总数
|
|
||||||
// private int mCancelNum = 0; // 已经取消的线程的数
|
|
||||||
// private int mStopNum = 0; // 已经停止的线程数
|
|
||||||
// private int mFailNum = 0; // 失败的线程数
|
|
||||||
// private int mCompleteNum = 0; // 完成的线程数
|
|
||||||
// private long mProgress; //当前总进度
|
|
||||||
// private TaskRecord mTaskRecord; // 任务记录
|
|
||||||
// private Looper mLooper;
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * @param taskRecord 任务记录
|
|
||||||
// * @param listener 任务事件
|
|
||||||
// */
|
|
||||||
// M3U8ThreadStateManager(Looper looper, TaskRecord taskRecord, IEventListener listener) {
|
|
||||||
// mLooper = looper;
|
|
||||||
// mTaskRecord = taskRecord;
|
|
||||||
// mThreadNum = mTaskRecord.threadNum;
|
|
||||||
// mListener = listener;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 退出looper循环
|
|
||||||
// */
|
|
||||||
// private void quitLooper() {
|
|
||||||
// mLooper.quit();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override public boolean handleMessage(Message msg) {
|
|
||||||
// switch (msg.what) {
|
|
||||||
// case STATE_STOP:
|
|
||||||
// mStopNum++;
|
|
||||||
// if (isStop()) {
|
|
||||||
// mListener.onStop(mProgress);
|
|
||||||
// quitLooper();
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case STATE_CANCEL:
|
|
||||||
// mCancelNum++;
|
|
||||||
// if (isCancel()) {
|
|
||||||
// ALog.d(TAG, "icCancel");
|
|
||||||
// mListener.onCancel();
|
|
||||||
// quitLooper();
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case STATE_FAIL:
|
|
||||||
// mFailNum++;
|
|
||||||
// if (isFail()) {
|
|
||||||
// Bundle b = msg.getData();
|
|
||||||
// mListener.onFail(b.getBoolean(KEY_RETRY, true),
|
|
||||||
// (BaseException) b.getSerializable(KEY_ERROR_INFO));
|
|
||||||
// quitLooper();
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case STATE_COMPLETE:
|
|
||||||
// mCompleteNum++;
|
|
||||||
// if (isComplete()) {
|
|
||||||
// ALog.d(TAG, "isComplete, completeNum = " + mCompleteNum);
|
|
||||||
// if (mTaskRecord.isBlock) {
|
|
||||||
// if (mergeFile()) {
|
|
||||||
// mListener.onComplete();
|
|
||||||
// } else {
|
|
||||||
// mListener.onFail(false, null);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// mListener.onComplete();
|
|
||||||
// }
|
|
||||||
// quitLooper();
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case STATE_RUNNING:
|
|
||||||
// mProgress += (long) msg.obj;
|
|
||||||
// break;
|
|
||||||
// case STATE_UPDATE_PROGRESS:
|
|
||||||
// if (msg.obj == null) {
|
|
||||||
// mProgress = updateBlockProgress();
|
|
||||||
// } else {
|
|
||||||
// mProgress = (long) msg.obj;
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override public boolean isStop() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override public boolean isFail() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override public boolean isComplete() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override public boolean isCancel() {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override public long getCurrentProgress() {
|
|
||||||
// return mProgress;
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -0,0 +1,380 @@ |
|||||||
|
/* |
||||||
|
* 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.util; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.common.RecordHandler; |
||||||
|
import com.arialyy.aria.core.common.RecordWrapper; |
||||||
|
import com.arialyy.aria.core.common.TaskRecord; |
||||||
|
import com.arialyy.aria.core.common.ThreadRecord; |
||||||
|
import com.arialyy.aria.core.download.DownloadEntity; |
||||||
|
import com.arialyy.aria.core.download.DownloadGroupEntity; |
||||||
|
import com.arialyy.aria.core.download.m3u8.M3U8FileLoader; |
||||||
|
import com.arialyy.aria.core.inf.AbsEntity; |
||||||
|
import com.arialyy.aria.core.inf.AbsNormalEntity; |
||||||
|
import com.arialyy.aria.core.upload.UploadEntity; |
||||||
|
import com.arialyy.aria.orm.DbEntity; |
||||||
|
import java.io.File; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 任务记录处理工具 |
||||||
|
*/ |
||||||
|
public class RecordUtil { |
||||||
|
private static final String TAG = "RecordUtil"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除任务组记录 |
||||||
|
* |
||||||
|
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件; |
||||||
|
* {@code false} 如果任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。 |
||||||
|
*/ |
||||||
|
public static void delGroupTaskRecord(String groupHash, boolean removeFile) { |
||||||
|
if (TextUtils.isEmpty(groupHash)) { |
||||||
|
ALog.e(TAG, "删除下载任务组记录失败,groupHash为null"); |
||||||
|
return; |
||||||
|
} |
||||||
|
DownloadGroupEntity groupEntity = DbDataHelper.getDGEntity(groupHash); |
||||||
|
|
||||||
|
delGroupTaskRecord(groupEntity, removeFile, true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除任务组记录 |
||||||
|
* |
||||||
|
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件; |
||||||
|
* {@code false} 如果任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。 |
||||||
|
*/ |
||||||
|
public static void delGroupTaskRecord(DownloadGroupEntity groupEntity, boolean removeFile, |
||||||
|
boolean removeEntity) { |
||||||
|
if (groupEntity == null) { |
||||||
|
ALog.e(TAG, "删除下载任务组记录失败,任务组实体为null"); |
||||||
|
return; |
||||||
|
} |
||||||
|
List<RecordWrapper> records = |
||||||
|
DbEntity.findRelationData(RecordWrapper.class, "dGroupHash=?", groupEntity.getGroupHash()); |
||||||
|
|
||||||
|
if (records == null || records.isEmpty()) { |
||||||
|
ALog.w(TAG, "组任务记录删除失败,记录为null"); |
||||||
|
} else { |
||||||
|
for (RecordWrapper record : records) { |
||||||
|
if (record == null || record.taskRecord == null) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
// 删除分块文件
|
||||||
|
if (record.taskRecord.isBlock) { |
||||||
|
for (int i = 0, len = record.taskRecord.threadNum; i < len; i++) { |
||||||
|
File partFile = |
||||||
|
new File(String.format(RecordHandler.SUB_PATH, record.taskRecord.filePath, i)); |
||||||
|
if (partFile.exists()) { |
||||||
|
partFile.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
DbEntity.deleteData(ThreadRecord.class, "key=?", record.taskRecord.filePath); |
||||||
|
record.taskRecord.deleteData(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
List<DownloadEntity> subs = groupEntity.getSubEntities(); |
||||||
|
if (subs != null) { |
||||||
|
for (DownloadEntity sub : subs) { |
||||||
|
File file = new File(sub.getFilePath()); |
||||||
|
if (file.exists() && (removeFile || !sub.isComplete())) { |
||||||
|
file.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// 删除文件夹
|
||||||
|
if (!TextUtils.isEmpty(groupEntity.getDirPath())) { |
||||||
|
File dir = new File(groupEntity.getDirPath()); |
||||||
|
if (dir.exists() && (removeFile || !groupEntity.isComplete())) { |
||||||
|
dir.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
if (removeEntity) { |
||||||
|
DbEntity.deleteData(DownloadEntity.class, "groupHash=?", groupEntity.getGroupHash()); |
||||||
|
DbEntity.deleteData(DownloadGroupEntity.class, "groupHash=?", groupEntity.getGroupHash()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除任务记录,默认删除文件 |
||||||
|
* |
||||||
|
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件; |
||||||
|
* {@code false} 如果是下载任务,并且任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。 |
||||||
|
* 如果是上传任务,无论任务是否完成,都只删除记录 |
||||||
|
*/ |
||||||
|
public static void delTaskRecord(AbsNormalEntity entity, boolean removeFile) { |
||||||
|
if (entity == null) return; |
||||||
|
String filePath; |
||||||
|
int type; |
||||||
|
if (entity instanceof DownloadEntity) { |
||||||
|
type = RecordHandler.TYPE_DOWNLOAD; |
||||||
|
filePath = ((DownloadEntity) entity).getDownloadPath(); |
||||||
|
} else if (entity instanceof UploadEntity) { |
||||||
|
type = RecordHandler.TYPE_UPLOAD; |
||||||
|
filePath = ((UploadEntity) entity).getFilePath(); |
||||||
|
} else { |
||||||
|
ALog.w(TAG, "删除记录失败,未知类型"); |
||||||
|
return; |
||||||
|
} |
||||||
|
File targetFile = new File(filePath); |
||||||
|
TaskRecord record = getTaskRecord(filePath); |
||||||
|
if (record == null) { |
||||||
|
if (removeFile) { |
||||||
|
removeTargetFile(targetFile); |
||||||
|
} |
||||||
|
removeRecord(filePath); |
||||||
|
removeEntity(type, filePath); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* 处理任务未完成的情况 |
||||||
|
*/ |
||||||
|
if (!entity.isComplete()) { |
||||||
|
if (record.taskType == TaskRecord.TYPE_M3U8) { // 删除ts分片文件
|
||||||
|
String cacheDir = null; |
||||||
|
if (!targetFile.isDirectory()) { |
||||||
|
cacheDir = targetFile.getParent() + "/." + targetFile.getName(); |
||||||
|
} |
||||||
|
removeTsCache(record, cacheDir); |
||||||
|
} else if (record.isBlock) { // 删除分块文件
|
||||||
|
removeBlockFile(record); |
||||||
|
} |
||||||
|
} else if (removeFile) { // 处理任务完成情况
|
||||||
|
removeTargetFile(targetFile); |
||||||
|
} |
||||||
|
|
||||||
|
// 成功与否都将删除记录
|
||||||
|
removeRecord(filePath); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除任务记录,默认删除文件 |
||||||
|
* |
||||||
|
* @param filePath 文件路径 |
||||||
|
* @param removeFile {@code true} 无论任务是否完成,都会删除记录和文件; |
||||||
|
* {@code false} 如果是下载任务,并且任务已经完成,则只删除记录,不删除文件;任务未完成,记录和文件都会删除。 |
||||||
|
* 如果是上传任务,无论任务是否完成,都只删除记录 |
||||||
|
* @param type {@link RecordHandler#TYPE_DOWNLOAD}下载任务的记录,{@link RecordHandler#TYPE_UPLOAD} |
||||||
|
* 上传任务的记录 |
||||||
|
* @param removeEntity {@code true} 删除任务实体, |
||||||
|
*/ |
||||||
|
public static void delTaskRecord(String filePath, int type, boolean removeFile, |
||||||
|
boolean removeEntity) { |
||||||
|
if (TextUtils.isEmpty(filePath)) { |
||||||
|
throw new NullPointerException("删除记录失败,文件路径为空"); |
||||||
|
} |
||||||
|
if (type != RecordHandler.TYPE_DOWNLOAD && type != RecordHandler.TYPE_UPLOAD) { |
||||||
|
throw new IllegalArgumentException("任务记录类型错误"); |
||||||
|
} |
||||||
|
|
||||||
|
AbsEntity entity; |
||||||
|
if (type == RecordHandler.TYPE_DOWNLOAD) { |
||||||
|
entity = DbEntity.findFirst(DownloadEntity.class, "downloadPath=?", filePath); |
||||||
|
} else { |
||||||
|
entity = DbEntity.findFirst(UploadEntity.class, "filePath=?", filePath); |
||||||
|
} |
||||||
|
File targetFile = new File(filePath); |
||||||
|
TaskRecord record = getTaskRecord(filePath); |
||||||
|
if (entity == null || record == null) { |
||||||
|
if (removeFile) { |
||||||
|
removeTargetFile(targetFile); |
||||||
|
} |
||||||
|
removeRecord(filePath); |
||||||
|
removeEntity(type, filePath); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* 处理任务未完成的情况 |
||||||
|
*/ |
||||||
|
if (!entity.isComplete()) { |
||||||
|
if (record.taskType == TaskRecord.TYPE_M3U8) { // 删除ts分片文件
|
||||||
|
String cacheDir = null; |
||||||
|
if (!targetFile.isDirectory()) { |
||||||
|
cacheDir = targetFile.getParent() + "/." + targetFile.getName(); |
||||||
|
} |
||||||
|
removeTsCache(record, cacheDir); |
||||||
|
} else if (record.isBlock) { // 删除分块文件
|
||||||
|
removeBlockFile(record); |
||||||
|
} |
||||||
|
} else if (removeFile) { // 处理任务完成情况
|
||||||
|
removeTargetFile(targetFile); |
||||||
|
} |
||||||
|
|
||||||
|
// 成功与否都将删除记录
|
||||||
|
removeRecord(filePath); |
||||||
|
|
||||||
|
if (removeEntity) { |
||||||
|
removeEntity(type, filePath); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void removeTargetFile(File targetFile) { |
||||||
|
if (targetFile.exists()) { |
||||||
|
targetFile.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void removeRecord(String filePath) { |
||||||
|
DbEntity.deleteData(ThreadRecord.class, "key=?", filePath); |
||||||
|
DbEntity.deleteData(TaskRecord.class, "filePath=?", filePath); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除实体 |
||||||
|
* |
||||||
|
* @param type {@link RecordHandler#TYPE_DOWNLOAD}下载任务的记录,{@link RecordHandler#TYPE_UPLOAD} |
||||||
|
* 上传任务的记录 |
||||||
|
*/ |
||||||
|
private static void removeEntity(int type, String filePath) { |
||||||
|
if (type == RecordHandler.TYPE_DOWNLOAD) { |
||||||
|
DbEntity.deleteData(DownloadEntity.class, "downloadPath=?", filePath); |
||||||
|
} else { |
||||||
|
DbEntity.deleteData(UploadEntity.class, "filePath=?", filePath); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据文件路径获取任务记录 |
||||||
|
*/ |
||||||
|
private static TaskRecord getTaskRecord(String filePath) { |
||||||
|
List<RecordWrapper> recordWrapper = |
||||||
|
DbEntity.findRelationData(RecordWrapper.class, "filePath=?", filePath); |
||||||
|
if (recordWrapper == null |
||||||
|
|| recordWrapper.isEmpty() |
||||||
|
|| recordWrapper.get(0) == null |
||||||
|
|| recordWrapper.get(0).taskRecord == null) { |
||||||
|
return null; |
||||||
|
} else { |
||||||
|
return recordWrapper.get(0).taskRecord; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除多线程分块下载的分块文件 |
||||||
|
*/ |
||||||
|
private static void removeBlockFile(TaskRecord record) { |
||||||
|
for (int i = 0, len = record.threadNum; i < len; i++) { |
||||||
|
File partFile = new File(String.format(RecordHandler.SUB_PATH, record.filePath, i)); |
||||||
|
if (partFile.exists()) { |
||||||
|
partFile.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除ts文件 |
||||||
|
*/ |
||||||
|
private static void removeTsCache(TaskRecord record, String cacheDir) { |
||||||
|
|
||||||
|
if (!TextUtils.isEmpty(cacheDir)) { |
||||||
|
List<String> partPath = new ArrayList<>(); |
||||||
|
for (ThreadRecord tr : record.threadRecords) { |
||||||
|
partPath.add(M3U8FileLoader.getTsFilePath(cacheDir, tr.threadId)); |
||||||
|
} |
||||||
|
for (String pp : partPath) { |
||||||
|
File f = new File(pp); |
||||||
|
if (f.exists()) { |
||||||
|
f.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
File cDir = new File(cacheDir); |
||||||
|
if (cDir.exists()) { |
||||||
|
cDir.delete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除任务记录,默认删除文件,删除任务实体 |
||||||
|
* |
||||||
|
* @param filePath 文件路径 |
||||||
|
* @param type {@link RecordHandler#TYPE_DOWNLOAD}下载任务的记录,{@link RecordHandler#TYPE_UPLOAD} |
||||||
|
* 上传任务的记录 |
||||||
|
*/ |
||||||
|
public static void delTaskRecord(String filePath, int type) { |
||||||
|
delTaskRecord(filePath, type, false, true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 修改任务路径,修改文件路径和任务记录信息。如果是分块任务,则修改分块文件的路径。 |
||||||
|
* |
||||||
|
* @param oldPath 旧的文件路径 |
||||||
|
* @param newPath 新的文件路径 |
||||||
|
*/ |
||||||
|
public static void modifyTaskRecord(String oldPath, String newPath) { |
||||||
|
if (oldPath.equals(newPath)) { |
||||||
|
ALog.w(TAG, "修改任务记录失败,新文件路径和旧文件路径一致"); |
||||||
|
return; |
||||||
|
} |
||||||
|
TaskRecord record = DbDataHelper.getTaskRecord(oldPath); |
||||||
|
if (record == null) { |
||||||
|
if (new File(oldPath).exists()) { |
||||||
|
ALog.w(TAG, "修改任务记录失败,文件【" + oldPath + "】对应的任务记录不存在"); |
||||||
|
} |
||||||
|
return; |
||||||
|
} |
||||||
|
if (!record.isBlock) { |
||||||
|
File oldFile = new File(oldPath); |
||||||
|
if (oldFile.exists()) { |
||||||
|
oldFile.renameTo(new File(newPath)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
record.filePath = newPath; |
||||||
|
record.update(); |
||||||
|
// 修改线程记录
|
||||||
|
if (record.threadRecords != null && !record.threadRecords.isEmpty()) { |
||||||
|
for (ThreadRecord tr : record.threadRecords) { |
||||||
|
tr.key = newPath; |
||||||
|
File blockFile = new File(String.format(RecordHandler.SUB_PATH, oldPath, tr.threadId)); |
||||||
|
if (blockFile.exists()) { |
||||||
|
blockFile.renameTo(new File(String.format(RecordHandler.SUB_PATH, newPath, tr.threadId))); |
||||||
|
} |
||||||
|
} |
||||||
|
DbEntity.updateManyData(record.threadRecords); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 检查分块任务是否存在 |
||||||
|
* |
||||||
|
* @param filePath 文件保存路径 |
||||||
|
* @return {@code true} 分块文件存在 |
||||||
|
*/ |
||||||
|
public static boolean blockTaskExists(String filePath) { |
||||||
|
return new File(String.format(RecordHandler.SUB_PATH, filePath, 0)).exists(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取分块文件的快大小 |
||||||
|
* |
||||||
|
* @param fileLen 文件总长度 |
||||||
|
* @param blockId 分块id |
||||||
|
* @param blockNum 分块数量 |
||||||
|
* @return 分块长度 |
||||||
|
*/ |
||||||
|
public static long getBlockLen(long fileLen, int blockId, int blockNum) { |
||||||
|
final long averageLen = fileLen / blockNum; |
||||||
|
return blockId == blockNum - 1 ? (fileLen - blockId * averageLen) : averageLen; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue