|
@@ -0,0 +1,228 @@
|
|
|
+package com.yonge.netty.server.handler.message;
|
|
|
+
|
|
|
+import io.netty.channel.Channel;
|
|
|
+import io.netty.channel.ChannelHandler;
|
|
|
+import io.netty.channel.ChannelHandlerContext;
|
|
|
+import io.netty.channel.SimpleChannelInboundHandler;
|
|
|
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
|
|
|
+
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.util.Comparator;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Map.Entry;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.alibaba.fastjson.JSONPath;
|
|
|
+import com.ym.mec.biz.dal.entity.SysMusicCompareRecord;
|
|
|
+import com.ym.mec.biz.dal.enums.DeviceTypeEnum;
|
|
|
+import com.ym.mec.biz.dal.enums.FeatureType;
|
|
|
+import com.ym.mec.biz.service.SysMusicCompareRecordService;
|
|
|
+import com.ym.mec.thirdparty.storage.StoragePluginContext;
|
|
|
+import com.ym.mec.thirdparty.storage.provider.KS3StoragePlugin;
|
|
|
+import com.ym.mec.util.upload.UploadUtil;
|
|
|
+import com.yonge.nettty.dto.SectionAnalysis;
|
|
|
+import com.yonge.nettty.dto.UserChannelContext;
|
|
|
+import com.yonge.nettty.dto.WebSocketResponse;
|
|
|
+import com.yonge.nettty.entity.MusicXmlBasicInfo;
|
|
|
+import com.yonge.nettty.entity.MusicXmlNote;
|
|
|
+import com.yonge.netty.server.handler.ChannelContextConstants;
|
|
|
+import com.yonge.netty.server.handler.NettyChannelManager;
|
|
|
+import com.yonge.netty.server.processor.WaveformWriter;
|
|
|
+import com.yonge.netty.server.service.UserChannelContextService;
|
|
|
+
|
|
|
+@Component
|
|
|
+@ChannelHandler.Sharable
|
|
|
+public class TextWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
|
|
|
+
|
|
|
+ private static final Logger LOGGER = LoggerFactory.getLogger(TextWebSocketHandler.class);
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private SysMusicCompareRecordService sysMusicCompareRecordService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private StoragePluginContext storagePluginContext;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private UserChannelContextService userChannelContextService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private NettyChannelManager nettyChannelManager;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {
|
|
|
+
|
|
|
+ Channel channel = ctx.channel();
|
|
|
+
|
|
|
+ String jsonMsg = frame.text();
|
|
|
+
|
|
|
+ LOGGER.info("接收到客户端的消息内容:{}", jsonMsg);
|
|
|
+
|
|
|
+ String type = (String) JSONPath.extract(jsonMsg, "$.header.type");
|
|
|
+
|
|
|
+ if(StringUtils.isNoneBlank(type)){
|
|
|
+ channel.attr(ChannelContextConstants.CHANNEL_ATTR_KEY_ACTION).set(type);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.equals(type, "PITCH_DETECTION")) {// 校音
|
|
|
+
|
|
|
+ return;
|
|
|
+ } else if (StringUtils.equals(type, "SOUND_COMPARE")) {// 评测
|
|
|
+ String command = (String) JSONPath.extract(jsonMsg, "$.header.commond");
|
|
|
+
|
|
|
+ JSONObject dataObj = (JSONObject) JSONPath.extract(jsonMsg, "$.body");
|
|
|
+
|
|
|
+ UserChannelContext channelContext = userChannelContextService.getChannelContext(channel);
|
|
|
+
|
|
|
+ MusicXmlBasicInfo musicXmlBasicInfo = null;
|
|
|
+
|
|
|
+ switch (command) {
|
|
|
+ case "musicXml": // 同步music xml信息
|
|
|
+
|
|
|
+ musicXmlBasicInfo = JSONObject.toJavaObject(dataObj, MusicXmlBasicInfo.class);
|
|
|
+
|
|
|
+ userChannelContextService.remove(channel);
|
|
|
+
|
|
|
+ if (channelContext == null) {
|
|
|
+ channelContext = new UserChannelContext();
|
|
|
+ }
|
|
|
+
|
|
|
+ channelContext.getSongMusicXmlMap().put(musicXmlBasicInfo.getExamSongId(), musicXmlBasicInfo);
|
|
|
+ channelContext.init(musicXmlBasicInfo.getHeardLevel(), musicXmlBasicInfo.getSubjectId(), musicXmlBasicInfo.getBeatLength());
|
|
|
+
|
|
|
+ userChannelContextService.register(channel, channelContext);
|
|
|
+
|
|
|
+ break;
|
|
|
+ case "recordStart": // 开始评测
|
|
|
+
|
|
|
+ // 清空缓存信息
|
|
|
+ channelContext.resetUserInfo();
|
|
|
+
|
|
|
+ musicXmlBasicInfo = channelContext.getMusicXmlBasicInfo(null);
|
|
|
+
|
|
|
+ if (musicXmlBasicInfo != null) {
|
|
|
+ Date date = new Date();
|
|
|
+ SysMusicCompareRecord sysMusicCompareRecord = new SysMusicCompareRecord(FeatureType.CLOUD_STUDY_EVALUATION);
|
|
|
+ sysMusicCompareRecord.setCreateTime(date);
|
|
|
+ sysMusicCompareRecord.setUserId(Integer.parseInt(nettyChannelManager.getUser(channel)));
|
|
|
+ sysMusicCompareRecord.setSysMusicScoreId(musicXmlBasicInfo.getExamSongId());
|
|
|
+ sysMusicCompareRecord.setBehaviorId(musicXmlBasicInfo.getBehaviorId());
|
|
|
+ //sysMusicCompareRecord.setClientId();
|
|
|
+ sysMusicCompareRecord.setDeviceType(DeviceTypeEnum.valueOf(musicXmlBasicInfo.getPlatform()));
|
|
|
+ sysMusicCompareRecord.setSpeed(musicXmlBasicInfo.getSpeed());
|
|
|
+
|
|
|
+ MusicXmlNote musicXmlNote = musicXmlBasicInfo.getMusicXmlInfos().stream().max(Comparator.comparing(MusicXmlNote::getTimeStamp)).get();
|
|
|
+ sysMusicCompareRecord.setSourceTime((float) ((musicXmlNote.getTimeStamp()+musicXmlNote.getDuration())/1000));
|
|
|
+ sysMusicCompareRecordService.insert(sysMusicCompareRecord);
|
|
|
+ channelContext.setRecordId(sysMusicCompareRecord.getId());
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case "recordEnd": // 结束评测
|
|
|
+ case "recordCancel": // 取消评测
|
|
|
+ if (channelContext == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ WaveformWriter waveFileProcessor = channelContext.getWaveFileProcessor();
|
|
|
+ if (waveFileProcessor != null) {
|
|
|
+ // 写文件头
|
|
|
+ waveFileProcessor.processingFinished();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.equals(command, "recordEnd")) {
|
|
|
+ // 生成评测报告
|
|
|
+ Map<String, Object> params = new HashMap<String, Object>();
|
|
|
+
|
|
|
+ Map<String, Integer> scoreMap = channelContext.evaluateForMusic();
|
|
|
+ for (Entry<String, Integer> entry : scoreMap.entrySet()) {
|
|
|
+ params.put(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+
|
|
|
+ //保存评测结果
|
|
|
+ Long recordId = channelContext.getRecordId();
|
|
|
+ SysMusicCompareRecord sysMusicCompareRecord = sysMusicCompareRecordService.get(recordId);
|
|
|
+ if(sysMusicCompareRecord != null){
|
|
|
+ musicXmlBasicInfo = channelContext.getMusicXmlBasicInfo(null);
|
|
|
+
|
|
|
+ if (scoreMap != null && scoreMap.size() > 1) {
|
|
|
+ sysMusicCompareRecord.setScore(new BigDecimal(scoreMap.get("score")));
|
|
|
+ sysMusicCompareRecord.setIntonation(new BigDecimal(scoreMap.get("intonation")));
|
|
|
+ sysMusicCompareRecord.setIntegrity(new BigDecimal(scoreMap.get("integrity")));
|
|
|
+ sysMusicCompareRecord.setCadence(new BigDecimal(scoreMap.get("cadence")));
|
|
|
+ sysMusicCompareRecord.setPlayTime(scoreMap.get("playTime") / 1000);
|
|
|
+ }
|
|
|
+ sysMusicCompareRecord.setFeature(FeatureType.CLOUD_STUDY_EVALUATION);
|
|
|
+
|
|
|
+ String url = null;
|
|
|
+ try {
|
|
|
+ String folder = UploadUtil.getFileFloder();
|
|
|
+ url = storagePluginContext.asyncUploadFile(KS3StoragePlugin.PLUGIN_NAME,"soundCompare/" + folder, waveFileProcessor.getFile());
|
|
|
+ } catch (Exception e) {
|
|
|
+ LOGGER.error("录音文件上传失败:{}", e);
|
|
|
+ }
|
|
|
+ sysMusicCompareRecord.setRecordFilePath(url);
|
|
|
+ //sysMusicCompareRecord.setVideoFilePath(videoFilePath);
|
|
|
+
|
|
|
+ Map<String, Object> scoreData = new HashMap<>();
|
|
|
+ List<SectionAnalysis> sectionAnalysisList = channelContext.getDoneSectionAnalysisList();
|
|
|
+ sectionAnalysisList = sectionAnalysisList.stream().filter(t -> t.isIngore() == false).collect(Collectors.toList());
|
|
|
+ scoreData.put("userMeasureScore", sectionAnalysisList.stream().collect(Collectors.toMap(SectionAnalysis :: getIndex, t -> t)));
|
|
|
+
|
|
|
+ Map<String, Object> musicalNotesPlayStats = new HashMap<>();
|
|
|
+ musicalNotesPlayStats.put("detailId", musicXmlBasicInfo.getDetailId());
|
|
|
+ musicalNotesPlayStats.put("examSongId", musicXmlBasicInfo.getExamSongId());
|
|
|
+ musicalNotesPlayStats.put("xmlUrl", musicXmlBasicInfo.getXmlUrl());
|
|
|
+
|
|
|
+ musicalNotesPlayStats.put("notesData", channelContext.getDoneNoteAnalysisList().stream().filter(t -> t.isIgnore() == false).collect(Collectors.toList()));
|
|
|
+ scoreData.put("musicalNotesPlayStats", musicalNotesPlayStats);
|
|
|
+ sysMusicCompareRecord.setScoreData(JSON.toJSONString(scoreData));
|
|
|
+
|
|
|
+ sysMusicCompareRecordService.saveMusicCompareData(sysMusicCompareRecord);
|
|
|
+ }
|
|
|
+
|
|
|
+ WebSocketResponse<Map<String, Object>> resp = new WebSocketResponse<Map<String, Object>>("overall", params);
|
|
|
+
|
|
|
+ nettyChannelManager.sendTextMessage(nettyChannelManager.getUser(channel), resp);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清空缓存信息
|
|
|
+ channelContext.resetUserInfo();
|
|
|
+
|
|
|
+ break;
|
|
|
+ case "proxyMessage": // ???
|
|
|
+
|
|
|
+ break;
|
|
|
+ case "videoUpload": // 上传音频
|
|
|
+ SysMusicCompareRecord musicCompareRecord = null;
|
|
|
+ if (dataObj.containsKey("recordId")) {
|
|
|
+ musicCompareRecord = sysMusicCompareRecordService.get(dataObj.getLong("recordId"));
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(musicCompareRecord) && dataObj.containsKey("filePath")) {
|
|
|
+ musicCompareRecord.setVideoFilePath(dataObj.getString("filePath"));
|
|
|
+ sysMusicCompareRecordService.update(musicCompareRecord);
|
|
|
+ } else {
|
|
|
+ musicCompareRecord.setVideoFilePath(musicCompareRecord.getRecordFilePath());
|
|
|
+ sysMusicCompareRecordService.update(musicCompareRecord);
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ // 非法请求
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|