app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraPushManager.java
@@ -15,6 +15,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import com.alivc.live.pusher.AlivcAudioAACProfileEnum; @@ -150,6 +151,7 @@ Timber.d("stopPush called"); stopPushThread(); // stopAudioTransfer(); stopWaterMaskSchedule(); releaseAlivcPusher(); if (usbCamera != null) { usbCamera.stopCamera(); @@ -282,7 +284,15 @@ private ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); private void setWaterMask() { scheduledExecutorService.scheduleWithFixedDelay(() -> { // 防止重复 schedule(startPush 可能被多次调用) if (watermarkFuture != null && !watermarkFuture.isCancelled()) { return; } if (scheduledExecutorService == null || scheduledExecutorService.isShutdown()) { scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); } watermarkFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { if (pushStarted){ @@ -350,6 +360,28 @@ } },1,1, TimeUnit.SECONDS); } private ScheduledFuture<?> watermarkFuture; private void stopWaterMaskSchedule() { try { if (watermarkFuture != null) { watermarkFuture.cancel(true); watermarkFuture = null; } } catch (Throwable t) { Timber.w(t, "cancel watermarkFuture failed"); } try { if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) { scheduledExecutorService.shutdownNow(); } } catch (Throwable t) { Timber.w(t, "shutdown watermark scheduledExecutorService failed"); } finally { scheduledExecutorService = null; } } private Handler mainHandler = new Handler(Looper.getMainLooper()); @@ -610,6 +642,8 @@ * 释放阿里推流资源 */ private void releaseAlivcPusher() { // 兜底:防止外部没有走 stopPush stopWaterMaskSchedule(); // 移除隐藏的 SurfaceView if (previewSurfaceView != null && windowManager != null) { try { app/src/main/java/com/safeluck/floatwindow/manager/UsbCameraRecordManager.java
@@ -28,6 +28,7 @@ import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; /** @@ -146,9 +147,18 @@ int baseY = 20; int fontSize= 24; private ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); private ScheduledFuture<?> watermarkFuture; private void setWaterMask() { scheduledExecutorService.scheduleWithFixedDelay(() -> { // 防止重复 schedule(startRecord 可能被多次调用) if (watermarkFuture != null && !watermarkFuture.isCancelled()) { return; } if (scheduledExecutorService == null || scheduledExecutorService.isShutdown()) { scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); } watermarkFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { @@ -216,6 +226,26 @@ },1,1, TimeUnit.SECONDS); } private void stopWaterMaskSchedule() { try { if (watermarkFuture != null) { watermarkFuture.cancel(true); watermarkFuture = null; } } catch (Throwable t) { Timber.w(t, "cancel watermarkFuture failed"); } try { if (scheduledExecutorService != null && !scheduledExecutorService.isShutdown()) { scheduledExecutorService.shutdownNow(); } } catch (Throwable t) { Timber.w(t, "shutdown watermark scheduledExecutorService failed"); } finally { scheduledExecutorService = null; } } /** @@ -223,6 +253,8 @@ */ public void stopRecord() { Timber.d("stopRecord called"); stopWaterMaskSchedule(); // 停止音频线程 if (audioThread != null) { @@ -351,6 +383,8 @@ * 释放资源 */ private void releaseResources() { // 兜底:防止异常退出时水印线程泄露 stopWaterMaskSchedule(); if (audioRecord != null) { try { if (audioRecord.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING) {