浏览代码

feat:小节评分

Joburgess 4 年之前
父节点
当前提交
76ed02af96

+ 87 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/AudioRecordConfig.java

@@ -0,0 +1,87 @@
+package com.ym.mec.biz.dal.dto;
+
+/**
+ * 录音参数配置
+ *
+ * @author maple
+ * @time 2018/4/10.
+ */
+public class AudioRecordConfig {
+    /**
+     * 音频源
+     */
+    private int audioSource = 1;
+
+    /**
+     * 采样率 赫兹
+     * 44100Hz 所有设备均可用
+     * 22050Hz  16000Hz  11025Hz
+     */
+    private int sampleRateInHz = 44100;
+
+    private int channelConfig = 0x10;
+
+    /**
+     * 音频数据格式
+     */
+    private int audioFormat = 2;
+
+
+    public AudioRecordConfig() {
+    }
+
+    public AudioRecordConfig(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat) {
+        this.audioSource = audioSource;
+        this.sampleRateInHz = sampleRateInHz;
+        this.channelConfig = channelConfig;
+        this.audioFormat = audioFormat;
+    }
+
+    public byte bitsPerSample() {
+        return 16;
+    }
+
+    // -------------------------- get/set ----------------------------------
+
+    public int getChannelConfig() {
+        return channelConfig;
+    }
+
+    public void setChannelConfig(int channelConfig) {
+        this.channelConfig = channelConfig;
+    }
+
+    public int getAudioSource() {
+        return audioSource;
+    }
+
+    public void setAudioSource(int audioSource) {
+        this.audioSource = audioSource;
+    }
+
+    public int getSampleRateInHz() {
+        return sampleRateInHz;
+    }
+
+    public void setSampleRateInHz(int sampleRateInHz) {
+        this.sampleRateInHz = sampleRateInHz;
+    }
+
+    public int getAudioFormat() {
+        return audioFormat;
+    }
+
+    public void setAudioFormat(int audioFormat) {
+        this.audioFormat = audioFormat;
+    }
+
+    @Override
+    public String toString() {
+        return "录音参数配置: \n{" +
+                "audioSource=" + audioSource +
+                ", sampleRateInHz=" + sampleRateInHz +
+                ", channelConfig=" + channelConfig +
+                ", audioFormat=" + audioFormat +
+                '}';
+    }
+}

+ 96 - 0
mec-biz/src/main/java/com/ym/mec/biz/dal/dto/WavHeader.java

@@ -0,0 +1,96 @@
+package com.ym.mec.biz.dal.dto;
+
+/**
+ * WAV文件头工具类
+ *
+ * @author maple
+ * @time 2018/4/10.
+ */
+public class WavHeader {
+    private AudioRecordConfig config;// wav录音配置参数
+    private long totalAudioLength;// 音频数据总长度
+
+    public WavHeader(AudioRecordConfig config, long totalAudioLength) {
+        this.config = config;
+        this.totalAudioLength = totalAudioLength;
+    }
+
+    /**
+     * 返回WAV文件头的byte数组
+     */
+    public byte[] toBytes() {
+        long sampleRateInHz = config.getSampleRateInHz();
+        int channels = 1;
+        byte bitsPerSample = config.bitsPerSample();
+        return wavFileHeader(
+                totalAudioLength - 44,
+                totalAudioLength - 44 + 36,
+                sampleRateInHz,
+                channels,
+                bitsPerSample * sampleRateInHz * channels / 8,
+                bitsPerSample
+        );
+    }
+
+    /**
+     * 获取wav文件头
+     *
+     * @param totalAudioLen  -
+     * @param totalDataLen   -
+     * @param longSampleRate - 采样率
+     * @param channels       - 通道数
+     * @param byteRate       -
+     * @param bitsPerSample  - 16/8 bit
+     * @return
+     */
+    private byte[] wavFileHeader(long totalAudioLen, long totalDataLen, long longSampleRate,
+                                 int channels, long byteRate, byte bitsPerSample) {
+        byte[] header = new byte[44];
+        header[0] = 'R'; // RIFF/WAVE header
+        header[1] = 'I';
+        header[2] = 'F';
+        header[3] = 'F';
+        header[4] = (byte) (totalDataLen & 0xff);
+        header[5] = (byte) ((totalDataLen >> 8) & 0xff);
+        header[6] = (byte) ((totalDataLen >> 16) & 0xff);
+        header[7] = (byte) ((totalDataLen >> 24) & 0xff);
+        header[8] = 'W';
+        header[9] = 'A';
+        header[10] = 'V';
+        header[11] = 'E';
+        header[12] = 'f'; // 'fmt ' chunk
+        header[13] = 'm';
+        header[14] = 't';
+        header[15] = ' ';
+        header[16] = 16; // 4 bytes: size of 'fmt ' chunk
+        header[17] = 0;
+        header[18] = 0;
+        header[19] = 0;
+        header[20] = 1; // format = 1
+        header[21] = 0;
+        header[22] = (byte) channels;
+        header[23] = 0;
+        header[24] = (byte) (longSampleRate & 0xff);
+        header[25] = (byte) ((longSampleRate >> 8) & 0xff);
+        header[26] = (byte) ((longSampleRate >> 16) & 0xff);
+        header[27] = (byte) ((longSampleRate >> 24) & 0xff);
+        header[28] = (byte) (byteRate & 0xff);
+        header[29] = (byte) ((byteRate >> 8) & 0xff);
+        header[30] = (byte) ((byteRate >> 16) & 0xff);
+        header[31] = (byte) ((byteRate >> 24) & 0xff);
+        header[32] = (byte) (channels * (bitsPerSample / 8)); //
+        // block align
+        header[33] = 0;
+        header[34] = bitsPerSample; // bits per sample
+        header[35] = 0;
+        header[36] = 'd';
+        header[37] = 'a';
+        header[38] = 't';
+        header[39] = 'a';
+        header[40] = (byte) (totalAudioLen & 0xff);
+        header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
+        header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
+        header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
+        return header;
+    }
+}

+ 17 - 2
mec-teacher/src/main/java/com/ym/mec/teacher/handler/WebSocketHandler.java

@@ -1,5 +1,7 @@
 package com.ym.mec.teacher.handler;
 
+import com.ym.mec.biz.dal.dto.AudioRecordConfig;
+import com.ym.mec.biz.dal.dto.WavHeader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -68,7 +70,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
         session.close();
         String phone = session.getPrincipal().getName().split(":")[1];
         WS_CLIENTS.remove(phone);
-        fos.close();
+        createHeader();
     }
 
     @Override
@@ -77,11 +79,24 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
         String phone = session.getPrincipal().getName().split(":")[1];
         LOGGER.info("{}离线", phone);
         WS_CLIENTS.remove(phone);
-        fos.close();
+        createHeader();
     }
 
     @Override
     public boolean supportsPartialMessages() {
         return super.supportsPartialMessages();
     }
+
+    private void createHeader() throws IOException {
+        fos.close();
+        RandomAccessFile randomAccessFile;
+        try {
+            randomAccessFile = new RandomAccessFile(file, "rw");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+        randomAccessFile.seek(0);
+        randomAccessFile.write(new WavHeader(new AudioRecordConfig(), file.length()).toBytes());
+        randomAccessFile.close();
+    }
 }