From f0e831b2fead8743c07bfeb31ca7f769c99f912d Mon Sep 17 00:00:00 2001 From: tongtongstudio Date: Thu, 19 Mar 2026 16:59:48 +0800 Subject: [PATCH] =?UTF-8?q?1.1.5=E5=A2=9E=E5=8A=A0=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E5=B0=81=E9=9D=A2=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- .../category/local/LocalCategoryActivity.java | 27 ++++--- .../local/LocalCategoryViewModel.java | 30 ++++--- .../online/CategoryVideoActivity.java | 6 ++ .../online/CategoryVideoViewModel.java | 2 +- .../player/DecryptionPlayerActivity.java | 2 + .../vc/adapter/CategoryVideoAdapter.java | 66 ++++++++++++--- .../com/hainaos/vc/adapter/VideoAdapter.java | 76 +++++++++++++++++- .../vc/network/NetInterfaceManager.java | 2 +- .../com/hainaos/vc/network/api/VideoApi.java | 3 +- .../java/com/hainaos/vc/utils/FileUtils.java | 39 +++++++++ .../main/res/drawable-hdpi/picture_split.png | Bin 0 -> 1740 bytes .../res/layout/activity_category_local.xml | 10 +-- app/src/main/res/layout/item_video_file.xml | 2 +- 14 files changed, 219 insertions(+), 50 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/picture_split.png diff --git a/app/build.gradle b/app/build.gradle index 7a6984e..82e7456 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,8 +18,8 @@ android { //There are no CERT files because If the mini sdk version is 23+, the AGP will ignore the V1 scheme signature. minSdkVersion 23 targetSdkVersion 29 - versionCode 14 - versionName "1.1.3" + versionCode 16 + versionName "1.1.5" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryActivity.java b/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryActivity.java index 089fae2..dff26c3 100644 --- a/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryActivity.java +++ b/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryActivity.java @@ -1,18 +1,20 @@ package com.hainaos.vc.activity.category.local; import android.content.Intent; +import android.os.Build; import android.text.TextUtils; import android.view.View; +import androidx.annotation.RequiresApi; import androidx.lifecycle.Observer; import androidx.recyclerview.widget.DefaultItemAnimator; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import com.hainaos.vc.R; import com.hainaos.vc.adapter.VideoAdapter; import com.hainaos.vc.base.mvvm.BaseMvvmActivity; import com.hainaos.vc.bean.BaseResponse; import com.hainaos.vc.bean.CategoryInfo; +import com.hainaos.vc.bean.CategoryVideoInfo; import com.hainaos.vc.bean.LocalVideoInfo; import com.hainaos.vc.bean.VideoListData; import com.hainaos.vc.databinding.ActivityCategoryLocalBinding; @@ -27,6 +29,9 @@ import com.hjq.toast.Toaster; import java.io.File; import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; public class LocalCategoryActivity extends BaseMvvmActivity { private static final String TAG = "LocalCategoryActivity"; @@ -72,13 +77,13 @@ public class LocalCategoryActivity extends BaseMvvmActivity>() { + @RequiresApi(api = Build.VERSION_CODES.N) @Override public void onChanged(BaseResponse baseResponse) { if (baseResponse.code == 200) { + List categoryVideoInfos = baseResponse.data.getData(); + Map coverMap = categoryVideoInfos.stream().collect(Collectors.toMap(categoryVideoInfo -> FileUtils.getFileNamefromURL(categoryVideoInfo.getFile_url()), CategoryVideoInfo::getCover)); + mVideoAdapter.setCoverMap(coverMap); mViewModel.getVideoList(mCategoryInfo.getFolder()); } else { Toaster.show("密码错误,请重新输入"); diff --git a/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java b/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java index 71556f2..ec4572f 100644 --- a/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java +++ b/app/src/main/java/com/hainaos/vc/activity/category/local/LocalCategoryViewModel.java @@ -34,7 +34,7 @@ import wseemann.media.FFmpegMediaMetadataRetriever; public class LocalCategoryViewModel extends BaseViewModel { - private static final String TAG = "CategoryViewModel"; + private static final String TAG = "LocalCategoryViewModel"; @Override public ActivityCategoryLocalBinding getVDBinding() { @@ -113,19 +113,23 @@ public class LocalCategoryViewModel extends BaseViewModel { private static final String TAG = "CategoryActivity"; + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private CategoryInfo mCategoryInfo; private String mPasswd = ""; private CategoryVideoAdapter mCategoryVideoAdapter; @@ -114,6 +119,7 @@ public class CategoryVideoActivity extends BaseMvvmActivity categoryVideoInfos = videoListData.getData(); mCategoryVideoAdapter.setData(categoryVideoInfos); + if (categoryVideoInfos == null || categoryVideoInfos.isEmpty()) { mViewDataBinding.clNodata.setVisibility(View.VISIBLE); mViewDataBinding.rvVideo.setVisibility(View.GONE); diff --git a/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoViewModel.java b/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoViewModel.java index 6c6e474..63c2a22 100644 --- a/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoViewModel.java +++ b/app/src/main/java/com/hainaos/vc/activity/category/online/CategoryVideoViewModel.java @@ -27,7 +27,7 @@ import io.reactivex.rxjava3.disposables.Disposable; public class CategoryVideoViewModel extends BaseViewModel { - private static final String TAG = "CategoryViewModel"; + private static final String TAG = "CategoryVideoViewModel"; @Override public ActivityCategoryVideoBinding getVDBinding() { diff --git a/app/src/main/java/com/hainaos/vc/activity/player/DecryptionPlayerActivity.java b/app/src/main/java/com/hainaos/vc/activity/player/DecryptionPlayerActivity.java index 3ce3987..7cd423a 100644 --- a/app/src/main/java/com/hainaos/vc/activity/player/DecryptionPlayerActivity.java +++ b/app/src/main/java/com/hainaos/vc/activity/player/DecryptionPlayerActivity.java @@ -3,6 +3,7 @@ package com.hainaos.vc.activity.player; import android.content.Intent; import android.net.Uri; import android.text.TextUtils; +import android.util.Log; import android.view.View; import com.google.android.exoplayer2.ExoPlayer; @@ -75,6 +76,7 @@ public class DecryptionPlayerActivity extends BaseMvvmActivity { private static final String TAG = "VideoAdapter"; + + private MMKV mMMKV = MMKV.mmkvWithID(CommonConfig.MMKV_ID, MMKV.MULTI_PROCESS_MODE); + + private Activity mContext; private ArrayList mLocalVideoInfos; private onItemLongClickListener onItemLongClickListener; + private Map mCoverMap; + public VideoAdapter() { } @@ -49,6 +62,11 @@ public class VideoAdapter extends RecyclerView.Adapter this.mLocalVideoInfos = path; } + public void setCoverMap(Map coverMap) { + mCoverMap = coverMap; + notifyDataSetChanged(); + } + private static class VideoResult { long time; Bitmap frame; @@ -72,6 +90,7 @@ public class VideoAdapter extends RecyclerView.Adapter @NonNull @Override public VideoHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + Aria.download(this).register(); VideoHolder holder = new VideoHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_video_file, parent, false)); return holder; } @@ -81,16 +100,40 @@ public class VideoAdapter extends RecyclerView.Adapter LocalVideoInfo localVideoInfo = mLocalVideoInfos.get(position); final String localPath = localVideoInfo.getLocalPath(); Log.e(TAG, "onBindViewHolder: " + localPath); - holder.title.setText(FileUtils.getFileName(localPath)); + String videoFileName = FileUtils.getFileName(localPath); + holder.title.setText(videoFileName); File file = new File(localPath); if (file.exists()) { holder.iv_status.setVisibility(View.GONE); - Glide.with(mContext).load(file).error(R.mipmap.ic_launcher).into(holder.video_image); - holder.duration.setText(TimeUtils.TimeFormat(localVideoInfo.getDuration() * 1000)); + if (file.getName().endsWith(".hnv")) { + String dirPaht = file.getParent(); + Log.e(TAG, "onBindViewHolder: dirPaht = " + dirPaht); + if (mCoverMap != null) { + String coverUrl = mCoverMap.get(videoFileName); + Log.e(TAG, "onBindViewHolder: coverUrl = " + coverUrl); + if (!TextUtils.isEmpty(coverUrl)) { + String coverName = FileUtils.getFileNamefromURL(coverUrl); + Log.e(TAG, "onBindViewHolder: coverName = " + coverName); + File coverFile = new File(dirPaht + File.separator + coverName); + Log.e(TAG, "onBindViewHolder: coverFile = " + coverFile.getAbsolutePath()); + if (coverFile.exists()) { + Glide.with(mContext).load(coverFile).centerCrop().error(R.drawable.picture_split).into(holder.video_image); + } else { + FileUtils.ariaDownloadCover(mContext, coverFile.getParent(), coverUrl); + } + } else { + holder.video_image.setImageDrawable(mContext.getDrawable(R.drawable.picture_split)); + } + } else { + holder.video_image.setImageDrawable(mContext.getDrawable(R.drawable.picture_split)); + } + } else { + Glide.with(mContext).load(file).centerCrop().error(R.drawable.picture_split).into(holder.video_image); + holder.duration.setText(TimeUtils.TimeFormat(localVideoInfo.getDuration() * 1000)); + } } else { holder.iv_status.setVisibility(View.VISIBLE); - } holder.iv_status.setOnClickListener(new View.OnClickListener() { @@ -194,4 +237,29 @@ public class VideoAdapter extends RecyclerView.Adapter void onScanCompleted(Bitmap bitmap); } + //在这里处理任务执行中的状态,如进度进度条的刷新 + @Download.onTaskRunning + void running(DownloadTask task) { + Log.e(TAG, "running: " + "正在下载:" + task.getState() + "-" + task.getPercent() + "--" + task.getExtendField()); + + notifyDataSetChanged(); + } + + @Download.onTaskComplete + void taskComplete(DownloadTask task) { + //在这里处理任务完成的状态 + Log.e(TAG, "taskComplete: " + task.getFilePath()); + notifyDataSetChanged(); + } + + @Download.onTaskFail + void taskFail(DownloadTask task, Exception e) { + try { + Log.e(TAG, "taskFail: e " + e.getMessage()); + } catch (Exception ex) { + Log.e(TAG, "taskFail: ex " + ex.getMessage()); + } + + notifyDataSetChanged(); + } } diff --git a/app/src/main/java/com/hainaos/vc/network/NetInterfaceManager.java b/app/src/main/java/com/hainaos/vc/network/NetInterfaceManager.java index 6a25de6..e76b6a7 100644 --- a/app/src/main/java/com/hainaos/vc/network/NetInterfaceManager.java +++ b/app/src/main/java/com/hainaos/vc/network/NetInterfaceManager.java @@ -243,7 +243,7 @@ public class NetInterfaceManager { public Observable> getVideoListObservable(String category_uuid, String password) { String bearerToken = LoginUtils.getInstance().getBearerToken(); return getVideoApi() - .getVideoList(bearerToken, category_uuid, password) + .getVideoList(bearerToken, category_uuid, password, 20) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()); } diff --git a/app/src/main/java/com/hainaos/vc/network/api/VideoApi.java b/app/src/main/java/com/hainaos/vc/network/api/VideoApi.java index cea34e7..40de544 100644 --- a/app/src/main/java/com/hainaos/vc/network/api/VideoApi.java +++ b/app/src/main/java/com/hainaos/vc/network/api/VideoApi.java @@ -24,7 +24,8 @@ public interface VideoApi { Observable> getVideoList( @Header("Authorization") String token, @Query("category_uuid") String category_uuid, - @Query("password") String password + @Query("password") String password, + @Query("page_size") int page_size ); @FormUrlEncoded diff --git a/app/src/main/java/com/hainaos/vc/utils/FileUtils.java b/app/src/main/java/com/hainaos/vc/utils/FileUtils.java index a19961b..d779b56 100644 --- a/app/src/main/java/com/hainaos/vc/utils/FileUtils.java +++ b/app/src/main/java/com/hainaos/vc/utils/FileUtils.java @@ -160,6 +160,45 @@ public class FileUtils { } } + public static void ariaDownload(Context context, String dirName, String url) { + String downLoadPath = getHainaVideoPath(context) + dirName + File.separator; + File dirFile = new File(downLoadPath); + if (!dirFile.exists()) { + Log.e(TAG, "ariaDownload: mkdirs = " + dirFile.mkdirs()); + } + String fileName = getFileNamefromURL(url); + File file = new File(downLoadPath + fileName); + if (file.exists() && !file.isDirectory()) { + Log.e("ariaDownload", url + " pic exists, skip"); + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(file.getAbsolutePath()) +// .ignoreFilePathOccupy() + .setExtendField(url) + .create(); //启动下载} + } + } + + public static void ariaDownloadCover(Context context, String coverPath, String url) { + File dirFile = new File(coverPath); + if (!dirFile.exists()) { + Log.e(TAG, "ariaDownload: mkdirs = " + dirFile.mkdirs()); + } + String fileName = getFileNamefromURL(url); + File file = new File(coverPath + File.separator + fileName); + if (file.exists() && !file.isDirectory()) { + Log.e("ariaDownload", url + " pic exists, skip"); + } else { + Aria.download(context) + .load(url) //读取下载地址 + .setFilePath(file.getAbsolutePath()) +// .ignoreFilePathOccupy() + .setExtendField(url) + .create(); //启动下载} + } + } + public static void ariaDownload(Context context, String url, AppInfo appInfo) { Log.e(TAG, "ariaDownload: " + appInfo); AriaDownloadInfo ariaDownloadInfo = AriaDownloadInfo.toAriaDownloadInfo(appInfo); diff --git a/app/src/main/res/drawable-hdpi/picture_split.png b/app/src/main/res/drawable-hdpi/picture_split.png new file mode 100644 index 0000000000000000000000000000000000000000..8a95223579c4f9fa38ca1d5a5c8b76c92472817c GIT binary patch literal 1740 zcmV;-1~d7IP)Px*hDk(0RCr$Pon2DgFbv0?4EHEK0%Uk@IZ4Y&%ATb3B!y=taD;B}0ZFT!gb9uv zS+?X@A(`p)0VlEb%U_n|kFCsp6=i{{sM_q6F*}gLK7t*{4x}&(6jq&GAv=)5EKpc= zc7Eb2-vf+ITyyY=9d93iE6~_FkW$q#Lb+?2=4L9-e9RQ)Ks{6~!%j=H< zq;z!vhhx(;pFaeU($z6QSRDxDlX66G8q~3hLhg()5C0RC_v2s);{TVIm-8WM`Aq_l z5_RMQ;_9q?!M?zFK#Mx^0EtQB4Jiy5s3p5IMe2|T5(8sY&XCIZod`vfI>dp@208G? zA$$DA7;~CisjBMO_x-PFzcNB;+cqh&sZ1TBKxW|^eDQtX|MX3AK|fPf)s3C`Y}+$<+4LK*rKa9yNJp*rM%*nJ1l^~_+lZQGM*7^6`gazN~_Gf*9G zHn-=yscuWDI>dm?`VZhhGULk@^B=B8;HNF<&v%Bb6RR|J=*T^*u8W~1~W^u@BdzWdN+NWOJe zRCh@XuepoM&4;-1SW8JmSNT+R45^x=^b5Dek>|+)f$2zl)IC;avLMa4a#&-z(7p#- zg{Vj+qCmi|-UVRTmq(ZvarPb4=MyspSk)x|E)L|hlERfV^tB30LfZFX>KMxt081Ji zd$v4~Nexi7L@ew^)e#fvVOA6TdsZN)c7S5w|Gw`Zpr0|ujB_L8*}+hCOjJ^O2cI7Z zfSgh^u^l|NN-|`z zA7hZP86YCAD+C7fpmRGwQd9y)wWBT{jKM`cOef$Np==6Bl1iov@_aC?=>XphWpJS2 z=;O8pgrS4Kh0Xk~BR4#AGu%)%2PCP3_eEvML>VWPb$|>pJ!E?SR#o+-?|atcEK)}B zHk80wOD-tcfgHQ8yRlsY7J7z^C#*8jVes@hfiT8fIG|(&GJBbAXwE@as!E73xS(VM zg2I@Dj+Ax0Uhz=&HAcEA-@8+kk_Ctt1|;}gM-wqACHNyqa8uk+#DO@CVr{~aT5(A3 zMHk^%#({34WsVPNf=LSY5M0RyYN6N&;DSi43jY(O|+V3mIdMG*|FT>#}9$9Y*2 zFtEy>pv1s%&3#0qW>RnQh5Fy^c^2vsf08gTD7T5zw&cSIQYpmb+bBSCz*vM5V<774 z`j~eR?m-8yp+IuNV1*(y03 zXrH#M3C7Z)X`-f$dpHin^;`|gfO;1gQDK!ltxr#0bzupHKHm9 z2p5bT{aZrB6mu)ysdM)sTrf5eQAH~xXiXI1b2u!Ng;VI>etpMRuCQ4@LetTrK?=$3 zqrFE1j?Gb+qe4jx1#loMg_Pcz!3{-JaV~2z0*0enbNp7UcN>9%S-(&v_{xPTWW0Nb zYT%b~KBd0dcYj^i2iKmF4MtQh6W~9+DrI=eb2l1MxlDjh;Zh7IRrUk8DlnbXRnO+s zrHo8@?$&|8*zEQ7_24?NphzG9Z-9cH0Z##4Kv_7U)p>5pShr$<6kxnns;~oD#q9o< i?m%`Rg;}7m>ih$Y-v__3HwU=@0000 - + + + + - + diff --git a/app/src/main/res/layout/item_video_file.xml b/app/src/main/res/layout/item_video_file.xml index c3f4cab..9d28862 100644 --- a/app/src/main/res/layout/item_video_file.xml +++ b/app/src/main/res/layout/item_video_file.xml @@ -20,7 +20,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:adjustViewBounds="true" - android:scaleType="centerCrop" + android:scaleType="centerInside" app:is_cover_src="true" />