From f81bd2c76d89c03f2cea45d66859ec8035f4ea54 Mon Sep 17 00:00:00 2001
From: xiaowusky <chenyangyang3858@dingtalk.com>
Date: Mon, 4 Dec 2023 10:07:20 +0800
Subject: [PATCH] =?UTF-8?q?desc:=E6=8E=A8=E6=B5=81=E7=9B=B8=E5=85=B3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/com/yinuo/safetywatcher/TestUtils.kt |  1 -
 .../com/yinuo/safetywatcher/watcher/App.kt    | 10 ----
 .../safetywatcher/watcher/ui/HomeActivity.kt  |  7 +++
 .../vlc/encoder/MediaCodecManager.java        | 56 ++++++++++---------
 .../main/java/org/easydarwin/PushHelper.kt    | 16 ++++--
 5 files changed, 48 insertions(+), 42 deletions(-)

diff --git a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt
index e417c0c..892ccf7 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/TestUtils.kt
@@ -32,7 +32,6 @@ object TestUtils {
 
     fun insertData() {
         getSupportCodec()
-        PushHelper.setPushUrl("rtsp://192.168.5.17:554/123")
         GlobalScope.launch() {
             // 构造气体数据
             val timeMillis = System.currentTimeMillis()
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt
index 1f388aa..85e0baa 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/App.kt
@@ -3,18 +3,8 @@ package com.yinuo.safetywatcher.watcher
 import com.common.commonlib.CommonApplication
 import com.common.commonlib.db.DBUtils
 import com.common.commonlib.db.entity.Warning
-import com.yinuo.safetywatcher.R
-import com.yinuo.safetywatcher.TestUtils
-import com.yinuo.safetywatcher.watcher.constant.CAMERA_DNS
-import com.yinuo.safetywatcher.watcher.constant.CAMERA_GATEWAY
-import com.yinuo.safetywatcher.watcher.constant.CAMERA_IP
-import com.yinuo.safetywatcher.watcher.constant.CAMERA_NETMASK
-import com.yinuo.safetywatcher.watcher.port.cmd.GasPortStatus
 import com.yinuo.safetywatcher.watcher.utils.GPIOUtils
 import com.yinuo.safetywatcher.watcher.utils.PlatformUtils
-import com.yinuo.safetywatcher.watcher.utils.SoundUtils
-import com.yinuo.safetywatcher.watcher.wifi.WiFiConfig
-import com.yinuo.safetywatcher.watcher.wifi.WiFiModule
 import kotlinx.coroutines.DelicateCoroutinesApi
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt
index 0691d72..0afa8e9 100644
--- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt
+++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/HomeActivity.kt
@@ -29,6 +29,7 @@ import com.yinuo.safetywatcher.watcher.utils.WifiHelper
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
+import org.easydarwin.PushHelper
 import org.easydarwin.TxtOverlay
 import org.easydarwin.video.EasyPlayerClient
 import java.io.File
@@ -101,6 +102,9 @@ class HomeActivity : NoOptionsActivity() {
     private fun onCameraOpen() {
         // 启动录制编码
         RecordHelper.startRecording()
+        // 启动推送
+        PushHelper.opSwitch(true)
+        PushHelper.startStream(true)
         // 开启GPIO
         GPIOUtils.openCamera()
         setForCamera()
@@ -109,6 +113,9 @@ class HomeActivity : NoOptionsActivity() {
     private fun onCameraClose() {
         // 暂停录制编码
         RecordHelper.stopRecording()
+        // 关闭推流
+        PushHelper.opSwitch(false)
+        PushHelper.stop()
         // 关闭GPIO
         GPIOUtils.closeCamera()
         // 关闭视频播放
diff --git a/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java b/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java
index 192e798..90545c9 100644
--- a/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java
+++ b/library-push/src/main/java/com/yinuo/library/vlc/encoder/MediaCodecManager.java
@@ -5,8 +5,10 @@ import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaFormat;
 import android.os.Build;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.HandlerThread;
+import android.util.Log;
 
 import androidx.annotation.NonNull;
 
@@ -15,7 +17,6 @@ import com.common.commonlib.utils.LogUtils;
 import org.easydarwin.PushHelper;
 
 import java.nio.ByteBuffer;
-import java.text.SimpleDateFormat;
 import java.util.concurrent.ArrayBlockingQueue;
 
 @TargetApi(Build.VERSION_CODES.M)
@@ -42,9 +43,6 @@ public class MediaCodecManager {
 
     private boolean isFlush = false;
 
-    private long lastPauseTime = -1;//上次暂停时间
-    private boolean isHasKeyFrame;
-
     private Handler mHandler;
 
     private int off_y = 50, off_x = 100;
@@ -182,14 +180,14 @@ public class MediaCodecManager {
         int videoH = rotation == 90 || rotation == 270 ? dstWidth : dstHeight;
         mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE,//注意这里旋转后有一个大坑,就是要交换mHeight,和mWidth的位置。否则录制出来的视频时花屏的。
                 videoW, videoH);
-        int frameRate = 25; // 15fps
+        int frameRate = 24; // 15fps
         int compressRatio = 256;
         int bitRate = dstWidth * dstHeight * 3 * 8 * frameRate / compressRatio;
 
         mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
         mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
         mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, mColorFormat);
-        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
+        mediaFormat.setFloat(MediaFormat.KEY_I_FRAME_INTERVAL, 5f);
         LogUtils.w("prepare format: " + mediaFormat);
     }
 
@@ -197,7 +195,6 @@ public class MediaCodecManager {
     public static final int NAL_VPS = 32;
 
     private byte[] vps_sps_pps_buf;
-    byte[] outData;
 
     private void start() {
         if (!isInitCodec)
@@ -244,45 +241,39 @@ public class MediaCodecManager {
 
                 @Override
                 public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {
+                    buildKeyFrame();
                     ByteBuffer outputBuffer = codec.getOutputBuffer(index);
-                    if (!isHasKeyFrame && info.flags == MediaCodec.BUFFER_FLAG_KEY_FRAME) {
-                        isHasKeyFrame = true;
-                    }
-                    if (outData == null) {
-                        outData = new byte[info.size];
-                    }
-                    if (outputBuffer == null)
+                    if (outputBuffer == null) {
                         return;
-                    else if (info.presentationTimeUs < lastPauseTime || !isHasKeyFrame) {//上一视频的数据,或者无关键帧,丢弃
-                        //视频第一帧一定要是关键帧
-                        outputBuffer.get(outData);
                     } else if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                         LogUtils.w(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
                     } else {
                         outputBuffer.position(info.offset);
                         outputBuffer.limit(info.offset + info.size);
-                        if (androidMuxer != null) {
+                        if (androidMuxer != null && mTrackIndex != -1) {
                             androidMuxer.writeSampleData(mTrackIndex, outputBuffer, info);
                         }
+                        byte[] outData = new byte[info.size];
+                        outputBuffer.get(outData);
                         int offset = 4;
                         if (outData[2] == 0x01) {
                             offset = 3;
                         }
                         int type = (outData[offset] & 0x7E) >> 1;
+                        Log.i("cyy", "type = " + type);
                         if (type == NAL_VPS) {
                             vps_sps_pps_buf = outData;
-                            PushHelper.INSTANCE.pushData(outData, outData.length, info.presentationTimeUs / 1000);
-                        } else if (type == NAL_I) {
-                            if (vps_sps_pps_buf != null) {
+                        } else {
+                            if (type == NAL_I && vps_sps_pps_buf != null) {
                                 byte[] newBuf = new byte[vps_sps_pps_buf.length + outData.length];
                                 System.arraycopy(vps_sps_pps_buf, 0, newBuf, 0, vps_sps_pps_buf.length);
                                 System.arraycopy(outData, 0, newBuf, vps_sps_pps_buf.length, outData.length);
                                 outData = newBuf;
-                                PushHelper.INSTANCE.pushData(outData, outData.length, info.presentationTimeUs / 1000);
                             }
                         }
+                        PushHelper.INSTANCE.pushData(outData, outData.length, info.presentationTimeUs / 1000);
+                        codec.releaseOutputBuffer(index, false);
                     }
-                    codec.releaseOutputBuffer(index, false);
                     try {
                         Thread.sleep(0);
                     } catch (InterruptedException e) {
@@ -313,6 +304,17 @@ public class MediaCodecManager {
         isStart = true;
     }
 
+    long timeStamp = -1L;
+
+    void buildKeyFrame() {
+        if (System.currentTimeMillis() - timeStamp >= 5000) {//1000毫秒后,设置参数
+            timeStamp = System.currentTimeMillis();
+            Bundle params = new Bundle();
+            params.putInt(MediaCodec.PARAMETER_KEY_REQUEST_SYNC_FRAME, 0);
+            mMediaCodec.setParameters(params);
+        }
+    }
+
     /**
      * 返回到接收数据状态
      */
@@ -320,9 +322,9 @@ public class MediaCodecManager {
         LogUtils.w(TAG, "flushMediaCodec");
         frameBytes.clear();
         isFlush = true;
-        lastPauseTime = (System.nanoTime()) / 1000;//记录
-
-        isHasKeyFrame = false;
+//        lastPauseTime = (System.nanoTime()) / 1000;//记录
+//
+//        isHasKeyFrame = false;
 
     }
 
@@ -339,7 +341,7 @@ public class MediaCodecManager {
             }
             isStart = false;
             isPause = true;
-            isHasKeyFrame = false;
+//            isHasKeyFrame = false;
             LogUtils.w(TAG, "stopMediaCodec video");
         });
     }
diff --git a/library-push/src/main/java/org/easydarwin/PushHelper.kt b/library-push/src/main/java/org/easydarwin/PushHelper.kt
index 59af174..b7cb340 100644
--- a/library-push/src/main/java/org/easydarwin/PushHelper.kt
+++ b/library-push/src/main/java/org/easydarwin/PushHelper.kt
@@ -22,8 +22,14 @@ object PushHelper {
 
     private var mInitialized = false
 
+    private var switchOpen = true
+
+    fun opSwitch(open: Boolean) {
+        switchOpen = open
+    }
+
     var callback = InitCallback { code ->
-        var msg = ""
+        var msg = "$code"
         when (code) {
             EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_INVALID_KEY -> msg = "无效Key"
             EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_SUCCESS -> msg = "未开始"
@@ -50,14 +56,16 @@ object PushHelper {
         mIp = mUri.host
         mPort = mUri.port.toString()
         mId = mUri.path
-        if (mId?.startsWith("/")!!){
+        if (mId?.startsWith("/")!!) {
             mId = mId!!.substring(1)
         }
     }
 
     fun startStream(hevc: Boolean) {
-        stop()
-        initHelper(hevc)
+        if (switchOpen) {
+            stop()
+            initHelper(hevc)
+        }
     }
 
     fun stop() {