交友房

This commit is contained in:
2025-10-31 15:18:32 +08:00
parent 6098927e73
commit 7a81001f2a
21 changed files with 1148 additions and 2611 deletions

View File

@@ -57,72 +57,13 @@ import okhttp3.ResponseBody;
public class AvatarFrameView extends FrameLayout {
private PlaybackManager playbackManager;
private void handleVideoComplete() {
// if (isDestroyed) return;
if (mType == 1) {
if (mBinding != null && mFile != null) {
mBinding.playView.startPlay(mFile); // 循环播放
}
} else {
isPlaying = false;
// playNextFromQueue(); // 播放下一项
currentProcessingCount = Math.max(0, currentProcessingCount - 1);
// 内存检查和清理
if (playQueue.size() % 1 == 0) { // 每处理10个动画检查一次内存
performLightCleanup();
}
// 延迟处理下一个,避免过于频繁
mainHandler.postDelayed(() -> {
smartCheckAndStartPlayback();
}, PROCESSING_DELAY);
// mainHandler.postDelayed(this::playNextFromQueue, 50);
}
}
private void performLightCleanup() {
// 只清理不需要的缓存,保留正在使用的资源
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
long maxMemory = runtime.maxMemory();
double memoryUsage = (double) usedMemory / maxMemory;
// 内存使用超过70%时进行轻量级清理
if (memoryUsage > 0.7) {
// 清理SVGA缓存中较旧的项目
if (svgaCache.size() > 1) {
// 保留最近使用的1个缓存项
String oldestKey = null;
for (String key : svgaCache.keySet()) {
if (oldestKey == null) {
oldestKey = key;
}
}
if (oldestKey != null) {
svgaCache.remove(oldestKey);
}
}
// 建议进行垃圾回收
System.gc();
}
}
public enum RenderType {SVGA, MP4}
private RenderType renderType;
// private ExoPlayer exoPlayer;
// private PlayerView playerView;
private SVGAImageView svgaSurface;
private SVGAImageView svgaSurface2;
private GLSurfaceView glSurfaceView;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private ChannelSplitRenderer1 renderer;
private int mType;//1:循环播放 2:播放一次停止播放
private File mFile;
private final BlockingQueue<PlayItem> playQueue = new LinkedBlockingQueue<>();
private boolean isPlaying = false;
@@ -369,55 +310,7 @@ public class AvatarFrameView extends FrameLayout {
playNextFromQueue();
}
}
// 异步处理URL解析等耗时操作
// ThreadUtils.executeByIo(new ThreadUtils.SimpleTask<String>() {
// @Override
// public String doInBackground() throws Throwable {
// // 在后台线程进行URL有效性检查或其他预处理
// if (url == null || url.isEmpty()) {
// return null;
// }
// return url; // 返回处理后的URL
// }
//
// @Override
// public void onSuccess(String processedUrl) {
// if (processedUrl != null) {
// // 使用post方法确保在下一个UI循环中执行
// mainHandler.post(() -> {
// // 再次检查状态
// if (!isDestroyed && !isPlaying) {
// playQueue.add(new PlayItem(processedUrl, type2));
//// checkAndStartPlayback();
// // 智能检查并开始播放
// smartCheckAndStartPlayback();
// } else {
// // 如果正在播放,添加到队列中
// playQueue.add(new PlayItem(processedUrl, type2));
// }
// });
// }
// }
//
// @Override
// public void onFail(Throwable e) {
// LogUtils.e("Error processing gift URL: " + e.getMessage());
// }
// });
// 添加到播放队列
// playQueue.offer(new PlayItem(url, type2));
// playQueue.add(new PlayItem(url, type2));
Logger.d("AvatarFrameView", "Added to queue, queue size: " + playQueue.size() + ", url: " + url);
// 如果当前没有在播放,则开始播放
// if (!isPlaying) {
// playNextFromQueue();
// }
// 改进播放检查逻辑
// checkAndStartPlayback();
}
private void smartCheckAndStartPlayback() {
@@ -568,14 +461,8 @@ public class AvatarFrameView extends FrameLayout {
playMp4File(file);
} else {
LogUtils.w(TAG, "有缓存2222222222222");
// onPlaybackComplete();
}
});
// 直接播放缓存文件
// if (isTxk) {
// mBinding.playView.setLoop(1);
// }
// mBinding.playView.startPlay(file);
}
}
@@ -619,138 +506,6 @@ public class AvatarFrameView extends FrameLayout {
}
}
// private void downloadAndPlayMp4(String url) {
// String filePath = PathUtils.getInternalAppCachePath() + Md5Utils.getStringMD5(url) + ".mp4";
// File file = new File(filePath);
//
// if (file.exists() && file.length() > 0) {
// playMp4(file);
// mFile = file;
// } else {
// // 删除可能存在的损坏文件
//// if (file.exists()) {
//// file.delete();
//// }
//
// DownloadTask task = new DownloadTask.Builder(url, PathUtils.getInternalAppCachePath()
// , Md5Utils.getStringMD5(url) + ".mp4")
// .setMinIntervalMillisCallbackProcess(300)
// .setPassIfAlreadyCompleted(true)
// .setAutoCallbackToUIThread(true)
// .setConnectionCount(3) // 增加连接数提高稳定性
// .setReadBufferSize(1024 * 8) // 增大缓冲区
// .build();
// if (StatusUtil.isCompleted(task)) {
// playMp4(task.getFile());
// mFile = task.getFile();
// } else if (StatusUtil.isSameTaskPendingOrRunning(task)) {
// Logger.d(TAG, "Task is pending or running, checking if it's stuck");
// // 检查任务是否可能卡住了
// // 添加超时机制,如果任务长时间没有进展,则重新开始
// checkAndHandleStuckTask(task, url);
// } else {
// Logger.d(TAG, "Starting new download task");
// startNewDownload(task, url);
// }
//
//// else if (StatusUtil.isSameTaskPendingOrRunning(task)) {
//// // 如果任务正在进行中,等待完成
//// // 可以通过监听器处理
//// attachToExistingTask(task);
//// } else {
//// task.enqueue(new DownloadListener1() {
//// @Override
//// public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) {
//// Logger.e("AvatarFrameView1", model);
//// }
////
//// @Override
//// public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) {
//// Logger.e("AvatarFrameView2", cause);
////
//// }
////
//// @Override
//// public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
//// Logger.e("AvatarFrameView3", blockCount);
//// }
////
//// @Override
//// public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
//// Logger.e("AvatarFrameView4", currentOffset);
//// }
////
//// @Override
//// public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
//// Logger.e("AvatarFrameView5", model);
////// playMp4(task.getFile());
////// mFile = task.getFile();
////// if (cause != null && cause != EndCause.COMPLETED) {
//////// CrashReport.postCatchedException(new RuntimeException("下载任务结束:" + cause == null ? "" : cause.name() + "_realCause:" + realCause == null ? "" : realCause.getMessage()));
////// }
////
//// if (cause == EndCause.COMPLETED) {
//// File downloadedFile = task.getFile();
//// if (downloadedFile != null && downloadedFile.exists() && downloadedFile.length() > 0) {
//// playMp4(downloadedFile);
//// mFile = downloadedFile;
//// } else {
//// Logger.e(TAG, "Downloaded file is invalid");
//// handleDownloadFailure(url, cause, new IOException("Downloaded file is invalid"));
//// }
//// } else {
//// handleDownloadFailure(url, cause, realCause);
//// }
//// }
//// });
//// }
// }
// }
// 添加检查进行中任务的方法
private void attachToExistingTask(DownloadTask task) {
// 为已经在队列中的任务附加监听器
task.enqueue(new DownloadListener1() {
@Override
public void taskEnd(@NonNull DownloadTask task, @NonNull EndCause cause, @Nullable Exception realCause, @NonNull Listener1Assist.Listener1Model model) {
if (cause == EndCause.COMPLETED) {
playMp4(task.getFile());
mFile = task.getFile();
} else {
isPlaying = false;
playNextFromQueue();
}
}
// 其他回调方法保持空实现或按需处理
@Override
public void taskStart(@NonNull DownloadTask task, @NonNull Listener1Assist.Listener1Model model) {
}
@Override
public void retry(@NonNull DownloadTask task, @NonNull ResumeFailedCause cause) {
}
@Override
public void connected(@NonNull DownloadTask task, int blockCount, long currentOffset, long totalLength) {
}
@Override
public void progress(@NonNull DownloadTask task, long currentOffset, long totalLength) {
}
});
}
private void playMp4(File file) {
if (file != null) {
mBinding.playView.startPlay(file);
} else {
// showAnim();
// playMp4(file);
// CrashReport.postCatchedException(new RuntimeException("播放MP4失败:File is null"));
}
}
private void handleSVGAComplete(SVGAVideoEntity videoItem, String url) {
if (svgaSurface == null) {
onPlaybackComplete();
@@ -758,7 +513,6 @@ public class AvatarFrameView extends FrameLayout {
}
try {
// 缓存实体(使用弱引用)
// 缓存实体(使用弱引用)
if (svgaCache.size() < MAX_SVGA_CACHE_SIZE) {
svgaCache.put(url, new WeakReference<>(videoItem));
@@ -793,15 +547,6 @@ public class AvatarFrameView extends FrameLayout {
} else {
onPlaybackComplete();
}
// if (Looper.myLooper() != Looper.getMainLooper()) {
// mainHandler.post(() -> {
// isPlaying = false;
// playNextFromQueue();
// });
// } else {
// isPlaying = false;
// playNextFromQueue();
// }
}
});
// 设置循环次数
@@ -838,8 +583,6 @@ public class AvatarFrameView extends FrameLayout {
}
private void playCachedSVGA(SVGAVideoEntity videoItem) {
// if (isDestroyed || svgaSurface == null) return;
try {
SVGADrawable drawable = new SVGADrawable(videoItem, new SVGADynamicEntity());
svgaSurface.setImageDrawable(drawable);
@@ -858,18 +601,14 @@ public class AvatarFrameView extends FrameLayout {
@Override
public void onFinished() {
// if (isDestroyed) return;
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> {
isPlaying = false;
// 添加延迟确保状态更新
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
// playNextFromQueue();
});
} else {
isPlaying = false;
// playNextFromQueue();
mainHandler.postDelayed(AvatarFrameView.this::playNextFromQueue, 50);
}
}
@@ -890,7 +629,6 @@ public class AvatarFrameView extends FrameLayout {
}
private void loadNewSVGA(String url) {
// if (isDestroyed) return;
try {
new SVGAParser(getContext()).parse(new URL(url), new SVGAParser.ParseCompletion() {
@@ -928,8 +666,6 @@ public class AvatarFrameView extends FrameLayout {
}
private void loadSVGA(String url) {
// if (isDestroyed || svgaSurface == null) return;
if (Looper.myLooper() != Looper.getMainLooper()) {
mainHandler.post(() -> loadSVGA(url));
return;
@@ -986,13 +722,6 @@ public class AvatarFrameView extends FrameLayout {
}
});
// svgaSurface.setCallback(new SVGAImageViewCallback() {
// @Override
// public void onAnimationFinished() {
// isPlaying = false;
// playNextFromQueue();
// }
// });
svgaSurface.startAnimation();
}
@@ -1007,65 +736,9 @@ public class AvatarFrameView extends FrameLayout {
}
}
// private void loadMP4(String url) {
// svgaSurface.setVisibility(View.GONE);
// playerView.setVisibility(View.GONE);
//
// glSurfaceView.setVisibility(View.VISIBLE);
// glSurfaceView.onResume();
// glSurfaceView.requestRender();
// // 使用 post 确保 GLSurfaceView 已完成 layout
// glSurfaceView.post(() -> {
// Log.d("@@@", "GLSurfaceView size after layout: " + glSurfaceView.getWidth() + "x" + glSurfaceView.getHeight());
//
// glSurfaceView.onResume();
// glSurfaceView.requestRender();
//
// renderer.setOnSurfaceTextureReadyListener(surfaceTexture -> {
// mainHandler.post(() -> {
// Surface surface = new Surface(surfaceTexture);
//
// MediaItem mediaItem = MediaItem.fromUri(Uri.parse(url));
// exoPlayer.setMediaItem(mediaItem);
// exoPlayer.setVideoSurface(surface);
// exoPlayer.prepare();
// exoPlayer.play();
// Log.d("@@@", "ExoPlayer state after play: " + exoPlayer.getPlaybackState());
// });
// });
// });
// }
private void clearPrevious() {
// 确保在主线程中执行
// if (Looper.myLooper() != Looper.getMainLooper()) {
// mainHandler.post(() -> {
// clearPrevious();
//// }
// });
// return;
// }
try {
// 停止并清理 ExoPlayer
// if (exoPlayer != null) {
// try {
// exoPlayer.stop(); // 这里可能会在错误线程中调用
// exoPlayer.clearVideoSurface();
// } catch (Exception e) {
// Logger.e("Error stopping ExoPlayer: " + e.getMessage());
// // 如果在错误线程中,切换到主线程重试
// mainHandler.post(() -> {
// try {
// if (exoPlayer != null) {
// exoPlayer.stop();
// exoPlayer.clearVideoSurface();
// }
// } catch (Exception ex) {
// Logger.e("Error stopping ExoPlayer on main thread: " + ex.getMessage());
// }
// });
// }
// }
// 停止并清理 SVGA 动画
if (svgaSurface != null && svgaSurface.getDrawable() instanceof SVGADrawable) {
SVGADrawable drawable = (SVGADrawable) svgaSurface.getDrawable();
@@ -1090,15 +763,6 @@ public class AvatarFrameView extends FrameLayout {
} catch (Exception e) {
LogUtils.e(TAG, "Error in clearPrevious: " + e.getMessage());
}
// if (svgaSurface.getDrawable() instanceof SVGADrawable) {
// ((SVGADrawable) svgaSurface.getDrawable()).stop();
// }
// if (playerView != null) playerView.setVisibility(View.GONE);
// if (svgaSurface != null) svgaSurface.setVisibility(View.GONE);
// if (glSurfaceView != null) glSurfaceView.setVisibility(View.GONE);
// mBinding.playView.setVisibility(View.GONE);
}
// 简单的 LRU Cache 实现
@@ -1141,40 +805,6 @@ public class AvatarFrameView extends FrameLayout {
});
}
}).start();
// try {
// // 清理 SVGA 资源
// if (svgaSurface != null && svgaSurface.getDrawable() instanceof SVGADrawable) {
// SVGADrawable drawable = (SVGADrawable) svgaSurface.getDrawable();
// if (drawable != null) {
// try {
// drawable.stop();
// svgaSurface.clearAnimation();
// svgaSurface.setImageDrawable(null);
// } catch (Exception e) {
// LogUtils.e(TAG, "Error releasing SVGA resources: " + e.getMessage());
// }
// }
// }
//
// // 停止并清理播放器
// if (mBinding != null && mBinding.playView != null) {
// mBinding.playView.stopPlay();
// }
//
// // 清理 ExoPlayer 资源
// if (exoPlayer != null) {
// try {
// exoPlayer.stop();
// exoPlayer.clearVideoSurface();
// } catch (Exception e) {
// LogUtils.e(TAG, "Error releasing ExoPlayer resources: " + e.getMessage());
// }
// }
// } catch (Exception e) {
// LogUtils.e(TAG, "Error in releaseResources: " + e.getMessage());
// }
}
/**