修复任务记录删除失败的问题

优化网络连接状态获取的逻辑
修复配置文件的某些配置失效的问题
新增m3u8切片状态注解`@M3U8.onPeerStart`,`@M3U8.onPeerComplete`,`@M3U8.onPeerFail`
新增动态指定m3u8协议视频的下载功能(边下边播)
This commit is contained in:
laoyuyu
2019-07-05 21:20:38 +08:00
parent 060b1f138e
commit b0818537f2
133 changed files with 2492 additions and 1199 deletions

View File

@@ -12,6 +12,7 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar"
tools:ignore="GoogleAppIndexingWarning">
@@ -47,8 +48,8 @@
android:screenOrientation="landscape"
android:theme="@style/FullScreen"
android:windowSoftInputMode="stateHidden|adjustResize"/>
<activity android:name=".core.download.m3u8.M3U8VodDownloadActivity"/>
<activity android:name=".core.download.m3u8.M3U8LiveDownloadActivity"/>
<activity android:name=".core.download.m3u8.M3U8VodDLoadActivity"/>
<activity android:name=".core.download.m3u8.M3U8LiveDLoadActivity"/>
<service android:name=".core.download.service_download.DownloadService"/>

View File

@@ -68,7 +68,7 @@ class KotlinDownloadActivity : BaseActivity<ActivitySingleBinding>() {
}
/**
* 注解方法不能添加internal修饰符否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: index 1 for '$a' not in range (received 0 arguments)错误
* 注解方法不能添加internal修饰符否则会出现e: [kapt] An exception occurred: java.lang.IllegalArgumentException: peerIndex 1 for '$a' not in range (received 0 arguments)错误
*/
@Download.onTaskRunning
fun running(task: DownloadTask) {

View File

@@ -36,8 +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.M3U8LiveDownloadActivity;
import com.arialyy.simple.core.download.m3u8.M3U8VodDownloadActivity;
import com.arialyy.simple.core.download.m3u8.M3U8LiveDLoadActivity;
import com.arialyy.simple.core.download.m3u8.M3U8VodDLoadActivity;
import com.arialyy.simple.databinding.ActivityMainBinding;
import com.arialyy.simple.core.download.DownloadActivity;
import com.arialyy.simple.core.download.FtpDownloadActivity;
@@ -110,11 +110,11 @@ public class MainActivity extends BaseActivity<ActivityMainBinding> {
break;
case 6:
module.startNextActivity(MainActivity.this, data.get(position),
M3U8VodDownloadActivity.class);
M3U8VodDLoadActivity.class);
break;
case 7:
module.startNextActivity(MainActivity.this, data.get(position),
M3U8LiveDownloadActivity.class);
M3U8LiveDLoadActivity.class);
break;
}
}

View File

@@ -17,13 +17,10 @@
package com.arialyy.simple.base;
import android.app.Application;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.os.StrictMode;
import com.arialyy.aria.core.Aria;
import com.arialyy.frame.core.AbsFrame;
import com.arialyy.simple.BuildConfig;
//import com.squareup.leakcanary.LeakCanary;
/**
* Created by Lyy on 2016/9/27.
@@ -38,16 +35,16 @@ public class BaseApplication extends Application {
AbsFrame.init(this);
Aria.init(this);
if (BuildConfig.DEBUG) {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.build());
StrictMode.setThreadPolicy(
new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
//StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
// .detectAll()
// .penaltyLog()
// .build());
//StrictMode.setThreadPolicy(
// new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
//if (LeakCanary.isInAnalyzerProcess(this)) {//1
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
//return;
// //This process is dedicated to LeakCanary for heap analysis.
// //You should not init your app in this process.
// return;
//}
//LeakCanary.install(this);
}

View File

@@ -286,15 +286,6 @@ class KotlinDownloadActivity : BaseActivity<ActivitySingleKotlinBinding>() {
//.addHeader("Cookie", "BAIDUID=648E5FF020CC69E8DD6F492D1068AAA9:FG=1; BIDUPSID=648E5FF020CC69E8DD6F492D1068AAA9; PSTM=1519099573; BD_UPN=12314753; locale=zh; BDSVRTM=0")
.useServerFileName(true)
.setFilePath(mFilePath!!, true)
.setFileLenAdapter(IHttpFileLenAdapter { headers ->
val sLength = headers["Content-Length"]
if (sLength == null || sLength.isEmpty()) {
return@IHttpFileLenAdapter -1
}
val temp = sLength[0]
java.lang.Long.parseLong(temp)
})
.start()
}

View File

@@ -31,6 +31,7 @@ import android.view.View;
import android.widget.Toast;
import com.arialyy.annotations.Download;
import com.arialyy.annotations.M3U8;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;

View File

@@ -41,7 +41,7 @@ import com.arialyy.simple.common.ModifyUrlDialog;
import com.arialyy.simple.databinding.ActivityM3u8LiveBinding;
import java.io.File;
public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBinding> {
public class M3U8LiveDLoadActivity extends BaseActivity<ActivityM3u8LiveBinding> {
private String mUrl;
private String mFilePath;
@@ -60,7 +60,7 @@ public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBindi
if (entity == null) {
return;
}
mTarget = Aria.download(M3U8LiveDownloadActivity.this).load(entity.getUrl());
mTarget = Aria.download(M3U8LiveDLoadActivity.this).load(entity.getUrl());
getBinding().setStateStr(getString(R.string.start));
getBinding().setUrl(entity.getUrl());
getBinding().setFilePath(entity.getFilePath());
@@ -184,7 +184,7 @@ public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBindi
@Download.onTaskFail
void taskFail(DownloadTask task, Exception e) {
if (task.getKey().equals(mUrl)) {
Toast.makeText(M3U8LiveDownloadActivity.this, getString(R.string.download_fail),
Toast.makeText(M3U8LiveDLoadActivity.this, getString(R.string.download_fail),
Toast.LENGTH_SHORT)
.show();
getBinding().setStateStr(getString(R.string.start));
@@ -195,7 +195,7 @@ public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBindi
void taskComplete(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
getBinding().setProgress(100);
Toast.makeText(M3U8LiveDownloadActivity.this, getString(R.string.download_success),
Toast.makeText(M3U8LiveDLoadActivity.this, getString(R.string.download_success),
Toast.LENGTH_SHORT).show();
getBinding().setStateStr(getString(R.string.re_start));
getBinding().setSpeed("");
@@ -225,15 +225,15 @@ public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBindi
}
private void startD() {
Aria.download(M3U8LiveDownloadActivity.this)
Aria.download(M3U8LiveDLoadActivity.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;
// int peerIndex = mUrl.lastIndexOf("/");
// return mUrl.substring(0, peerIndex + 1) + bandWidthUrl;
// }
//})
.asLive()
@@ -246,8 +246,8 @@ public class M3U8LiveDownloadActivity extends BaseActivity<ActivityM3u8LiveBindi
})
//.setLiveTsUrlConvert(new IVodTsUrlConverter() {
// @Override public List<String> convert(String m3u8Url, List<String> tsUrls) {
// int index = m3u8Url.lastIndexOf("/");
// String parentUrl = m3u8Url.substring(0, index + 1);
// int peerIndex = m3u8Url.lastIndexOf("/");
// String parentUrl = m3u8Url.substring(0, peerIndex + 1);
// List<String> newUrls = new ArrayList<>();
// for (String url : tsUrls) {
// newUrls.add(parentUrl + url);

View File

@@ -20,12 +20,14 @@ import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentTransaction;
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.annotations.M3U8;
import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadTarget;
@@ -47,12 +49,13 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding> {
public class M3U8VodDLoadActivity extends BaseActivity<ActivityM3u8VodBinding> {
private String mUrl;
private String mFilePath;
private M3U8VodModule mModule;
private DownloadTarget mTarget;
private VideoPlayerFragment mVideoFragment;
@Override
protected void init(Bundle savedInstanceState) {
@@ -66,7 +69,7 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
if (entity == null) {
return;
}
mTarget = Aria.download(M3U8VodDownloadActivity.this).load(entity.getUrl());
mTarget = Aria.download(M3U8VodDLoadActivity.this).load(entity.getUrl());
if (mTarget.getTaskState() == IEntity.STATE_STOP) {
getBinding().setStateStr(getString(R.string.resume));
} else if (mTarget.isRunning()) {
@@ -81,6 +84,10 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
getBinding().setFilePath(entity.getFilePath());
mUrl = entity.getUrl();
mFilePath = entity.getFilePath();
mVideoFragment = new VideoPlayerFragment(0, entity);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.video_content, mVideoFragment);
ft.commit();
}
});
getBinding().setViewModel(this);
@@ -140,6 +147,22 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
return true;
}
@M3U8.onPeerStart
void onPeerStart(String m3u8Url, String peerPath, int peerIndex) {
//ALog.d(TAG, "peer start, path: " + peerPath + ", index: " + peerIndex);
}
@M3U8.onPeerComplete
void onPeerComplete(String m3u8Url, String peerPath, int peerIndex) {
//ALog.d(TAG, "peer complete, path: " + peerPath + ", index: " + peerIndex);
mVideoFragment.addPlayer(peerIndex, peerPath);
}
@M3U8.onPeerFail
void onPeerFail(String m3u8Url, String peerPath, int peerIndex) {
//ALog.d(TAG, "peer fail, path: " + peerPath + ", index: " + peerIndex);
}
@Download.onWait
void onWait(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
@@ -165,7 +188,7 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
@Download.onTaskRunning
protected void running(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
ALog.d(TAG, "isRunning");
//ALog.d(TAG, "isRunning");
getBinding().setProgress(task.getPercent());
getBinding().setSpeed(task.getConvertSpeed());
}
@@ -199,7 +222,7 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
@Download.onTaskFail
void taskFail(DownloadTask task, Exception e) {
if (task.getKey().equals(mUrl)) {
Toast.makeText(M3U8VodDownloadActivity.this, getString(R.string.download_fail),
Toast.makeText(M3U8VodDLoadActivity.this, getString(R.string.download_fail),
Toast.LENGTH_SHORT)
.show();
getBinding().setStateStr(getString(R.string.start));
@@ -212,7 +235,7 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
void taskComplete(DownloadTask task) {
if (task.getKey().equals(mUrl)) {
getBinding().setProgress(100);
Toast.makeText(M3U8VodDownloadActivity.this, getString(R.string.download_success),
Toast.makeText(M3U8VodDLoadActivity.this, getString(R.string.download_success),
Toast.LENGTH_SHORT).show();
getBinding().setStateStr(getString(R.string.re_start));
getBinding().setSpeed("");
@@ -242,7 +265,7 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
}
private void startD() {
Aria.download(M3U8VodDownloadActivity.this)
Aria.download(M3U8VodDLoadActivity.this)
.load(mUrl)
.useServerFileName(true)
.setFilePath(mFilePath, true)
@@ -270,6 +293,7 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
return false;
}
})
//.asVod().setPeerIndex(50)
.start();
}
@@ -279,6 +303,8 @@ public class M3U8VodDownloadActivity extends BaseActivity<ActivityM3u8VodBinding
mModule.uploadUrl(this, String.valueOf(data));
} else if (result == ModifyPathDialog.MODIFY_PATH_RESULT) {
mModule.updateFilePath(this, String.valueOf(data));
} else if (result == VideoPlayerFragment.SEEK_BAR_PROGRESS_KEY) {
Aria.download(this).load(mUrl).asM3U8().asVod().jumPeerIndex((Integer) data);
}
}
}

View File

@@ -0,0 +1,217 @@
package com.arialyy.simple.core.download.m3u8;
import android.annotation.SuppressLint;
import android.arch.lifecycle.ViewModelProviders;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.SeekBar;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.m3u8.M3U8Entity;
import com.arialyy.frame.base.BaseFragment;
import com.arialyy.simple.R;
import com.arialyy.simple.databinding.FragmentVideoPlayerBinding;
import java.io.IOException;
import java.util.List;
@SuppressLint("ValidFragment")
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public class VideoPlayerFragment extends BaseFragment<FragmentVideoPlayerBinding> {
static final int SEEK_BAR_PROGRESS_KEY = 0xC1;
private M3U8VodModule mModule;
private DownloadEntity mEntity;
private int mPeerIndex;
SparseArray<String> mPlayers = new SparseArray<>();
private SurfaceHolder mSurfaceHolder;
private NextMediaPlayer nexPlayer;
VideoPlayerFragment(int peerIndex, DownloadEntity entity) {
mEntity = entity;
mPeerIndex = peerIndex;
List<M3U8Entity.PeerInfo> peerInfos = entity.getM3U8Entity().getCompletedPeer();
if (peerInfos != null) {
for (M3U8Entity.PeerInfo info : peerInfos) {
mPlayers.put(info.peerId, info.peerPath);
}
}
}
@Override protected void init(Bundle savedInstanceState) {
mModule = ViewModelProviders.of(this).get(M3U8VodModule.class);
final MediaPlayer firstPlayer = new MediaPlayer();
firstPlayer.setScreenOnWhilePlaying(true);
getBinding().surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override public void surfaceCreated(SurfaceHolder holder) {
mSurfaceHolder = holder;
firstPlayer.setSurface(holder.getSurface());
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override public void surfaceDestroyed(SurfaceHolder holder) {
}
});
getBinding().seekBar.setMax(mEntity.getM3U8Entity().getPeerNum());
getBinding().seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override public void onStopTrackingTouch(SeekBar seekBar) {
dataCallback(SEEK_BAR_PROGRESS_KEY, seekBar.getProgress());
}
});
getBinding().controlBt.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
try {
firstPlayer.setDataSource(mPlayers.valueAt(0));
firstPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
});
firstPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override public void onPrepared(MediaPlayer mp) {
mp.start();
setNextMediaPlayer(mp);
}
});
firstPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override public void onCompletion(MediaPlayer mp) {
mp.setDisplay(null);
nexPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
nexPlayer.start();
}
});
}
/**
* 设置下一个分片
*/
private void setNextMediaPlayer(final MediaPlayer lastPlayer) {
mPeerIndex++;
String nextPeerPath = mPlayers.get(mPeerIndex);
if (!TextUtils.isEmpty(nextPeerPath)) {
nexPlayer = new NextMediaPlayer(nextPeerPath);
nexPlayer.prepareAsync();
nexPlayer.setListener(new NextMediaPlayer.StateListener() {
@Override public void onStart(MediaPlayer mp) {
setNextMediaPlayer(mp);
}
@Override public void onCompletion(MediaPlayer mp) {
mp.setDisplay(null);
nexPlayer.getPlayer().setSurface(mSurfaceHolder.getSurface());
nexPlayer.start();
}
@Override public void onPrepared(MediaPlayer mp) {
lastPlayer.setNextMediaPlayer(nexPlayer.getPlayer());
}
});
}
}
@Override protected int setLayoutId() {
return R.layout.fragment_video_player;
}
public void addPlayer(int peerIndex, String peerPath) {
mPlayers.put(peerIndex, peerPath);
}
private static class NextMediaPlayer implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
private StateListener listener;
public interface StateListener {
void onStart(MediaPlayer mp);
void onCompletion(MediaPlayer mp);
void onPrepared(MediaPlayer mp);
}
private MediaPlayer player;
private String videoPath;
private NextMediaPlayer(String videoPath) {
player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnErrorListener(this);
player.setOnCompletionListener(this);
player.setScreenOnWhilePlaying(true);
this.videoPath = videoPath;
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override public void onPrepared(MediaPlayer mp) {
if (listener != null) {
listener.onPrepared(mp);
}
}
});
}
private void prepareAsync() {
try {
player.setDataSource(videoPath);
player.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setListener(StateListener listener) {
this.listener = listener;
}
public String getVideoPath() {
return videoPath;
}
public void start() {
player.start();
if (listener != null) {
listener.onStart(player);
}
}
@Override public void onCompletion(MediaPlayer mp) {
if (listener != null) {
listener.onCompletion(mp);
}
}
@Override public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
@Override public void onPrepared(MediaPlayer mp) {
}
private MediaPlayer getPlayer() {
return player;
}
}
}

View File

@@ -104,7 +104,7 @@ final class FileListAdapter extends AbsRVAdapter<FileListEntity, FileListAdapter
for (String key : keys) {
if (key.equals(url)) {
int index = mPositions.get(key);
//Log.d(TAG, "index ==> " + index);
//Log.d(TAG, "peerIndex ==> " + peerIndex);
return index;
}
}

View File

@@ -35,7 +35,7 @@
/>
<variable
name="viewModel"
type="com.arialyy.simple.core.download.m3u8.M3U8LiveDownloadActivity"
type="com.arialyy.simple.core.download.m3u8.M3U8LiveDLoadActivity"
/>
</data>

View File

@@ -1,6 +1,7 @@
<?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"
xmlns:tools="http://schemas.android.com/tools"
>
<data>
@@ -31,12 +32,11 @@
/>
<variable
name="viewModel"
type="com.arialyy.simple.core.download.m3u8.M3U8VodDownloadActivity"
type="com.arialyy.simple.core.download.m3u8.M3U8VodDLoadActivity"
/>
</data>
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
@@ -76,5 +76,12 @@
bind:stateStr="@{stateStr}"
/>
<FrameLayout
android:id="@+id/video_content"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginTop="16dp"
/>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<SurfaceView
android:id="@+id/surface_view"
android:layout_width="match_parent"
android:layout_height="200dp"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="30dp"
android:layout_alignBottom="@+id/surface_view"
android:background="#33000000"
android:paddingLeft="8dp"
android:paddingRight="8dp"
>
<android.support.v7.widget.AppCompatImageView
android:id="@+id/control_bt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:clickable="true"
app:srcCompat="@drawable/ic_start"
/>
<SeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/control_bt"
/>
</RelativeLayout>
</RelativeLayout>
</layout>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
<!--<domain-config cleartextTrafficPermitted="true">-->
<!--<domain includeSubdomains="true">Your URL(ex: 127.0.0.1)</domain>-->
<!--</domain-config>-->
</network-security-config>