hls 直播下载实现
This commit is contained in:
@@ -47,7 +47,8 @@
|
||||
android:screenOrientation="landscape"
|
||||
android:theme="@style/FullScreen"
|
||||
android:windowSoftInputMode="stateHidden|adjustResize"/>
|
||||
<activity android:name=".core.download.m3u8.M3U8DownloadActivity"/>
|
||||
<activity android:name=".core.download.m3u8.M3U8VodDownloadActivity"/>
|
||||
<activity android:name=".core.download.m3u8.M3U8LiveDownloadActivity"/>
|
||||
|
||||
<service android:name=".core.download.service_download.DownloadService"/>
|
||||
|
||||
|
||||
@@ -36,7 +36,8 @@ import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.base.adapter.AbsHolder;
|
||||
import com.arialyy.simple.base.adapter.AbsRVAdapter;
|
||||
import com.arialyy.simple.base.adapter.RvItemClickSupport;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8DownloadActivity;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8LiveDownloadActivity;
|
||||
import com.arialyy.simple.core.download.m3u8.M3U8VodDownloadActivity;
|
||||
import com.arialyy.simple.databinding.ActivityMainBinding;
|
||||
import com.arialyy.simple.core.download.DownloadActivity;
|
||||
import com.arialyy.simple.core.download.FtpDownloadActivity;
|
||||
@@ -109,7 +110,11 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
|
||||
break;
|
||||
case 6:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
M3U8DownloadActivity.class);
|
||||
M3U8VodDownloadActivity.class);
|
||||
break;
|
||||
case 7:
|
||||
module.startNextActivity(MainActivity.this, data.get(position),
|
||||
M3U8LiveDownloadActivity.class);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* 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.simple.core.download.m3u8;
|
||||
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import com.arialyy.annotations.Download;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadTarget;
|
||||
import com.arialyy.aria.core.download.DownloadTask;
|
||||
import com.arialyy.aria.core.download.m3u8.ILiveTsUrlConverter;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.common.ModifyPathDialog;
|
||||
import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivityM3u8LiveBinding;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBinding> {
|
||||
|
||||
private String mUrl;
|
||||
private String mFilePath;
|
||||
private M3U8LiveModule mModule;
|
||||
private DownloadTarget mTarget;
|
||||
|
||||
@Override
|
||||
protected void init(Bundle savedInstanceState) {
|
||||
super.init(savedInstanceState);
|
||||
setTitle(getString(R.string.m3u8_live));
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(M3U8LiveModule.class);
|
||||
mModule.getHttpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTarget = Aria.download(M3U8LiveDownloadActivity.this).load(entity.getUrl());
|
||||
getBinding().setStateStr(getString(R.string.start));
|
||||
getBinding().setUrl(entity.getUrl());
|
||||
getBinding().setFilePath(entity.getFilePath());
|
||||
mUrl = entity.getUrl();
|
||||
mFilePath = entity.getFilePath();
|
||||
}
|
||||
});
|
||||
getBinding().setViewModel(this);
|
||||
}
|
||||
|
||||
public void chooseUrl() {
|
||||
ModifyUrlDialog dialog =
|
||||
new ModifyUrlDialog(this, getString(R.string.modify_url_dialog_title), mUrl);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyUrlDialog");
|
||||
}
|
||||
|
||||
public void chooseFilePath() {
|
||||
ModifyPathDialog dialog =
|
||||
new ModifyPathDialog(this, getString(R.string.modify_file_path), mFilePath);
|
||||
dialog.show(getSupportFragmentManager(), "ModifyPathDialog");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_single_task_activity, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
int speed = -1;
|
||||
String msg = "";
|
||||
switch (item.getItemId()) {
|
||||
case R.id.help:
|
||||
msg = "一些小知识点:\n"
|
||||
+ "1、你可以在注解中增加链接,用于指定被注解的方法只能被特定的下载任务回调,以防止progress乱跳\n"
|
||||
+ "2、当遇到网络慢的情况时,你可以先使用onPre()更新UI界面,待连接成功时,再在onTaskPre()获取完整的task数据,然后给UI界面设置正确的数据\n"
|
||||
+ "3、你可以在界面初始化时通过Aria.download(this).load(URL).getPercent()等方法快速获取相关任务的一些数据";
|
||||
showMsgDialog("tip", msg);
|
||||
break;
|
||||
case R.id.speed_0:
|
||||
speed = 0;
|
||||
break;
|
||||
case R.id.speed_128:
|
||||
speed = 128;
|
||||
break;
|
||||
case R.id.speed_256:
|
||||
speed = 256;
|
||||
break;
|
||||
case R.id.speed_512:
|
||||
speed = 512;
|
||||
break;
|
||||
case R.id.speed_1m:
|
||||
speed = 1024;
|
||||
break;
|
||||
}
|
||||
if (speed > -1) {
|
||||
msg = item.getTitle().toString();
|
||||
Aria.download(this).setMaxSpeed(speed);
|
||||
T.showShort(this, msg);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Download.onWait
|
||||
void onWait(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Log.d(TAG, "wait ==> " + task.getDownloadEntity().getFileName());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onPre
|
||||
protected void onPre(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStart
|
||||
void taskStart(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setFileSize(task.getConvertFileSize());
|
||||
ALog.d(TAG, "isComplete = " + task.isComplete() + ", state = " + task.getState());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskRunning
|
||||
protected void running(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
ALog.d(TAG, "isRunning");
|
||||
getBinding().setProgress(task.getPercent());
|
||||
getBinding().setSpeed(task.getConvertSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskResume
|
||||
void taskResume(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setStateStr(getString(R.string.stop));
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskStop
|
||||
void taskStop(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setStateStr(getString(R.string.resume));
|
||||
getBinding().setSpeed("");
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskCancel
|
||||
void taskCancel(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setProgress(0);
|
||||
getBinding().setStateStr(getString(R.string.start));
|
||||
getBinding().setSpeed("");
|
||||
Log.d(TAG, "cancel");
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(M3U8LiveDownloadActivity.this, getString(R.string.download_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
getBinding().setStateStr(getString(R.string.start));
|
||||
}
|
||||
}
|
||||
|
||||
@Download.onTaskComplete
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setProgress(100);
|
||||
Toast.makeText(M3U8LiveDownloadActivity.this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
getBinding().setStateStr(getString(R.string.re_start));
|
||||
getBinding().setSpeed("");
|
||||
ALog.d(TAG, "md5: " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_m3u8_live;
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.start:
|
||||
ALog.d(TAG, "isRunning = " + mTarget.isRunning());
|
||||
if (mTarget.isRunning()) {
|
||||
Aria.download(this).load(mUrl).stop();
|
||||
} else {
|
||||
startD();
|
||||
}
|
||||
break;
|
||||
case R.id.cancel:
|
||||
Aria.download(this).load(mUrl).cancel(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void startD() {
|
||||
Aria.download(M3U8LiveDownloadActivity.this)
|
||||
.load(mUrl)
|
||||
.useServerFileName(true)
|
||||
.setFilePath(mFilePath, true)
|
||||
.asM3U8()
|
||||
//.setBandWidthUrlConverter(new IBandWidthUrlConverter() {
|
||||
// @Override public String convert(String bandWidthUrl) {
|
||||
// int index = mUrl.lastIndexOf("/");
|
||||
// return mUrl.substring(0, index + 1) + bandWidthUrl;
|
||||
// }
|
||||
//})
|
||||
.asLive()
|
||||
.setLiveTsUrlConvert(new ILiveTsUrlConverter() {
|
||||
@Override public String convert(String m3u8Url, String tsUrl) {
|
||||
int index = m3u8Url.lastIndexOf("/");
|
||||
String parentUrl = m3u8Url.substring(0, index + 1);
|
||||
return parentUrl + tsUrl;
|
||||
}
|
||||
})
|
||||
//.setLiveTsUrlConvert(new IVodTsUrlConverter() {
|
||||
// @Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
|
||||
// int index = m3u8Url.lastIndexOf("/");
|
||||
// String parentUrl = m3u8Url.substring(0, index + 1);
|
||||
// List<String> newUrls = new ArrayList<>();
|
||||
// for (String url : tsUrls) {
|
||||
// newUrls.add(parentUrl + url);
|
||||
// }
|
||||
//
|
||||
// return newUrls;
|
||||
// }
|
||||
//})
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
mModule.uploadUrl(this, String.valueOf(data));
|
||||
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
|
||||
mModule.updateFilePath(this, String.valueOf(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.simple.core.download.m3u8;
|
||||
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import com.arialyy.aria.core.Aria;
|
||||
import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8LiveModule extends BaseViewModule {
|
||||
private final String M3U8_LIVE_URL_KEY = "M3U8_LIVE_URL_KEY";
|
||||
private final String M3U8_LIVE_PATH_KEY = "M3U8_LIVE_PATH_KEY";
|
||||
// 多码率地址:
|
||||
private final String defUrl = "http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8";
|
||||
private final String filePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
+ "/live.ts";
|
||||
|
||||
private MutableLiveData<DownloadEntity> liveData = new MutableLiveData<>();
|
||||
private DownloadEntity singDownloadInfo;
|
||||
|
||||
/**
|
||||
* 单任务下载的信息
|
||||
*/
|
||||
LiveData<DownloadEntity> getHttpDownloadInfo(Context context) {
|
||||
String url = AppUtil.getConfigValue(context, M3U8_LIVE_URL_KEY, defUrl);
|
||||
String filePath = AppUtil.getConfigValue(context, M3U8_LIVE_PATH_KEY, this.filePath);
|
||||
|
||||
singDownloadInfo = Aria.download(context).getDownloadEntity(url);
|
||||
if (singDownloadInfo == null) {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
File temp = new File(this.filePath);
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_PATH_KEY, singDownloadInfo.getDownloadPath());
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
|
||||
return liveData;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件保存路径
|
||||
*
|
||||
* @param filePath 文件保存路径
|
||||
*/
|
||||
void updateFilePath(Context context, String filePath) {
|
||||
if (TextUtils.isEmpty(filePath)) {
|
||||
ALog.e(TAG, "文件保存路径为空");
|
||||
return;
|
||||
}
|
||||
File temp = new File(filePath);
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_PATH_KEY, filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新url
|
||||
*/
|
||||
void uploadUrl(Context context, String url) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
ALog.e(TAG, "下载地址为空");
|
||||
return;
|
||||
}
|
||||
AppUtil.setConfigValue(context, M3U8_LIVE_URL_KEY, url);
|
||||
singDownloadInfo.setUrl(url);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package com.arialyy.simple.core.download.m3u8;
|
||||
|
||||
import android.arch.lifecycle.Observer;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
@@ -32,9 +31,8 @@ import com.arialyy.aria.core.download.DownloadEntity;
|
||||
import com.arialyy.aria.core.download.DownloadTarget;
|
||||
import com.arialyy.aria.core.download.DownloadTask;
|
||||
import com.arialyy.aria.core.download.m3u8.IBandWidthUrlConverter;
|
||||
import com.arialyy.aria.core.download.m3u8.ITsUrlConverter;
|
||||
import com.arialyy.aria.core.download.m3u8.IVodTsUrlConverter;
|
||||
import com.arialyy.aria.core.inf.IEntity;
|
||||
import com.arialyy.aria.core.inf.IHttpFileLenAdapter;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.frame.util.show.T;
|
||||
@@ -42,17 +40,16 @@ import com.arialyy.simple.R;
|
||||
import com.arialyy.simple.base.BaseActivity;
|
||||
import com.arialyy.simple.common.ModifyPathDialog;
|
||||
import com.arialyy.simple.common.ModifyUrlDialog;
|
||||
import com.arialyy.simple.databinding.ActivityM3u8Binding;
|
||||
import com.arialyy.simple.databinding.ActivityM3u8VodBinding;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding> {
|
||||
|
||||
private String mUrl;
|
||||
private String mFilePath;
|
||||
private M3U8Module mModule;
|
||||
private M3U8VodModule mModule;
|
||||
private DownloadTarget mTarget;
|
||||
|
||||
@Override
|
||||
@@ -60,14 +57,14 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
super.init(savedInstanceState);
|
||||
setTitle(getString(R.string.m3u8_file));
|
||||
Aria.download(this).register();
|
||||
mModule = ViewModelProviders.of(this).get(M3U8Module.class);
|
||||
mModule = ViewModelProviders.of(this).get(M3U8VodModule.class);
|
||||
mModule.getHttpDownloadInfo(this).observe(this, new Observer<DownloadEntity>() {
|
||||
|
||||
@Override public void onChanged(@Nullable DownloadEntity entity) {
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
mTarget = Aria.download(M3U8DownloadActivity.this).load(entity.getUrl());
|
||||
mTarget = Aria.download(M3U8VodDownloadActivity.this).load(entity.getUrl());
|
||||
if (mTarget.getTaskState() == IEntity.STATE_STOP) {
|
||||
getBinding().setStateStr(getString(R.string.resume));
|
||||
} else if (mTarget.isRunning()) {
|
||||
@@ -200,7 +197,7 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
@Download.onTaskFail
|
||||
void taskFail(DownloadTask task, Exception e) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
Toast.makeText(M3U8DownloadActivity.this, getString(R.string.download_fail),
|
||||
Toast.makeText(M3U8VodDownloadActivity.this, getString(R.string.download_fail),
|
||||
Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
getBinding().setStateStr(getString(R.string.start));
|
||||
@@ -211,7 +208,7 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
void taskComplete(DownloadTask task) {
|
||||
if (task.getKey().equals(mUrl)) {
|
||||
getBinding().setProgress(100);
|
||||
Toast.makeText(M3U8DownloadActivity.this, getString(R.string.download_success),
|
||||
Toast.makeText(M3U8VodDownloadActivity.this, getString(R.string.download_success),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
getBinding().setStateStr(getString(R.string.re_start));
|
||||
getBinding().setSpeed("");
|
||||
@@ -221,7 +218,7 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
|
||||
@Override
|
||||
protected int setLayoutId() {
|
||||
return R.layout.activity_m3u8;
|
||||
return R.layout.activity_m3u8_vod;
|
||||
}
|
||||
|
||||
public void onClick(View view) {
|
||||
@@ -241,7 +238,7 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
}
|
||||
|
||||
private void startD() {
|
||||
Aria.download(M3U8DownloadActivity.this)
|
||||
Aria.download(M3U8VodDownloadActivity.this)
|
||||
.load(mUrl)
|
||||
.useServerFileName(true)
|
||||
.setFilePath(mFilePath, true)
|
||||
@@ -252,7 +249,7 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
return mUrl.substring(0, index + 1) + bandWidthUrl;
|
||||
}
|
||||
})
|
||||
.setTsUrlConvert(new ITsUrlConverter() {
|
||||
.setTsUrlConvert(new IVodTsUrlConverter() {
|
||||
@Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
|
||||
int index = m3u8Url.lastIndexOf("/");
|
||||
String parentUrl = m3u8Url.substring(0, index + 1);
|
||||
@@ -267,12 +264,6 @@ public class M3U8DownloadActivity extends BaseActivity<ActivityM3u8Binding> {
|
||||
.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
//Aria.download(this).unRegister();
|
||||
}
|
||||
|
||||
@Override protected void dataCallback(int result, Object data) {
|
||||
super.dataCallback(result, data);
|
||||
if (result == ModifyUrlDialog.MODIFY_URL_DIALOG_RESULT) {
|
||||
@@ -28,13 +28,13 @@ import com.arialyy.frame.base.BaseViewModule;
|
||||
import com.arialyy.simple.util.AppUtil;
|
||||
import java.io.File;
|
||||
|
||||
public class M3U8Module extends BaseViewModule {
|
||||
public class M3U8VodModule extends BaseViewModule {
|
||||
private final String M3U8_URL_KEY = "M3U8_URL_KEY";
|
||||
private final String M3U8_PATH_KEY = "M3U8_PATH_KEY";
|
||||
// m3u8测试集合:http://www.voidcn.com/article/p-snaliarm-ct.html
|
||||
//private final String defUrl = "https://www.gaoya123.cn/2019/1557993797897.m3u8";
|
||||
// 多码率地址:
|
||||
private final String defUrl = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
|
||||
private final String defUrl = "http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8";
|
||||
private final String filePath =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath()
|
||||
+ "/1557993797897.ts";
|
||||
@@ -54,10 +54,10 @@ public class M3U8Module extends BaseViewModule {
|
||||
singDownloadInfo = new DownloadEntity();
|
||||
singDownloadInfo.setUrl(url);
|
||||
File temp = new File(this.filePath);
|
||||
singDownloadInfo.setDownloadPath(filePath);
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
} else {
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, singDownloadInfo.getDownloadPath());
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, singDownloadInfo.getFilePath());
|
||||
AppUtil.setConfigValue(context, M3U8_URL_KEY, singDownloadInfo.getUrl());
|
||||
}
|
||||
liveData.postValue(singDownloadInfo);
|
||||
@@ -78,7 +78,7 @@ public class M3U8Module extends BaseViewModule {
|
||||
File temp = new File(filePath);
|
||||
AppUtil.setConfigValue(context, M3U8_PATH_KEY, filePath);
|
||||
singDownloadInfo.setFileName(temp.getName());
|
||||
singDownloadInfo.setDownloadPath(filePath);
|
||||
singDownloadInfo.setFilePath(filePath);
|
||||
liveData.postValue(singDownloadInfo);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,8 @@ public class CommonModule extends BaseViewModule {
|
||||
R.drawable.ic_ftp,
|
||||
R.drawable.ic_ftp_dir,
|
||||
R.drawable.ic_ftp,
|
||||
R.drawable.ic_ts
|
||||
R.drawable.ic_ts,
|
||||
R.drawable.ic_live
|
||||
};
|
||||
int i = 0;
|
||||
for (String title : titles) {
|
||||
|
||||
12
app/src/main/res/drawable/ic_live.xml
Normal file
12
app/src/main/res/drawable/ic_live.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="1024"
|
||||
android:viewportWidth="1024"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@color/icon_color"
|
||||
android:pathData="M690.42,297.75c3.04,0 5.23,0 7.42,0 24.08,0 48.29,-0.73 72.37,0.36 34.79,1.58 65.19,13.99 88.18,41.11 14.6,17.15 22.01,37.46 22.01,59.84 0.24,123.21 0.49,246.54 -0.12,369.75 -0.12,35.15 -12.53,66.29 -39.53,90.25 -17.27,15.45 -37.95,22.99 -61.06,23.6 -16.18,0.36 -32.48,0.12 -48.65,0.12 -155.08,0 -310.16,-0.49 -465.23,0.24 -59.11,0.24 -110.8,-45 -120.41,-99.61 -1.34,-7.78 -1.7,-15.69 -1.7,-23.6 -0.12,-117.37 0.61,-234.75 -0.36,-352.12 -0.49,-59.36 38.8,-95.11 84.65,-105.82 11.92,-2.8 24.45,-3.65 36.73,-3.89 24.08,-0.61 48.17,-0.12 73.34,-0.12 -1.34,-2.55 -2.19,-4.5 -3.16,-6.32 -9.37,-16.54 -18.85,-33.08 -28.1,-49.75 -6.57,-11.92 -4.14,-25.06 5.84,-33.57 6.81,-5.84 13.26,-7.3 20.56,-2.07 7.42,5.35 14.47,11.8 19.95,19.22 14.96,20.43 29.68,41.11 43.06,62.64 5.23,8.39 10.58,10.1 19.58,10.1 67.87,-0.36 135.86,-0.24 203.73,-0.12 4.87,0 7.54,-1.34 9.85,-5.72 12.65,-23.84 25.54,-47.44 38.56,-71.03 5.96,-10.83 15.57,-15.69 27.85,-14.47 11.07,0.97 18.73,7.05 23.11,17.27 3.53,8.15 2.55,16.3 -1.58,23.96 -7.78,14.35 -15.69,28.83 -23.6,43.18C692.61,293.01 691.76,294.95 690.42,297.75zM518.56,834.87c84.9,0 169.79,-0.12 254.81,0.12 23.84,0.12 39.89,-10.95 50.48,-31.38 7.05,-13.74 9,-28.46 9,-43.54 0,-87.82 0,-175.51 0,-263.33 0,-30.65 -0.12,-61.18 0,-91.83 0.12,-23.6 -11.07,-40.02 -31.62,-50.48 -13.26,-6.81 -27.61,-8.88 -42.33,-8.88 -164.56,0 -329.13,0 -493.69,0.12 -7.66,0 -15.45,0.73 -22.87,2.19 -33.93,6.69 -50.96,27.61 -50.96,62.03 0,116.76 0.61,233.53 -0.24,350.29 -0.24,40.38 36.37,75.9 75.29,75.29C350.35,834.01 434.52,834.87 518.56,834.87z"/>
|
||||
<path
|
||||
android:fillColor="@color/icon_color"
|
||||
android:pathData="M446.31,601.95c0,-28.58 0,-57.17 0,-85.75 0,-15.33 8.88,-20.68 22.01,-13.26 50.6,28.1 101.2,56.31 151.67,84.53 1.58,0.85 3.16,1.7 4.74,2.68 10.22,6.32 10.1,18.37 -0.36,24.45 -11.31,6.69 -22.87,13.01 -34.42,19.46 -40.62,22.62 -81.37,45.25 -121.99,67.87 -13.01,7.18 -21.77,1.95 -21.77,-13.01C446.31,659.84 446.31,630.89 446.31,601.95z"/>
|
||||
</vector>
|
||||
112
app/src/main/res/layout/activity_m3u8_live.xml
Normal file
112
app/src/main/res/layout/activity_m3u8_live.xml
Normal file
@@ -0,0 +1,112 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:bind="http://schemas.android.com/apk/res-auto"
|
||||
>
|
||||
|
||||
<data>
|
||||
<variable
|
||||
name="fileSize"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="speed"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="progress"
|
||||
type="int"
|
||||
/>
|
||||
<variable
|
||||
name="stateStr"
|
||||
type="String"
|
||||
/>
|
||||
|
||||
<variable
|
||||
name="url"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="filePath"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="hint"
|
||||
type="String"
|
||||
/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.arialyy.simple.core.download.m3u8.M3U8LiveDownloadActivity"
|
||||
/>
|
||||
</data>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".core.download.SingleTaskActivity"
|
||||
>
|
||||
|
||||
<include layout="@layout/layout_bar"/>
|
||||
|
||||
<com.arialyy.simple.widget.SvgTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
bind:iconClickListener="@{() -> viewModel.chooseUrl()}"
|
||||
bind:svg_text_view_icon="@drawable/ic_modify"
|
||||
bind:text="@{@string/url(url)}"
|
||||
/>
|
||||
|
||||
<com.arialyy.simple.widget.SvgTextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
bind:iconClickListener="@{() -> viewModel.chooseFilePath()}"
|
||||
bind:svg_text_view_icon="@drawable/ic_choose_file"
|
||||
bind:text="@{@string/file_path(filePath)}"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/hint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{hint}"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
<TextView
|
||||
android:id="@+id/speed"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_weight="1"
|
||||
android:text="@{speed}"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/start"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:onClick="onClick"
|
||||
android:text="@{stateStr ?? @string/start}"
|
||||
style="?buttonBarButtonStyle"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
||||
@@ -31,7 +31,7 @@
|
||||
/>
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.arialyy.simple.core.download.m3u8.M3U8DownloadActivity"
|
||||
type="com.arialyy.simple.core.download.m3u8.M3U8VodDownloadActivity"
|
||||
/>
|
||||
</data>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<string name="name">NAME: </string>
|
||||
<string name="modify_file_path">修改文件路径</string>
|
||||
<string name="m3u8_file">M3U8点播文件下载</string>
|
||||
<string name="m3u8_live">M3U8直播文件下载</string>
|
||||
|
||||
|
||||
<string name="error_file_name_null">文件名为空</string>
|
||||
@@ -37,6 +38,7 @@
|
||||
<item>FTP 文件夹下载</item>
|
||||
<item>FTP 文件上传</item>
|
||||
<item>M3U8 点播文件下载</item>
|
||||
<item>M3U8 直播文件下载</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="main_items_desc">
|
||||
@@ -47,6 +49,7 @@
|
||||
<item>下载服务器上的某个FTP文件夹</item>
|
||||
<item>上传单个文件到服务器</item>
|
||||
<item>下载M3U8点播文件</item>
|
||||
<item>下载M3U8直播文件</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="download_items">
|
||||
|
||||
Reference in New Issue
Block a user