交友房
This commit is contained in:
@@ -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());
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user