package com.ym.controller; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.microsvc.toolkit.middleware.live.LivePluginContext; import com.microsvc.toolkit.middleware.live.LivePluginService; import com.microsvc.toolkit.middleware.live.impl.TencentCloudLivePlugin; import com.ym.common.BaseResponse; import com.ym.mec.biz.dal.dto.TencentData; import com.ym.mec.biz.dal.dto.TencentImCallbackResult; import com.ym.mec.biz.dal.enums.ETencentImCallbackCommand; import com.ym.mec.biz.service.ImLiveBroadcastRoomService; import com.ym.mec.common.entity.ImUserState; import com.ym.service.LiveRoomService; import com.ym.service.RoomService; import com.ym.service.UserService; import io.rong.models.user.UserModel; import io.swagger.annotations.ApiOperation; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; import java.util.List; import static com.ym.mec.common.controller.BaseController.succeed; @RestController @RequestMapping("/user") public class UserController { private static final Logger log = LoggerFactory.getLogger(UserController.class); @Autowired private UserService userService; @Autowired private ImLiveBroadcastRoomService imLiveBroadcastRoomService; @Autowired private LiveRoomService liveRoomService; @Autowired private LivePluginContext livePluginContext; @Autowired private RoomService roomService; @RequestMapping(value = "/register", method = RequestMethod.POST) public Object register(@RequestBody UserModel userModel) throws Exception { return userService.register(userModel); } @RequestMapping(value = "/update", method = RequestMethod.POST) public Object update(@RequestBody UserModel userModel) throws Exception { return userService.update(userModel); } /** * 监听融云用户状态变更 * * @param userState List */ @PostMapping(value = "/statusImUser") public BaseResponse statusImUser(@RequestBody List userState) { log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(userState)); imLiveBroadcastRoomService.opsRoom(userState); return new BaseResponse<>(); } /** * 监听融云用户状态变更 * * @param userState List */ @PostMapping(value = "/update/statusImUser") public Object updateStatusImUser(@RequestBody List userState) { log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(userState)); imLiveBroadcastRoomService.opsRoom(userState); return succeed(); } @PostMapping(value = "/syncLikeCount") public Object syncLikeCount(String roomUid) { log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(roomUid)); imLiveBroadcastRoomService.syncLikeCount(roomUid); return succeed(); } @ApiOperation("腾讯im 回调接口") @PostMapping(value = "/tencentImCallback") public TencentImCallbackResult tencentImCallback(@RequestBody String body, HttpServletRequest request) { log.info("tencentImCallback body:{}", body); LivePluginService pluginService = livePluginContext.getPluginService(TencentCloudLivePlugin.PLUGIN_NAME); String appKey = pluginService.getLiveRoomConfig().getAppKey(); log.info("tencentImCallback request param:{}", JSON.toJSONString(request.getParameterMap())); List sdkList = Arrays.asList(request.getParameterValues("SdkAppid")); if (sdkList == null || sdkList.size() == 0) { log.error("tencentImCallback sdkAppid is null"); return new TencentImCallbackResult(); } if (!sdkList.contains(appKey)) { log.error("tencentImCallback sdkAppid is not match"); return new TencentImCallbackResult(); } String clientIP = request.getParameter("ClientIP"); String optPlatform = request.getParameter("OptPlatform"); if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKONMEMBERSTATECHANGE.getCommand())) { // 直播群成员在线状态回调 TencentData.CallbackOnMemberStateChange callbackOnMemberStateChange = TencentData.CallbackOnMemberStateChange.toObject( body); log.debug("callbackOnMemberStateChange: {}", callbackOnMemberStateChange); callbackOnMemberStateChange.setClientIP(clientIP); callbackOnMemberStateChange.setOptPlatform(optPlatform); if (callbackOnMemberStateChange.getGroupId().startsWith("LIVE")) { imLiveBroadcastRoomService.callbackOnMemberStateChange(callbackOnMemberStateChange); // 直播课学生签退 String[] values = callbackOnMemberStateChange.getGroupId().split("-"); String roomId = values.length > 2 ? values[1] : ""; if ((roomId.startsWith("S") || roomId.startsWith("I")) && CollectionUtils.isNotEmpty(callbackOnMemberStateChange.getMemberList()) && "Offline".equals(callbackOnMemberStateChange.getEventType())) { // 学生编号 String userId = callbackOnMemberStateChange.getMemberList().get(0).getMemberAccount(); try { roomService.leaveRoomSuccess(roomId, userId, null); } catch (Exception e) { log.error("tencentImCallback leaveRoomSuccess error, roomId={}, userId={}", roomId, userId, e); } } } } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERMEMBEREXIT.getCommand())) { // 群成员离开之后回调 TencentData.CallbackAfterMemberExit callbackAfterMemberExit = TencentData.CallbackAfterMemberExit.toObject( body); log.debug("callbackAfterMemberExit: {}", callbackAfterMemberExit); callbackAfterMemberExit.setClientIP(clientIP); callbackAfterMemberExit.setOptPlatform(optPlatform); if (callbackAfterMemberExit.getGroupId().startsWith("LIVE")) { imLiveBroadcastRoomService.callbackAfterMemberExit(callbackAfterMemberExit); // 直播课学生签退 String[] values = callbackAfterMemberExit.getGroupId().split("-"); String roomId = values.length > 2 ? values[1] : ""; if ((roomId.startsWith("S") || roomId.startsWith("I")) && CollectionUtils.isNotEmpty(callbackAfterMemberExit.getExitMemberList())) { // 学生编号 String userId = callbackAfterMemberExit.getExitMemberList().get(0).getMemberAccount(); try { roomService.leaveRoomSuccess(roomId, userId, null); } catch (Exception e) { log.error("tencentImCallback leaveRoomSuccess error, roomId={}, userId={}", roomId, userId, e); } } } } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERNEWMEMBERJOIN.getCommand())) { // 新成员入群之后回调 TencentData.CallbackAfterNewMemberJoin callbackAfterNewMemberJoin = TencentData.CallbackAfterNewMemberJoin.toObject( body); log.debug("CallbackAfterNewMemberJoin: {}", callbackAfterNewMemberJoin); callbackAfterNewMemberJoin.setClientIP(clientIP); callbackAfterNewMemberJoin.setOptPlatform(optPlatform); if (callbackAfterNewMemberJoin.getGroupId().startsWith("LIVE")) { imLiveBroadcastRoomService.callbackAfterNewMemberJoin(callbackAfterNewMemberJoin); // 直播课学生签到 String[] values = callbackAfterNewMemberJoin.getGroupId().split("-"); String roomId = values.length > 2 ? values[1] : ""; if ((roomId.startsWith("S") || roomId.startsWith("I")) && CollectionUtils.isNotEmpty(callbackAfterNewMemberJoin.getNewMemberList())) { // 学生编号 String userId = callbackAfterNewMemberJoin.getNewMemberList().get(0).getMemberAccount(); try { roomService.joinRoomSuccess(roomId, userId, null); } catch (Exception e) { log.error("tencentImCallback joinRoomSuccess error, roomId={}, userId={}", roomId, userId, e); } } } } return new TencentImCallbackResult(); } @ApiOperation("腾讯云直播-推流 回调接口") @PostMapping(value = "/tencentStreamEventCallback") public TencentData.StreamEventCallbackResult tencentStreamEventCallback(@RequestBody String body) { log.info("tencentStreamEventCallback body:{}", body); TencentData.CallbackStreamStateEvent event = TencentData.CallbackStreamStateEvent.from(body); // 直播间推流事件 if (event.getStreamId().startsWith("LIVE")) { ImUserState imUserState = new ImUserState(); imUserState.setUserid(getSpeakerId(event.getStreamId()).toString()); // 断流事件通知 if (event.getEventType() == 0) { // 更新推流时长 if (StringUtils.isNotBlank(event.getPushDuration()) && event.getPushDuration().matches("\\d+")) { // 更新直播推流时长 imLiveBroadcastRoomService.updateLiveRoomPushStreamTime(event); } imUserState.setStatus("3"); // 自动关闭录制 imLiveBroadcastRoomService.closeLive(getRoomUid(event.getStreamId()), getSpeakerId(event.getStreamId()),event.getSequence()); // 同步点赞数 imLiveBroadcastRoomService.syncLikeCount(getRoomUid(event.getStreamId())); } // 推流事件通知 if (event.getEventType() == 1) { // 自动开启录制 imLiveBroadcastRoomService.startLive(getRoomUid(event.getStreamId()), getSpeakerId(event.getStreamId()), null,event.getSequence()); imUserState.setStatus("0"); } //imLiveBroadcastRoomService.opsRoom(Lists.newArrayList(imUserState)); } return TencentData.StreamEventCallbackResult.builder().code(0).build(); } private Integer getSpeakerId(String streamId) { return Integer.parseInt(streamId.split("_")[1]); } private String getRoomUid(String streamId) { return streamId.split("_")[0]; } @ApiOperation("腾讯云直播-录制 回调接口") @PostMapping(value = "/tencentStreamRecordCallback") public TencentData.StreamEventCallbackResult tencentStreamRecordCallback(@RequestBody String body) { log.info("tencentStreamRecordCallback body:{}", body); TencentData.CallbackSteamRecordEvent event = TencentData.CallbackSteamRecordEvent.from(body); // 直播录制事件通知 if (event.getStreamId().startsWith("LIVE")) { log.info("taskId={}, url={}", event.getTaskId(), event.getVideoUrl()); // 生成直播录制信息 liveRoomService.createLiveRoomVideoRecord(event); } return TencentData.StreamEventCallbackResult.builder().code(0).build(); } @ApiOperation("腾讯云直播-推流异常 回调接口") @PostMapping(value = "/tencentStreamExceptionCallback") public TencentData.StreamEventCallbackResult tencentStreamExceptionCallback(@RequestBody String body) { log.info("tencentStreamExceptionCallback body:{}", body); return TencentData.StreamEventCallbackResult.builder().code(0).build(); } }