增加获取执行中的任务api
增加获取剩余时间的api 修复重构loader导致的m3u8问题
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.m3u8.live;
|
||||
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
import com.arialyy.aria.core.common.RecordHandler;
|
||||
import com.arialyy.aria.core.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.m3u8.M3U8TaskOption;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 直播m3u8文件处理器
|
||||
*/
|
||||
final class LiveRecordHandler extends RecordHandler {
|
||||
private M3U8TaskOption mOption;
|
||||
|
||||
LiveRecordHandler(AbsTaskWrapper wrapper) {
|
||||
super(wrapper);
|
||||
}
|
||||
|
||||
public void setOption(M3U8TaskOption option) {
|
||||
mOption = option;
|
||||
}
|
||||
|
||||
@Override public void onPre() {
|
||||
super.onPre();
|
||||
RecordUtil.delTaskRecord(getEntity().getFilePath(), IRecordHandler.TYPE_DOWNLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 直播文件不需要处理任务记录
|
||||
*/
|
||||
@Deprecated
|
||||
@Override public void handlerTaskRecord(TaskRecord record) {
|
||||
if (record.threadRecords == null) {
|
||||
record.threadRecords = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated 交由{@link #createThreadRecord(TaskRecord, String, int)} 处理
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public ThreadRecord createThreadRecord(TaskRecord record, int threadId, long startL, long endL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建线程记录
|
||||
*
|
||||
* @param taskRecord 任务记录
|
||||
* @param tsUrl ts下载地址
|
||||
* @param threadId 线程id
|
||||
*/
|
||||
ThreadRecord createThreadRecord(TaskRecord taskRecord, String tsUrl, int threadId) {
|
||||
ThreadRecord tr = new ThreadRecord();
|
||||
tr.taskKey = taskRecord.filePath;
|
||||
tr.isComplete = false;
|
||||
tr.tsUrl = tsUrl;
|
||||
tr.threadType = getEntity().getTaskType();
|
||||
tr.threadId = threadId;
|
||||
tr.startLocation = 0;
|
||||
taskRecord.threadRecords.add(tr);
|
||||
return tr;
|
||||
}
|
||||
|
||||
@Override public TaskRecord createTaskRecord(int threadNum) {
|
||||
TaskRecord record = new TaskRecord();
|
||||
record.fileName = getEntity().getFileName();
|
||||
record.filePath = getEntity().getFilePath();
|
||||
record.threadRecords = new ArrayList<>();
|
||||
record.threadNum = threadNum;
|
||||
record.isBlock = true;
|
||||
record.taskType = getEntity().getTaskType();
|
||||
record.bandWidth = mOption.getBandWidth();
|
||||
return record;
|
||||
}
|
||||
|
||||
@Override public int initTaskThreadNum() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.m3u8.live;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -80,7 +81,11 @@ final class LiveStateManager implements IThreadStateManager {
|
||||
msg.getData().getString(ISchedulers.DATA_M3U8_PEER_PATH), peerIndex);
|
||||
break;
|
||||
case STATE_RUNNING:
|
||||
mProgress += (long) msg.obj;
|
||||
Bundle b = msg.getData();
|
||||
if (b != null) {
|
||||
long len = b.getLong(IThreadStateManager.DATA_ADD_LEN, 0);
|
||||
mProgress += len;
|
||||
}
|
||||
break;
|
||||
case STATE_FAIL:
|
||||
mLoader.notifyLock(false, peerIndex);
|
||||
|
||||
@@ -68,11 +68,9 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
private Condition mCondition = LOCK.newCondition();
|
||||
private LinkedBlockingQueue<ExtInfo> mPeerQueue = new LinkedBlockingQueue<>();
|
||||
private ExtInfo mCurExtInfo;
|
||||
private LiveStateManager mManager;
|
||||
private M3U8InfoTask mInfoTask;
|
||||
private ScheduledThreadPoolExecutor mTimer;
|
||||
private List<String> mPeerUrls = new ArrayList<>();
|
||||
private Looper mLooper;
|
||||
|
||||
M3U8LiveLoader(DTaskWrapper wrapper, M3U8Listener listener) {
|
||||
super(wrapper, listener);
|
||||
@@ -94,8 +92,22 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
if (isBreak()) {
|
||||
return;
|
||||
}
|
||||
mLooper = looper;
|
||||
|
||||
// 处理记录
|
||||
getRecordHandler().setOption(mM3U8Option);
|
||||
mRecord = getRecordHandler().getRecord(0);
|
||||
|
||||
// 初始化状态管理器
|
||||
getStateManager().setLooper(mRecord, looper);
|
||||
getStateManager().setLoader(this);
|
||||
mStateHandler = new Handler(looper, getStateManager().getHandlerCallback());
|
||||
|
||||
// 循环获取直播文件列表
|
||||
startLoaderLiveInfo();
|
||||
|
||||
// 启动定时器
|
||||
startTimer();
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
String cacheDir = getCacheDir();
|
||||
@@ -127,6 +139,14 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override protected LiveStateManager getStateManager() {
|
||||
return (LiveStateManager) super.getStateManager();
|
||||
}
|
||||
|
||||
private LiveRecordHandler getRecordHandler() {
|
||||
return (LiveRecordHandler) mRecordHandler;
|
||||
}
|
||||
|
||||
@Override public long getFileSize() {
|
||||
return mTempFile.length();
|
||||
}
|
||||
@@ -165,20 +185,14 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
* 配置config
|
||||
*/
|
||||
private ThreadTask createThreadTask(String cacheDir, int indexId, String tsUrl) {
|
||||
ThreadRecord record = new ThreadRecord();
|
||||
record.taskKey = mRecord.filePath;
|
||||
record.isComplete = false;
|
||||
record.tsUrl = tsUrl;
|
||||
record.threadType = getEntity().getTaskType();
|
||||
record.threadId = indexId;
|
||||
mRecord.threadRecords.add(record);
|
||||
ThreadRecord tr = getRecordHandler().createThreadRecord(mRecord, tsUrl, indexId);
|
||||
|
||||
SubThreadConfig config = new SubThreadConfig();
|
||||
config.url = tsUrl;
|
||||
config.tempFile = new File(getTsFilePath(cacheDir, indexId));
|
||||
config.isBlock = mRecord.isBlock;
|
||||
config.taskWrapper = mTaskWrapper;
|
||||
config.record = record;
|
||||
config.record = tr;
|
||||
config.stateHandler = mStateHandler;
|
||||
config.peerIndex = indexId;
|
||||
config.threadType = SubThreadConfig.getThreadType(ITaskWrapper.M3U8_LIVE);
|
||||
@@ -219,15 +233,10 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
if (isSuccess) {
|
||||
// 合并成功,删除缓存文件
|
||||
for (String pp : partPath) {
|
||||
File f = new File(pp);
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
FileUtil.deleteFile(pp);
|
||||
}
|
||||
File cDir = new File(cacheDir);
|
||||
if (cDir.exists()) {
|
||||
cDir.delete();
|
||||
}
|
||||
FileUtil.deleteDir(cDir);
|
||||
return true;
|
||||
} else {
|
||||
ALog.e(TAG, "合并失败");
|
||||
@@ -323,10 +332,7 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
* 需要在{@link #addComponent(IRecordHandler)} 后调用
|
||||
*/
|
||||
@Override public void addComponent(IThreadStateManager threadState) {
|
||||
mManager = (LiveStateManager) threadState;
|
||||
mManager.setLooper(mRecordHandler.getRecord(0), mLooper);
|
||||
mManager.setLoader(this);
|
||||
mStateHandler = new Handler(mLooper, mManager.getHandlerCallback());
|
||||
mStateManager = threadState;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,7 +350,7 @@ final class M3U8LiveLoader extends BaseM3U8Loader {
|
||||
if (mInfoTask == null) {
|
||||
throw new NullPointerException(("文件信息组件为空"));
|
||||
}
|
||||
if (mManager == null) {
|
||||
if (mStateManager == null) {
|
||||
throw new NullPointerException("任务状态管理组件为空");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,9 +23,7 @@ import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.http.HttpTaskOption;
|
||||
import com.arialyy.aria.m3u8.M3U8InfoTask;
|
||||
import com.arialyy.aria.m3u8.M3U8Listener;
|
||||
import com.arialyy.aria.m3u8.M3U8RecordHandler;
|
||||
import com.arialyy.aria.m3u8.M3U8TaskOption;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
|
||||
/**
|
||||
* M3U8直播文件下载工具,对于直播来说,需要定时更新m3u8文件
|
||||
@@ -37,7 +35,6 @@ import com.arialyy.aria.util.CommonUtil;
|
||||
* 5、不处理直播切片下载失败的状态
|
||||
*/
|
||||
public class M3U8LiveUtil extends AbsNormalLoaderUtil {
|
||||
private final String TAG = CommonUtil.getClassName(getClass());
|
||||
|
||||
public M3U8LiveUtil(AbsTaskWrapper wrapper, IEventListener listener) {
|
||||
super(wrapper, listener);
|
||||
@@ -57,7 +54,7 @@ public class M3U8LiveUtil extends AbsNormalLoaderUtil {
|
||||
|
||||
@Override public LoaderStructure BuildLoaderStructure() {
|
||||
LoaderStructure structure = new LoaderStructure();
|
||||
structure.addComponent(new M3U8RecordHandler(getTaskWrapper()))
|
||||
structure.addComponent(new LiveRecordHandler(getTaskWrapper()))
|
||||
.addComponent(new M3U8InfoTask(getTaskWrapper()))
|
||||
.addComponent(new LiveStateManager(getTaskWrapper(), getListener()));
|
||||
structure.accept(getLoader());
|
||||
|
||||
@@ -73,7 +73,6 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
private Condition mJumpCondition = JUMP_LOCK.newCondition();
|
||||
private SparseArray<ThreadRecord> mBeforePeer = new SparseArray<>();
|
||||
private SparseArray<ThreadRecord> mAfterPeer = new SparseArray<>();
|
||||
private VodStateManager mManager;
|
||||
private PeerIndexEvent mCurrentEvent;
|
||||
private String mCacheDir;
|
||||
private int aIndex = 0, bIndex = 0;
|
||||
@@ -136,11 +135,6 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onPostPre() {
|
||||
super.onPostPre();
|
||||
initData();
|
||||
}
|
||||
|
||||
@Override public boolean isBreak() {
|
||||
return super.isBreak() || isDestroy;
|
||||
}
|
||||
@@ -154,6 +148,22 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
}
|
||||
|
||||
private void startThreadTask() {
|
||||
// 处理任务记录
|
||||
((VodRecordHandler) mRecordHandler).setOption(mM3U8Option);
|
||||
mRecord = mRecordHandler.getRecord(0);
|
||||
|
||||
// 处理任务管理器
|
||||
mStateHandler = new Handler(mLooper, getStateManager().getHandlerCallback());
|
||||
getStateManager().setVodLoader(this);
|
||||
getStateManager().setLooper(mRecord, mLooper);
|
||||
|
||||
// 初始化ts数据
|
||||
initData();
|
||||
|
||||
// 启动定时器
|
||||
startTimer();
|
||||
|
||||
// 启动线程开始下载ts切片
|
||||
Thread th = new Thread(new Runnable() {
|
||||
@Override public void run() {
|
||||
while (!isBreak()) {
|
||||
@@ -258,7 +268,7 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
mCompleteNum++;
|
||||
}
|
||||
}
|
||||
mManager.updateStateCount();
|
||||
getStateManager().updateStateCount();
|
||||
if (mCompleteNum <= 0) {
|
||||
getListener().onStart(0);
|
||||
} else {
|
||||
@@ -416,7 +426,7 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
String.format("beforeSize = %s, afterSize = %s, mCompleteNum = %s", mBeforePeer.size(),
|
||||
mAfterPeer.size(), mCompleteNum));
|
||||
ALog.i(TAG, String.format("完成处理数据的操作,将优先下载【%s】之后的切片", mCurrentEvent.peerIndex));
|
||||
mManager.updateStateCount();
|
||||
getStateManager().updateStateCount();
|
||||
|
||||
try {
|
||||
JUMP_LOCK.lock();
|
||||
@@ -487,7 +497,6 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
|
||||
@Override public void addComponent(IRecordHandler recordHandler) {
|
||||
mRecordHandler = recordHandler;
|
||||
mRecord = mRecordHandler.getRecord(0);
|
||||
}
|
||||
|
||||
@Override public void addComponent(IInfoTask infoTask) {
|
||||
@@ -543,10 +552,7 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
* 需要在 {@link #addComponent(IRecordHandler)}后调用
|
||||
*/
|
||||
@Override public void addComponent(IThreadStateManager threadState) {
|
||||
mManager = (VodStateManager) threadState;
|
||||
mStateHandler = new Handler(mLooper, mManager.getHandlerCallback());
|
||||
mManager.setVodLoader(this);
|
||||
mManager.setLooper(mRecord, mLooper);
|
||||
mStateManager = threadState;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -557,6 +563,11 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VodStateManager getStateManager() {
|
||||
return (VodStateManager) mStateManager;
|
||||
}
|
||||
|
||||
@Override protected void checkComponent() {
|
||||
if (mRecordHandler == null) {
|
||||
throw new NullPointerException("任务记录组件为空");
|
||||
@@ -564,7 +575,7 @@ final class M3U8VodLoader extends BaseM3U8Loader {
|
||||
if (mInfoTask == null) {
|
||||
throw new NullPointerException(("文件信息组件为空"));
|
||||
}
|
||||
if (mManager == null) {
|
||||
if (getStateManager() == null) {
|
||||
throw new NullPointerException("任务状态管理组件为空");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.arialyy.aria.core.wrapper.AbsTaskWrapper;
|
||||
import com.arialyy.aria.http.HttpTaskOption;
|
||||
import com.arialyy.aria.m3u8.M3U8InfoTask;
|
||||
import com.arialyy.aria.m3u8.M3U8Listener;
|
||||
import com.arialyy.aria.m3u8.M3U8RecordHandler;
|
||||
import com.arialyy.aria.m3u8.M3U8TaskOption;
|
||||
|
||||
/**
|
||||
@@ -54,7 +53,7 @@ public final class M3U8VodUtil extends AbsNormalLoaderUtil {
|
||||
|
||||
@Override public LoaderStructure BuildLoaderStructure() {
|
||||
LoaderStructure structure = new LoaderStructure();
|
||||
structure.addComponent(new M3U8RecordHandler(getTaskWrapper()))
|
||||
structure.addComponent(new VodRecordHandler(getTaskWrapper()))
|
||||
.addComponent(new M3U8InfoTask(getTaskWrapper()))
|
||||
.addComponent(new VodStateManager(getTaskWrapper(), (M3U8Listener) getListener()));
|
||||
structure.accept(getLoader());
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.arialyy.aria.m3u8;
|
||||
package com.arialyy.aria.m3u8.vod;
|
||||
|
||||
import com.arialyy.aria.core.TaskRecord;
|
||||
import com.arialyy.aria.core.ThreadRecord;
|
||||
@@ -21,11 +21,12 @@ import com.arialyy.aria.core.common.RecordHandler;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.M3U8Entity;
|
||||
import com.arialyy.aria.core.loader.IRecordHandler;
|
||||
import com.arialyy.aria.core.wrapper.ITaskWrapper;
|
||||
import com.arialyy.aria.m3u8.BaseM3U8Loader;
|
||||
import com.arialyy.aria.m3u8.M3U8InfoTask;
|
||||
import com.arialyy.aria.m3u8.M3U8TaskOption;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -33,19 +34,15 @@ import java.util.ArrayList;
|
||||
* @Author lyy
|
||||
* @Date 2019-09-24
|
||||
*/
|
||||
public final class M3U8RecordHandler extends RecordHandler {
|
||||
final class VodRecordHandler extends RecordHandler {
|
||||
private M3U8TaskOption mOption;
|
||||
|
||||
public M3U8RecordHandler(DTaskWrapper wrapper) {
|
||||
VodRecordHandler(DTaskWrapper wrapper) {
|
||||
super(wrapper);
|
||||
mOption = (M3U8TaskOption) wrapper.getM3u8Option();
|
||||
}
|
||||
|
||||
@Override public void onPre() {
|
||||
super.onPre();
|
||||
if (getWrapper().getRequestType() == ITaskWrapper.M3U8_LIVE) {
|
||||
RecordUtil.delTaskRecord(getEntity().getFilePath(), IRecordHandler.TYPE_DOWNLOAD);
|
||||
}
|
||||
public void setOption(M3U8TaskOption option) {
|
||||
mOption = option;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,6 @@ public final class VodStateManager implements IThreadStateManager {
|
||||
private int cancelNum = 0; // 已经取消的线程的数
|
||||
private int stopNum = 0; // 已经停止的线程数
|
||||
private int failNum = 0; // 失败的线程数
|
||||
private long percent; //当前总进度,百分比进度
|
||||
private long progress;
|
||||
private TaskRecord taskRecord; // 任务记录
|
||||
private Looper looper;
|
||||
@@ -164,7 +163,11 @@ public final class VodStateManager implements IThreadStateManager {
|
||||
}
|
||||
break;
|
||||
case STATE_RUNNING:
|
||||
progress += (long) msg.obj;
|
||||
Bundle b = msg.getData();
|
||||
if (b != null) {
|
||||
long len = b.getLong(IThreadStateManager.DATA_ADD_LEN, 0);
|
||||
progress += len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
@@ -226,7 +229,6 @@ public final class VodStateManager implements IThreadStateManager {
|
||||
int percent = completeNum * 100 / taskRecord.threadRecords.size();
|
||||
getEntity().setPercent(percent);
|
||||
getEntity().update();
|
||||
this.percent = percent;
|
||||
}
|
||||
|
||||
@Override public boolean isFail() {
|
||||
|
||||
Reference in New Issue
Block a user