From 2dafb5ad3d76a2c03d848226975e769025d3a4ed Mon Sep 17 00:00:00 2001 From: archurtan Date: Fri, 8 Oct 2021 11:21:50 +0800 Subject: [PATCH] =?UTF-8?q?=E9=9F=B3=E9=A2=91=E9=87=87=E9=9B=86=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E7=B1=BB=E6=9A=B4=E9=9C=B2=E9=87=87=E6=A0=B7=E7=8E=87?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If88136cd04af5df53cd5b767bdd3575fa11eb0c1 (cherry picked from commit 89899f50f48c4468dd1865ad19244e5f602c9cd8) --- .../link/util/audio/AudioRecordUtil.java | 22 ++++++-------- .../iot/video/link/util/audio/FLVPacker.java | 5 ++-- .../iot/video/link/util/audio/PCMEncoder.java | 30 +++++++++++++++---- .../video/preview/VideoPreviewActivity.kt | 2 +- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/AudioRecordUtil.java b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/AudioRecordUtil.java index 12698499a..2c6186767 100644 --- a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/AudioRecordUtil.java +++ b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/AudioRecordUtil.java @@ -8,15 +8,9 @@ public class AudioRecordUtil implements EncoderListener { - - //设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025 - private int sampleRateInHz = 16000; - //设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道 - private int channelConfig = AudioFormat.CHANNEL_IN_STEREO; - //音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。 - private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; - //录制状态 - private volatile boolean recorderState = true; + private int channelConfig = AudioFormat.CHANNEL_IN_STEREO; //设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道 + private int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。 + private volatile boolean recorderState = true; //录制状态 private byte[] buffer; private AudioRecord audioRecord; private volatile PCMEncoder pcmEncoder; @@ -24,14 +18,14 @@ public class AudioRecordUtil implements EncoderListener { private Context context; private String deviceId; //"productId/deviceName" private int recordMinBufferSize; - private int sampleRate; + private int sampleRate; //音频采样率 private int channel; private int bitDepth; - public AudioRecordUtil(Context ctx, String id) { + public AudioRecordUtil(Context ctx, String id, int sampleRate) { context = ctx; deviceId = id; - init(sampleRateInHz, channelConfig, audioFormat); + init(sampleRate, channelConfig, audioFormat); } public AudioRecordUtil(Context ctx, int sampleRate, int channel, int bitDepth) { context = ctx; @@ -58,7 +52,7 @@ public void start() { private void reset() { buffer = new byte[recordMinBufferSize]; audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, channel, bitDepth, recordMinBufferSize); - pcmEncoder = new PCMEncoder(sampleRateInHz, this, PCMEncoder.AAC_FORMAT); + pcmEncoder = new PCMEncoder(sampleRate, this, PCMEncoder.AAC_FORMAT); flvPacker = new FLVPacker(); } @@ -69,6 +63,8 @@ public void stop() { recorderState = false; audioRecord.stop(); audioRecord = null; + pcmEncoder = null; + flvPacker = null; } public void release() { diff --git a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/FLVPacker.java b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/FLVPacker.java index 3024597a2..274e5923a 100644 --- a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/FLVPacker.java +++ b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/FLVPacker.java @@ -7,7 +7,6 @@ public class FLVPacker { private long pts = 0; - private long sudioPts = 0; private volatile boolean isHead = false; public synchronized byte[] getFLV(byte[] data) { @@ -32,13 +31,13 @@ public synchronized byte[] aacToFlv(byte[] date) { baos.write(0x08); // 长度 baos.write(integerTo3Bytes(data.length + 2)); - if (sudioPts == 0) { + if (pts == 0) { // 时间戳 baos.write(0x00); baos.write(0x00); baos.write(0x00); baos.write(0x00); - sudioPts = System.currentTimeMillis(); + pts = System.currentTimeMillis(); } else { byte[] b = integerTo4Bytes((int) (System.currentTimeMillis() - pts)); baos.write(b[1]); diff --git a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/PCMEncoder.java b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/PCMEncoder.java index d81d2cba4..976ce12c0 100644 --- a/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/PCMEncoder.java +++ b/sdk/video-link-android/src/main/java/com/tencent/iot/video/link/util/audio/PCMEncoder.java @@ -6,6 +6,8 @@ import java.io.IOException; import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; public class PCMEncoder { @@ -23,19 +25,37 @@ public class PCMEncoder { private MediaCodec.BufferInfo encodeBufferInfo; private EncoderListener encoderListener; private int encodeType = 0; + private int sampleRate = 0; + + // 采样频率对照表 + private static Map samplingFrequencyIndexMap = new HashMap<>(); + + static { + samplingFrequencyIndexMap.put(96000, 0); + samplingFrequencyIndexMap.put(88200, 1); + samplingFrequencyIndexMap.put(64000, 2); + samplingFrequencyIndexMap.put(48000, 3); + samplingFrequencyIndexMap.put(44100, 4); + samplingFrequencyIndexMap.put(32000, 5); + samplingFrequencyIndexMap.put(24000, 6); + samplingFrequencyIndexMap.put(22050, 7); + samplingFrequencyIndexMap.put(16000, 8); + samplingFrequencyIndexMap.put(12000, 9); + samplingFrequencyIndexMap.put(11025, 10); + samplingFrequencyIndexMap.put(8000, 11); + } public PCMEncoder(int sampleRate, EncoderListener encoderListener, int encodeFormat) { this.encoderListener = encoderListener; this.encodeType = encodeFormat; - init(sampleRate); + this.sampleRate = sampleRate; + init(); } /** * 初始化AAC编码器 - * - * @param sampleRate 采样率 */ - private void init(int sampleRate) { + private void init() { try { //参数对应-> mime type、采样率、声道数 MediaFormat encodeFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, @@ -110,8 +130,8 @@ public void encodeData(byte[] data) { */ private void addADTStoPacket(byte[] packet, int packetLen) { int profile = 2; // AAC LC - int freqIdx = 8; // 44.1KHz int chanCfg = 2; // CPE + int freqIdx = samplingFrequencyIndexMap.get(sampleRate); // filled in ADTS data packet[0] = (byte) 0xFF; packet[1] = (byte) 0xF9; diff --git a/sdkdemo/src/main/java/com/tencent/iot/explorer/link/demo/video/preview/VideoPreviewActivity.kt b/sdkdemo/src/main/java/com/tencent/iot/explorer/link/demo/video/preview/VideoPreviewActivity.kt index d455a722f..c35327f91 100644 --- a/sdkdemo/src/main/java/com/tencent/iot/explorer/link/demo/video/preview/VideoPreviewActivity.kt +++ b/sdkdemo/src/main/java/com/tencent/iot/explorer/link/demo/video/preview/VideoPreviewActivity.kt @@ -120,7 +120,7 @@ class VideoPreviewActivity : VideoBaseActivity(), EventView, TextureView.Surface tv_event_status.setText(R.string.loading) XP2P.setQcloudApiCred(it.accessId, it.accessToken) XP2P.setCallback(this) - audioRecordUtil = AudioRecordUtil(this, "${it.productId}/${presenter.getDeviceName()}") + audioRecordUtil = AudioRecordUtil(this, "${it.productId}/${presenter.getDeviceName()}", 16000) } startPlayer()