|  | @@ -1,13 +1,23 @@
 | 
	
		
			
				|  |  |  package com.ym.mec.teacher.handler;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import be.tarsos.dsp.AudioDispatcher;
 | 
	
		
			
				|  |  | +import be.tarsos.dsp.io.jvm.AudioDispatcherFactory;
 | 
	
		
			
				|  |  | +import be.tarsos.dsp.pitch.PitchProcessor;
 | 
	
		
			
				|  |  | +import com.alibaba.fastjson.JSON;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.dto.AudioRecordConfig;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.dto.MusicPitchDetailDto;
 | 
	
		
			
				|  |  |  import com.ym.mec.biz.dal.dto.WavHeader;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.dal.dto.WebSocketInfo;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.service.SoundService;
 | 
	
		
			
				|  |  | +import com.ym.mec.biz.service.SoundSocketService;
 | 
	
		
			
				|  |  |  import org.slf4j.Logger;
 | 
	
		
			
				|  |  |  import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  |  import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.web.socket.*;
 | 
	
		
			
				|  |  |  import org.springframework.web.socket.handler.AbstractWebSocketHandler;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +import javax.sound.sampled.AudioFormat;
 | 
	
		
			
				|  |  | +import javax.sound.sampled.AudioSystem;
 | 
	
		
			
				|  |  |  import java.io.*;
 | 
	
		
			
				|  |  |  import java.util.Map;
 | 
	
		
			
				|  |  |  import java.util.concurrent.ConcurrentHashMap;
 | 
	
	
		
			
				|  | @@ -23,8 +33,11 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public static final Map<String, WebSocketSession> WS_CLIENTS = new ConcurrentHashMap<>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private static File file;
 | 
	
		
			
				|  |  | -    private static FileOutputStream fos;
 | 
	
		
			
				|  |  | +    AudioFormat audioFormat = new AudioFormat(44100, 16, 1, true, false);
 | 
	
		
			
				|  |  | +    PitchProcessor.PitchEstimationAlgorithm algo = PitchProcessor.PitchEstimationAlgorithm.FFT_YIN;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private Map<String, RandomAccessFile> userRandomAccessFileMap = new ConcurrentHashMap<>();
 | 
	
		
			
				|  |  | +    private Map<String, MusicPitchDetailDto> userXmlInfoMap = new ConcurrentHashMap<>();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      public WebSocketHandler() {
 | 
	
		
			
				|  |  |          super();
 | 
	
	
		
			
				|  | @@ -36,32 +49,53 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 | 
	
		
			
				|  |  |          LOGGER.info("{}上线", phone);
 | 
	
		
			
				|  |  |          WS_CLIENTS.put(phone, session);
 | 
	
		
			
				|  |  |          super.afterConnectionEstablished(session);
 | 
	
		
			
				|  |  | -        file = new File("E:\\Temp\\record.wav");
 | 
	
		
			
				|  |  | -        fos = new FileOutputStream(file);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
 | 
	
		
			
				|  |  | -        String phone = session.getPrincipal().getName().split(":")[1];
 | 
	
		
			
				|  |  | -        LOGGER.info("{}: {}", phone, message.getPayload());
 | 
	
		
			
				|  |  |          super.handleMessage(session, message);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
 | 
	
		
			
				|  |  |          super.handleTextMessage(session, message);
 | 
	
		
			
				|  |  | +        String phone = session.getPrincipal().getName().split(":")[1];
 | 
	
		
			
				|  |  | +        LOGGER.info("{}: {}", phone, message.getPayload());
 | 
	
		
			
				|  |  | +        WebSocketInfo webSocketInfo = JSON.parseObject(message.getPayload(), WebSocketInfo.class);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        String commond = "";
 | 
	
		
			
				|  |  | +        if(webSocketInfo.getHeader().containsKey(SoundSocketService.COMMOND)){
 | 
	
		
			
				|  |  | +            commond = webSocketInfo.getHeader().get(SoundSocketService.COMMOND);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if(message.getPayload().contains("Start")){
 | 
	
		
			
				|  |  | +            File file = new File("E:\\Temp\\record"+phone+".wav");
 | 
	
		
			
				|  |  | +            userRandomAccessFileMap.put(phone, new RandomAccessFile(file, "rw"));
 | 
	
		
			
				|  |  | +        }else if(message.getPayload().contains("End")){
 | 
	
		
			
				|  |  | +            createHeader(phone);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
 | 
	
		
			
				|  |  |          super.handleBinaryMessage(session, message);
 | 
	
		
			
				|  |  | -        fos.write(message.getPayload().array());
 | 
	
		
			
				|  |  | +        String phone = session.getPrincipal().getName().split(":")[1];
 | 
	
		
			
				|  |  | +        if(userRandomAccessFileMap.containsKey(phone)){
 | 
	
		
			
				|  |  | +            userRandomAccessFileMap.get(phone).write(message.getPayload().array());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        AudioDispatcher dispatcher = AudioDispatcherFactory.fromByteArray(message.getPayload().array(), audioFormat, 256, 128);
 | 
	
		
			
				|  |  | +        dispatcher.addAudioProcessor(new PitchProcessor(algo, 44100, 256, (pitchDetectionResult, audioEvent) -> {
 | 
	
		
			
				|  |  | +            int timeStamp = (int) (audioEvent.getTimeStamp()*1000);
 | 
	
		
			
				|  |  | +            float pitch = pitchDetectionResult.getPitch();
 | 
	
		
			
				|  |  | +//            LOGGER.info("时间:{},频率:{}", timeStamp, pitch);
 | 
	
		
			
				|  |  | +        }));
 | 
	
		
			
				|  |  | +        dispatcher.run();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
 | 
	
		
			
				|  |  |          super.handlePongMessage(session, message);
 | 
	
		
			
				|  |  | -        LOGGER.debug("心跳信息:{}", new String(message.getPayload().array(), "utf-8"));
 | 
	
		
			
				|  |  | +        LOGGER.info("心跳信息:{}", new String(message.getPayload().array(), "utf-8"));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -72,7 +106,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 | 
	
		
			
				|  |  |          LOGGER.info("发生了错误,移除客户端: {}", phone);
 | 
	
		
			
				|  |  |          session.close();
 | 
	
		
			
				|  |  |          WS_CLIENTS.remove(phone);
 | 
	
		
			
				|  |  | -        createHeader();
 | 
	
		
			
				|  |  | +        createHeader(phone);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -81,7 +115,7 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 | 
	
		
			
				|  |  |          String phone = session.getPrincipal().getName().split(":")[1];
 | 
	
		
			
				|  |  |          LOGGER.info("{}离线", phone);
 | 
	
		
			
				|  |  |          WS_CLIENTS.remove(phone);
 | 
	
		
			
				|  |  | -        createHeader();
 | 
	
		
			
				|  |  | +        createHeader(phone);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -89,16 +123,14 @@ public class WebSocketHandler extends AbstractWebSocketHandler {
 | 
	
		
			
				|  |  |          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);
 | 
	
		
			
				|  |  | +    private void createHeader(String phone) throws IOException {
 | 
	
		
			
				|  |  | +        if(!userRandomAccessFileMap.containsKey(phone)){
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +        RandomAccessFile randomAccessFile = userRandomAccessFileMap.get(phone);
 | 
	
		
			
				|  |  |          randomAccessFile.seek(0);
 | 
	
		
			
				|  |  | -        randomAccessFile.write(new WavHeader(new AudioRecordConfig(), file.length()).toBytes());
 | 
	
		
			
				|  |  | +        randomAccessFile.write(new WavHeader(new AudioRecordConfig(), randomAccessFile.length()).toBytes());
 | 
	
		
			
				|  |  |          randomAccessFile.close();
 | 
	
		
			
				|  |  | +        userRandomAccessFileMap.remove(phone);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |