Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

Commit

Permalink
Optimize the logic for downloading videos in m3u8 format
Browse files Browse the repository at this point in the history
  • Loading branch information
grandiloquent authored and grandiloquent committed Nov 10, 2021
1 parent fc2f284 commit 58ba03a
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 80 deletions.
126 changes: 77 additions & 49 deletions app/src/main/java/euphoria/psycho/tasks/HLSDownloadActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ public class HLSDownloadActivity extends Activity implements HLSDownloadListener
private HLSDownloadAdapter mVideoAdapter;
private Handler mHandler;

public static void createDownloadTask(Activity context) {
String uri = context.getIntent().getDataString();
if (uri == null) return;
ProgressDialog dialog = new ProgressDialog(context);
dialog.setMessage("创建任务...");
dialog.show();
new Thread(() -> {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
try {
HLSDownloadTask task = new HLSDownloadTask(context).build(uri);
if (!task.getVideoFile().exists())
HLSDownloadManager.getInstance(context).submit(task);
} catch (IOException e) {
e.printStackTrace();
}
context.runOnUiThread(dialog::dismiss);
}).start();
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Expand All @@ -54,25 +72,6 @@ protected void onStart() {
.addHLSDownloadRequestListener(mVideoAdapter);
}

public static void createDownloadTask(Activity context) {
String uri = context.getIntent().getDataString();
if (uri == null) return;
ProgressDialog dialog = new ProgressDialog(context);
dialog.setMessage("创建任务...");
dialog.show();
new Thread(() -> {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
try {
HLSDownloadTask task = new HLSDownloadTask(context).build(uri);
if (!task.getVideoFile().exists())
HLSDownloadManager.getInstance(context).submit(task);
} catch (IOException e) {
e.printStackTrace();
}
context.runOnUiThread(dialog::dismiss);
}).start();
}

@Override
protected void onStop() {
HLSDownloadManager.getInstance(this)
Expand Down Expand Up @@ -114,6 +113,14 @@ private static void bindViewHolder(ViewHolder viewHolder, View v) {
viewHolder.button = v.findViewById(R.id.button);
}

private void renderStart(HLSDownloadRequest request, ViewHolder viewHolder) {
mHandler.post(() -> {
viewHolder.layout.setOnClickListener(null);
viewHolder.tag = request.getTask().getUniqueId();
viewHolder.subtitle.setText("开始下载");
});
}

private void renderComplete(Handler handler, ViewHolder viewHolder, File videoFile) {
handler.post(() -> {
viewHolder.button.setImageResource(R.drawable.ic_action_play_arrow);
Expand All @@ -131,10 +138,43 @@ private void renderComplete(Handler handler, ViewHolder viewHolder, File videoFi
});
}

private static void renderStart(Handler handler, ViewHolder viewHolder) {
handler.post(() -> {
viewHolder.subtitle.setText("开始下载");
});
private void renderTask(HLSDownloadRequest hlsDownloadRequest, ViewHolder viewHolder) {
HLSDownloadTask task = hlsDownloadRequest.getTask();
switch (hlsDownloadRequest.getStatus()) {
case HLSDownloadRequest.STATUS_START:
renderStart(hlsDownloadRequest, viewHolder);
break;
case HLSDownloadRequest.STATUS_MERGE_VIDEO:
mHandler.post(() -> {
viewHolder.subtitle.setText(R.string.merge_start);
});
break;
case HLSDownloadRequest.STATUS_MERGE_COMPLETED:
renderComplete(mHandler, viewHolder, task.getVideoFile());
Native.deleteDirectory(task.getDirectory().getAbsolutePath());
break;
case HLSDownloadRequest.STATUS_FILE_CACHED:
case HLSDownloadRequest.STATUS_CONTENT_LENGTH:
int sequence = task.getSequence() + 1;
int total = task.getHLSDownloadTaskSegments().size();
mHandler.post(() -> {
viewHolder.subtitle.setText(String.format("%s/%s", sequence
, total));
viewHolder.progressBar.setProgress((int) ((sequence * 1.0 / total) * 100));
});
// viewHolder.title.setText(task.getUniqueId());
// viewHolder.subtitle.setText(R.string.waiting);
// viewHolder.progressBar.setProgress(0);
// viewHolder.layout.setOnClickListener(null);
// viewHolder.thumbnail.setImageResource(R.drawable.ic_action_file_download_light);
// viewHolder.tag = task.getUniqueId();
break;
case HLSDownloadRequest.STATUS_PAUSED:
mHandler.post(() -> {
viewHolder.subtitle.setText("暂停");
});
break;
}
}

@Override
Expand Down Expand Up @@ -168,43 +208,31 @@ public View getView(int position, View convertView, ViewGroup parent) {
HLSDownloadRequest request = getItem(position);
viewHolder.title.setText(request.getTask().getUniqueId());
viewHolder.subtitle.setText(R.string.waiting);
viewHolder.progressBar.setProgress(0);
viewHolder.layout.setOnClickListener(null);
viewHolder.thumbnail.setImageResource(R.drawable.ic_action_file_download_light);
viewHolder.progressBar.setProgress(0);
viewHolder.tag = request.getTask().getUniqueId();
viewHolder.button.setOnClickListener(view -> {
if (!request.isPaused()) {
request.setPaused(true);
viewHolder.button.setImageResource(R.drawable.ic_action_play_arrow);
} else {
HLSDownloadManager.getInstance(parent.getContext()).finish(request);
HLSDownloadManager.getInstance(parent.getContext())
.submit(request.getTask());
}

});
renderTask(request, viewHolder);
return convertView;
}

@Override
public void onProgress(HLSDownloadRequest hlsDownloadRequest) {
int status = hlsDownloadRequest.getStatus();
HLSDownloadTask task = hlsDownloadRequest.getTask();
String uniqueId = task.getUniqueId();
for (ViewHolder viewHolder : mViewHolders) {
if (uniqueId.equals(viewHolder.tag)) {
switch (status) {
case HLSDownloadRequest.STATUS_START:
renderStart(mHandler, viewHolder);
break;
case HLSDownloadRequest.STATUS_MERGE_VIDEO:
mHandler.post(() -> {
viewHolder.subtitle.setText(R.string.merge_start);
});
break;
case HLSDownloadRequest.STATUS_MERGE_COMPLETED:
renderComplete(mHandler, viewHolder, task.getVideoFile());
Native.deleteDirectory(task.getDirectory().getAbsolutePath());
break;
default:
int sequence = task.getSequence() + 1;
int total = task.getHLSDownloadTaskSegments().size();
mHandler.post(() -> {
viewHolder.subtitle.setText(String.format("%s/%s", sequence
, total));
viewHolder.progressBar.setProgress((int) ((sequence * 1.0 / total) * 100));
});
break;
}
renderTask(hlsDownloadRequest, viewHolder);
return;
}
}
Expand Down
52 changes: 26 additions & 26 deletions app/src/main/java/euphoria/psycho/tasks/HLSDownloadManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ public HLSDownloadManager(Context context) {
).getAbsolutePath());
}

public HLSDownloadManager addHLSDownloadListener(HLSDownloadListener listener) {
synchronized (this) {
mListeners.add(listener);
}
return this;
}

public HLSDownloadManager addHLSDownloadRequestListener(HLSDownloadRequestListener listener) {
synchronized (this) {
mRequestListeners.add(listener);
}
return this;
}

public void finish(HLSDownloadRequest request) {
synchronized (this) {
if (mRequests.contains(request)) {
Expand All @@ -45,11 +59,8 @@ public static HLSDownloadManager getInstance(Context context) {
return sManager;
}

public HLSDownloadManager addHLSDownloadListener(HLSDownloadListener listener) {
synchronized (this) {
mListeners.add(listener);
}
return this;
public List<HLSDownloadRequest> getRequests() {
return mRequests;
}

public HLSDownloadManager removeHLSDownloadListener(HLSDownloadListener listener) {
Expand All @@ -59,18 +70,23 @@ public HLSDownloadManager removeHLSDownloadListener(HLSDownloadListener listener
return this;
}

public HLSDownloadManager addHLSDownloadRequestListener(HLSDownloadRequestListener listener) {
public HLSDownloadManager removeHLSDownloadRequestListener(HLSDownloadRequestListener listener) {
synchronized (this) {
mRequestListeners.add(listener);
mRequestListeners.remove(listener);
}
return this;
}

public HLSDownloadManager removeHLSDownloadRequestListener(HLSDownloadRequestListener listener) {
public void submit(HLSDownloadTask task) {
synchronized (this) {
mRequestListeners.remove(listener);
if (mRequests.stream().anyMatch(m -> m.getTask().getUniqueId().equals(task.getUniqueId()))) {
return;
}
HLSDownloadRequest request = new HLSDownloadRequest(task, this);
mRequests.add(request);
mExecutor.submit(request);
mListeners.forEach(r -> r.onSubmit(request));
}
return this;
}

@Override
Expand All @@ -93,20 +109,4 @@ public void onProgress(HLSDownloadRequest hlsDownloadRequest) {
break;
}
}

public void submit(HLSDownloadTask task) {
synchronized (this) {
if (mRequests.stream().anyMatch(m -> m.getTask().getUniqueId().equals(task.getUniqueId()))) {
return;
}
HLSDownloadRequest request = new HLSDownloadRequest(task, this);
mRequests.add(request);
mExecutor.submit(request);
mListeners.forEach(r -> r.onSubmit(request));
}
}

public List<HLSDownloadRequest> getRequests() {
return mRequests;
}
}
13 changes: 8 additions & 5 deletions app/src/main/java/euphoria/psycho/tasks/HLSDownloadRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,23 @@

public class HLSDownloadRequest implements Runnable {

public static final int STATUS_CONTENT_LENGTH = 2;
public static final int STATUS_ERROR = -2;
public static final int STATUS_ERROR_IO_INPUT = -3;
public static final int STATUS_ERROR_IO_OUTPUT = -4;
public static final int STATUS_MERGE_FAILED = -5;
public static final int STATUS_FATAL_ERROR = -1;
public static final int STATUS_FILE_CACHED = 1;
public static final int STATUS_CONTENT_LENGTH = 2;
public static final int STATUS_PAUSED = 3;
public static final int STATUS_MERGE_VIDEO = 4;
public static final int STATUS_MERGE_COMPLETED = 5;
public static final int STATUS_MERGE_FAILED = -5;
public static final int STATUS_MERGE_VIDEO = 4;
public static final int STATUS_PAUSED = 3;
public static final int STATUS_START = 6;

private final String mBaseUri;
private final HLSDownloadRequestListener mListener;
private final HLSDownloadTask mTask;
private volatile boolean mPaused;
private int mStatus;

public HLSDownloadRequest(HLSDownloadTask task, HLSDownloadRequestListener listener) {
mTask = task;
mListener = listener;
Expand All @@ -49,6 +48,10 @@ public HLSDownloadTask getTask() {
return mTask;
}

public boolean isPaused() {
return mPaused;
}

public void setPaused(boolean paused) {
mPaused = paused;
}
Expand Down

0 comments on commit 58ba03a

Please sign in to comment.