From d5eee6f9dbe88ec16f61d164f56b0da21afd9b8f Mon Sep 17 00:00:00 2001 From: xiaowusky Date: Thu, 15 Jun 2023 17:58:28 +0800 Subject: [PATCH] =?UTF-8?q?desc:=E5=BD=95=E5=88=B6=E5=8E=BB=E5=88=B0?= =?UTF-8?q?=E9=9F=B3=E9=A2=91=EF=BC=8C=E8=A7=86=E9=A2=91=E4=B8=8D=E4=BC=9A?= =?UTF-8?q?=E7=89=B9=E5=88=AB=E5=BF=AB=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yinuo/library/vlc/PushHelper.kt | 83 +++++++++++++++++++ .../yinuo/library/vlc/RtspSurfaceRender2.java | 16 ++-- .../java/com/yinuo/library/vlc/TxtOverlay.kt | 5 ++ .../library/vlc/encoder/AndroidMuxer.java | 2 +- .../library/vlc/encoder/AudioEncoderCore.java | 8 +- .../library/vlc/encoder/MediaEncoderCore.java | 37 ++++++++- .../library/vlc/encoder/VideoEncoderCore.java | 4 +- .../com/yinuo/library/vlc/utils/LogUtils.java | 2 +- 8 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 library-vlc/src/main/java/com/yinuo/library/vlc/PushHelper.kt diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/PushHelper.kt b/library-vlc/src/main/java/com/yinuo/library/vlc/PushHelper.kt new file mode 100644 index 0000000..686a99d --- /dev/null +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/PushHelper.kt @@ -0,0 +1,83 @@ +package com.yinuo.library.vlc + +import com.common.commonlib.CommonApplication +import com.yinuo.library.vlc.utils.LogUtils +import org.easydarwin.push.EasyPusher +import org.easydarwin.push.InitCallback +import org.easydarwin.push.Pusher + +object PushHelper { + + private val mPusher: EasyPusher by lazy { + EasyPusher() + } + + private val mApplicationContext = CommonApplication.getContext() + + private var mHeight: Int = 0 + private var mWidth: Int = 0 + + init { + setPushUrl("") + } + + var callback = InitCallback { code -> + var msg = "" + when (code) { + EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_INVALID_KEY -> msg = "无效Key" + EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_SUCCESS -> msg = "未开始" + EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECTING -> msg = "连接中" + EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECTED -> msg = "连接成功" + EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECT_FAILED -> msg = "连接失败" + EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_CONNECT_ABORT -> msg = + "连接异常中断" + + EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_PUSHING -> msg = "推流中" + EasyPusher.OnInitPusherCallback.CODE.EASY_PUSH_STATE_DISCONNECTED -> msg = "断开连接" + EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_PLATFORM_ERR -> msg = "平台不匹配" + EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_COMPANY_ID_LEN_ERR -> msg = + "授权使用商不匹配" + + EasyPusher.OnInitPusherCallback.CODE.EASY_ACTIVATE_PROCESS_NAME_LEN_ERR -> msg = + "进程名称长度不匹配" + } + LogUtils.v("PushHelper. InitCallback $msg") + } + + fun configSize(width: Int, height: Int) { + this.mWidth = width + this.mHeight = height + } + + fun setPushUrl(url: String) { + initHelper("192.168.5.16", "554", "123") + } + + fun stop() { + mPusher.stop() + } + + fun pushData(h264: ByteArray, length: Int, timeStamp: Long) { + mPusher.push(h264, 0, length, timeStamp, 1) + } + + private fun initHelper(ip: String, port: String, id: String) { + mPusher.initPush(mApplicationContext, callback) + mPusher.setMediaInfo( + Pusher.Codec.EASY_SDK_VIDEO_CODEC_H264, + 24, + Pusher.Codec.EASY_SDK_AUDIO_CODEC_AAC, + 1, + 8000, + 16 + ) + mPusher.start(ip, port, String.format("%s.sdp", id), Pusher.TransType.EASY_RTP_OVER_TCP) + } + + + @JvmField + var mPpsSps = ByteArray(0) + + @JvmField + var h264 = ByteArray(1920 * 1080) +} \ No newline at end of file diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/RtspSurfaceRender2.java b/library-vlc/src/main/java/com/yinuo/library/vlc/RtspSurfaceRender2.java index 4285474..b87e504 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/RtspSurfaceRender2.java +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/RtspSurfaceRender2.java @@ -75,6 +75,7 @@ public class RtspSurfaceRender2 implements RtspHelper.RtspCallback { mVideoBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); RtspHelper.getInstance().createPlayer(mRtspUrl, width, height, RtspSurfaceRender2.this); renderThread.start(); + PushHelper.INSTANCE.configSize(width, height); } } @@ -116,15 +117,14 @@ public class RtspSurfaceRender2 implements RtspHelper.RtspCallback { @Override public void onPreviewFrame(final ByteBuffer buffer, int width, int height) { synchronized (mBitmapLock) { - Bitmap overLayBitmap = TxtOverlay.INSTANCE.buildOverlayBitmap(); + Bitmap overLayBitmap = TxtOverlay.INSTANCE.getOverlayBitmap(); mVideoBitmap.copyPixelsFromBuffer(buffer.position(0)); - mVideoBitmap = BitmapUtil.mergeBitmap(mVideoBitmap, overLayBitmap); - buffer.clear(); - mVideoBitmap.copyPixelsToBuffer(buffer); - } - - if (mRecording) { - mSurfaceView.post(() -> mVideoEncoder.frameAvailable(buffer.array(), System.nanoTime())); + if (overLayBitmap != null) { + mVideoBitmap = BitmapUtil.mergeBitmap(mVideoBitmap, overLayBitmap); + buffer.clear(); + mVideoBitmap.copyPixelsToBuffer(buffer); + } + mVideoEncoder.frameAvailable(buffer.array(), System.nanoTime()); } } diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt b/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt index 5fb62a9..5270f5f 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/TxtOverlay.kt @@ -19,6 +19,7 @@ object TxtOverlay { // 外部调用,设置待显示水印文字 fun setShowTip(string: String) { mToDoShowTip = string + buildOverlayBitmap() } // 上一次展示的时间 @@ -49,4 +50,8 @@ object TxtOverlay { } return bmp } + + fun getOverlayBitmap(): Bitmap? { + return bmp; + } } \ No newline at end of file diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AndroidMuxer.java b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AndroidMuxer.java index 756c2d4..220b4fd 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AndroidMuxer.java +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AndroidMuxer.java @@ -13,7 +13,7 @@ import java.nio.ByteBuffer; public class AndroidMuxer { - private final int mExpectedNumTracks = 2; + private final int mExpectedNumTracks = 1; private MediaMuxer mMuxer; diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java index 3e5d30b..0bc6805 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/AudioEncoderCore.java @@ -122,14 +122,14 @@ public class AudioEncoderCore extends MediaEncoderCore implements Runnable { @Override public void run() { while (mRecording) { - drainEncoder(false); - drainAudio(false); +// drainEncoder(false); +// drainAudio(false); } - drainAudio(true); +// drainAudio(true); mAudioRecord.stop(); - drainEncoder(true); +// drainEncoder(true); release(); } diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/MediaEncoderCore.java b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/MediaEncoderCore.java index 63e9e95..ec3be0d 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/MediaEncoderCore.java +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/MediaEncoderCore.java @@ -4,8 +4,11 @@ import android.media.MediaCodec; import android.media.MediaFormat; import android.util.Log; +import com.yinuo.library.vlc.PushHelper; import com.yinuo.library.vlc.utils.LogUtils; +import org.easydarwin.easypusher.BuildConfig; + import java.nio.ByteBuffer; /** @@ -16,7 +19,7 @@ public abstract class MediaEncoderCore { protected final String TAG = getClass().getSimpleName(); - protected static final boolean VERBOSE = false; + protected static final boolean VERBOSE = true; protected AndroidMuxer mMuxer; @@ -114,6 +117,38 @@ public abstract class MediaEncoderCore { } } + // add + boolean sync = false; + if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {// sps + sync = (mBufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0; + if (!sync) { + byte[] temp = new byte[mBufferInfo.size]; + encodedData.get(temp); + PushHelper.mPpsSps = temp; + mEncoder.releaseOutputBuffer(encoderStatus, false); + continue; + } else { + PushHelper.mPpsSps = new byte[0]; + } + } + sync |= (mBufferInfo.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) != 0; + int len = PushHelper.mPpsSps.length + mBufferInfo.size; + if (len > PushHelper.h264.length) { + PushHelper.h264 = new byte[len]; + } + if (sync) { + System.arraycopy(PushHelper.mPpsSps, 0, PushHelper.h264, 0, PushHelper.mPpsSps.length); + encodedData.get(PushHelper.h264, PushHelper.mPpsSps.length, mBufferInfo.size); + PushHelper.INSTANCE.pushData(PushHelper.h264, PushHelper.mPpsSps.length + mBufferInfo.size, mBufferInfo.presentationTimeUs / 1000); + if (BuildConfig.DEBUG) + Log.i(TAG, String.format("push i video stamp:%d", mBufferInfo.presentationTimeUs / 1000)); + } else { + encodedData.get(PushHelper.h264, 0, mBufferInfo.size); + PushHelper.INSTANCE.pushData(PushHelper.h264, mBufferInfo.size, mBufferInfo.presentationTimeUs / 1000); + if (BuildConfig.DEBUG) + Log.i(TAG, String.format("push video stamp:%d", mBufferInfo.presentationTimeUs / 1000)); + } + mEncoder.releaseOutputBuffer(encoderStatus, false); if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) { diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCore.java b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCore.java index abdf5b3..766a980 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCore.java +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/encoder/VideoEncoderCore.java @@ -38,8 +38,8 @@ public class VideoEncoderCore extends MediaEncoderCore { // TODO: these ought to be configurable as well private static final String MIME_TYPE = "video/avc"; // H.264 Advanced Video Coding - private static final int FRAME_RATE = 30; // 30fps - private static final int IFRAME_INTERVAL = 5; // 5 seconds between I-frames + private static final int FRAME_RATE = 24; // 30fps + private static final int IFRAME_INTERVAL = 1; // 5 seconds between I-frames private static final int BIT_RATE = 4000000; private Surface mInputSurface; diff --git a/library-vlc/src/main/java/com/yinuo/library/vlc/utils/LogUtils.java b/library-vlc/src/main/java/com/yinuo/library/vlc/utils/LogUtils.java index 2f57f81..f41cb6f 100644 --- a/library-vlc/src/main/java/com/yinuo/library/vlc/utils/LogUtils.java +++ b/library-vlc/src/main/java/com/yinuo/library/vlc/utils/LogUtils.java @@ -12,7 +12,7 @@ import java.io.Writer; public class LogUtils { - private static final String TAG = "bush"; + private static final String TAG = "watcher"; public static void v(String msg) { Log.v(TAG, msg);