|
@@ -0,0 +1,361 @@
|
|
|
|
|
+package com.poyee.controller.live;
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
|
|
+import com.poyee.anon.ApiLog;
|
|
|
|
|
+import com.poyee.anon.RequireRoles;
|
|
|
|
|
+import com.poyee.constant.UserType;
|
|
|
|
|
+import com.poyee.controller.base.BaseController;
|
|
|
|
|
+import com.poyee.dto.InDto;
|
|
|
|
|
+import com.poyee.dto.ResultDTO;
|
|
|
|
|
+import com.poyee.entity.CardGroupLivesConfig;
|
|
|
|
|
+import com.poyee.entity.QCardGroupLivesConfig;
|
|
|
|
|
+import com.poyee.enums.BusinessType;
|
|
|
|
|
+import com.poyee.service.CardGroupLivesConfigService;
|
|
|
|
|
+import com.poyee.service.dto.AppLiveDTO;
|
|
|
|
|
+import com.poyee.service.dto.CloneLiveDTO;
|
|
|
|
|
+import com.poyee.utils.Md5Utils;
|
|
|
|
|
+import com.poyee.constant.Constants;
|
|
|
|
|
+import com.poyee.utils.PushMsgUtil;
|
|
|
|
|
+import com.poyee.utils.RedisUtils;
|
|
|
|
|
+import com.poyee.utils.WebSocketUtils;
|
|
|
|
|
+import com.tencentcloudapi.common.Credential;
|
|
|
|
|
+import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
|
|
|
|
+import com.tencentcloudapi.common.profile.ClientProfile;
|
|
|
|
|
+import com.tencentcloudapi.common.profile.HttpProfile;
|
|
|
|
|
+import com.tencentcloudapi.vod.v20180717.VodClient;
|
|
|
|
|
+import com.tencentcloudapi.vod.v20180717.models.LiveRealTimeClipRequest;
|
|
|
|
|
+import com.tencentcloudapi.vod.v20180717.models.LiveRealTimeClipResponse;
|
|
|
|
|
+import com.tencentcloudapi.vod.v20180717.models.SimpleHlsClipRequest;
|
|
|
|
|
+import com.tencentcloudapi.vod.v20180717.models.SimpleHlsClipResponse;
|
|
|
|
|
+import io.swagger.annotations.Api;
|
|
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
+import org.apache.logging.log4j.util.Strings;
|
|
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
|
|
+import org.springframework.data.domain.PageRequest;
|
|
|
|
|
+import org.springframework.data.domain.Sort;
|
|
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
|
|
+
|
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
|
+import java.util.Date;
|
|
|
|
|
+import java.util.TimeZone;
|
|
|
|
|
+
|
|
|
|
|
+@Slf4j
|
|
|
|
|
+@Api("商家直播api")
|
|
|
|
|
+@RestController
|
|
|
|
|
+@RequestMapping("/api/live/")
|
|
|
|
|
+public class CardGroupLivesConfigController extends BaseController {
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private CardGroupLivesConfigService cardGroupLivesConfigService;
|
|
|
|
|
+
|
|
|
|
|
+ @Value("${tencentCloud.living.secretKey:c018bdfe07b758cb11dc10ffea7feca6}")
|
|
|
|
|
+ private String livingSecretKey;
|
|
|
|
|
+
|
|
|
|
|
+ @Value("${living.tencent.secretId:AKIDsZ0A3f29zYrsc5IEsFLBk23oztWsxlIX}")
|
|
|
|
|
+ private String secretId;
|
|
|
|
|
+
|
|
|
|
|
+ @Value("${living.tencent.secretKey:0jBMGtEI5csrZ2E8l9G6fy0lFRN2QXOy}")
|
|
|
|
|
+ private String secretKey;
|
|
|
|
|
+
|
|
|
|
|
+ @Value("${living.im.host:1309648802.vod2.myqcloud.com}")
|
|
|
|
|
+ private String host;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private WebSocketUtils webSocketUtils;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private RedisUtils redisUtils;
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/volc/steamEnd/callback")
|
|
|
|
|
+ @ApiOperation("火山直播断流回调")
|
|
|
|
|
+ public ResultDTO volcengineSteamCallback(@RequestBody JSONObject jsonObject){
|
|
|
|
|
+ log.info("火山直播断流回调结果:{}", jsonObject.toJSONString());
|
|
|
|
|
+ //(直播结束)断流
|
|
|
|
|
+ JSONObject data = jsonObject.getJSONObject("data");
|
|
|
|
|
+ if(data != null) {
|
|
|
|
|
+ String code = data.getString("stream");
|
|
|
|
|
+ Object cache = redisUtils.hget(Constants.LIVING_ROOM_LIKE_KEY, code);
|
|
|
|
|
+ int likeNum = 0;
|
|
|
|
|
+ if(cache != null) {
|
|
|
|
|
+ likeNum = Integer.parseInt(cache.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+ webSocketUtils.sendGroupMsg(code, "火山直播断流通知", JSON.toJSONString(new result().likeNum = likeNum), "STREAMENDNOTIFY");
|
|
|
|
|
+ }
|
|
|
|
|
+ return ResultDTO.buildEmptySuccess();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/tencent/steamEnd/callback")
|
|
|
|
|
+ @ApiOperation("腾讯直播断流回调")
|
|
|
|
|
+ public ResultDTO tencentSteamCallback(@RequestBody JSONObject jsonObject){
|
|
|
|
|
+ log.info("腾讯直播断流回调结果:{}", jsonObject.toJSONString());
|
|
|
|
|
+ if(jsonObject.containsKey("stream_id")) {
|
|
|
|
|
+ String code = jsonObject.getString("stream_id");
|
|
|
|
|
+ Object cache = redisUtils.hget(Constants.LIVING_ROOM_LIKE_KEY, code);
|
|
|
|
|
+ int likeNum = 0;
|
|
|
|
|
+ if(cache != null) {
|
|
|
|
|
+ likeNum = Integer.parseInt(cache.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+ webSocketUtils.sendGroupMsg(code, "腾讯直播断流通知", JSON.toJSONString(new result().likeNum = likeNum), "STREAMENDNOTIFY");
|
|
|
|
|
+ }
|
|
|
|
|
+ return ResultDTO.buildEmptySuccess();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/add")
|
|
|
|
|
+ @RequireRoles(value = {UserType.USER_ROLE_SHIPPING,UserType.USER_ROLE_LIVING})
|
|
|
|
|
+ @ApiLog(title = "创建直播间", businessType = BusinessType.INSERT)
|
|
|
|
|
+ @ApiOperation("创建直播间")
|
|
|
|
|
+ public ResultDTO createLives(@RequestBody InDto inDto){
|
|
|
|
|
+ AppLiveDTO appLiveDTO = buildQueryParam(inDto, new AppLiveDTO());
|
|
|
|
|
+ return cardGroupLivesConfigService.createLives(appLiveDTO, getSimpleUserInfo(true));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/page")
|
|
|
|
|
+ @ApiLog(title = "直播列表", businessType = BusinessType.SEARCH)
|
|
|
|
|
+ @ApiOperation("直播列表")
|
|
|
|
|
+ public ResultDTO findPage(@RequestBody InDto inDto){
|
|
|
|
|
+ PageRequest pageRequest = PageRequest.of(Integer.parseInt(inDto.getString("limit")),
|
|
|
|
|
+ Integer.parseInt(inDto.getString("offset")), Sort.Direction.DESC, "createTime");
|
|
|
|
|
+ Long status = Long.parseLong(inDto.getData().get("status").toString());
|
|
|
|
|
+ return cardGroupLivesConfigService.findLivesPage(status, getSimpleUserInfo(true), pageRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/edit")
|
|
|
|
|
+ @RequireRoles(value = {UserType.USER_ROLE_SHIPPING})
|
|
|
|
|
+ @ApiLog(title = "编辑直播间", businessType = BusinessType.UPDATE)
|
|
|
|
|
+ @ApiOperation("编辑直播间")
|
|
|
|
|
+ public ResultDTO updateLives(@RequestBody InDto inDto){
|
|
|
|
|
+ AppLiveDTO appLiveDTO = buildQueryParam(inDto, new AppLiveDTO());
|
|
|
|
|
+ return cardGroupLivesConfigService.updateLives(appLiveDTO, getSimpleUserInfo(true));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/start")
|
|
|
|
|
+ @RequireRoles(value = {UserType.USER_ROLE_SHIPPING,UserType.USER_ROLE_LIVING})
|
|
|
|
|
+ @ApiLog(title = "直播开始", businessType = BusinessType.UPDATE)
|
|
|
|
|
+ @ApiOperation("直播开始")
|
|
|
|
|
+ public ResultDTO startLive(@RequestBody InDto inDto){
|
|
|
|
|
+ return cardGroupLivesConfigService.startLive(Long.valueOf(inDto.getString("id")), getSimpleUserInfo(true).getMerchantId());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/end")
|
|
|
|
|
+ @RequireRoles(value = {UserType.USER_ROLE_SHIPPING,UserType.USER_ROLE_ADMIN, UserType.USER_ROLE_LIVING})
|
|
|
|
|
+ @ApiLog(title = "直播结束", businessType = BusinessType.UPDATE)
|
|
|
|
|
+ @ApiOperation("直播结束")
|
|
|
|
|
+ public ResultDTO endLive(@RequestBody InDto inDto){
|
|
|
|
|
+ Long id = Long.valueOf(inDto.getString("id"));
|
|
|
|
|
+ return cardGroupLivesConfigService.endLive(id, getSimpleUserInfo(true).getMerchantId());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/online/status")
|
|
|
|
|
+ @ApiLog(title = "查询帐号在线状态", businessType = BusinessType.SEARCH)
|
|
|
|
|
+ @ApiOperation("查询帐号在线状态")
|
|
|
|
|
+ public ResultDTO onlineStatus(@RequestBody InDto inDto){
|
|
|
|
|
+ return cardGroupLivesConfigService.onlineStatus(getSimpleUserInfo(true).getId().longValue());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ //@ApiLog(title = "商家直播回调-腾讯直播", businessType = BusinessType.UPDATE)
|
|
|
|
|
+ @PostMapping("/tencentCallBack")
|
|
|
|
|
+ public void tencentCallBack(@RequestBody JSONObject params) {
|
|
|
|
|
+ /*{
|
|
|
|
|
+ "app": "mlivecdn.hobbystocks.cn",
|
|
|
|
|
+ "appid": 1309648802,
|
|
|
|
|
+ "appname": "live",
|
|
|
|
|
+ "callback_ext": "{\"video_codec\":\"h264\",\"session_id\":\"1767705490833341553\",\"resolution\":\"1088x1920\"}",
|
|
|
|
|
+ "channel_id": "TC4088024121016602",
|
|
|
|
|
+ "duration": 45,
|
|
|
|
|
+ "end_time": 1733818379,
|
|
|
|
|
+ "end_time_usec": 159101,
|
|
|
|
|
+ "event_type": 100,
|
|
|
|
|
+ "file_format": "hls",
|
|
|
|
|
+ "file_id": "1397757899855318636",
|
|
|
|
|
+ "file_size": 41151964,
|
|
|
|
|
+ "media_start_time": 51331905,
|
|
|
|
|
+ "record_bps": 0,
|
|
|
|
|
+ "record_file_id": "1397757899855318636",
|
|
|
|
|
+ "sign": "f8604f92fa23182847aea96644185726",
|
|
|
|
|
+ "start_time": 1733818336,
|
|
|
|
|
+ "start_time_usec": 643117,
|
|
|
|
|
+ "stream_id": "TC4088024121016602",
|
|
|
|
|
+ "stream_param": "txSecret=92eed031935e95dc9e370a102a143bc1&txTime=675b0880",
|
|
|
|
|
+ "t": 1733818982,
|
|
|
|
|
+ "task_id": "1767705490833341553",
|
|
|
|
|
+ "video_id": "1309648802_80c8a08eb60e4df2873efe1c036e46fa",
|
|
|
|
|
+ "video_url": "http://1309648802.vod2.myqcloud.com/46b68c6bvodcq1309648802/503721431397757899855318636/playlist.m3u8"
|
|
|
|
|
+ }*/
|
|
|
|
|
+ //JSONObject retbackMsg = new JSONObject();
|
|
|
|
|
+ //retbackMsg.put("code", 0);
|
|
|
|
|
+ log.info("tencentCallBack result: " + params);
|
|
|
|
|
+ if (null != params) {
|
|
|
|
|
+ Integer t = params.getInteger("t");
|
|
|
|
|
+ String sign = params.getString("sign");
|
|
|
|
|
+ //验签
|
|
|
|
|
+ String signStr = Md5Utils.hash(livingSecretKey + t);
|
|
|
|
|
+ log.info("商城直播回调signStr: " + signStr);
|
|
|
|
|
+ if (StringUtils.isNotEmpty(sign) && StringUtils.isNotEmpty(signStr) && sign.equals(signStr)) {//验签通过
|
|
|
|
|
+ QCardGroupLivesConfig qCardGroupLivesConfig = QCardGroupLivesConfig.cardGroupLivesConfig;
|
|
|
|
|
+ String streamId = params.getString("stream_id");//直播间code
|
|
|
|
|
+ String videoUrl = params.getString("video_url");//回放地址
|
|
|
|
|
+ // 查询是否有回放地址
|
|
|
|
|
+ CardGroupLivesConfig oldEntity = cardGroupLivesConfigService.getQueryFactory().
|
|
|
|
|
+ selectFrom(qCardGroupLivesConfig)
|
|
|
|
|
+ .where(qCardGroupLivesConfig.code.eq(streamId).and(qCardGroupLivesConfig.category.eq("goods")))
|
|
|
|
|
+ .fetchOne();
|
|
|
|
|
+ if(oldEntity == null){
|
|
|
|
|
+ log.error("商城直播不存在");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果之前有回放地址,在后面用逗号追加一个新地址
|
|
|
|
|
+ String oldPath = oldEntity.getPlaybackPath();
|
|
|
|
|
+ if(Strings.isNotEmpty(oldPath)){
|
|
|
|
|
+ videoUrl = String.join(",", oldPath, videoUrl);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 腾讯直播结束回调 根据code同步直播间回放地址
|
|
|
|
|
+ long result = cardGroupLivesConfigService.buildPlaybackPath(videoUrl, oldEntity.getId());
|
|
|
|
|
+ if(result == 0){
|
|
|
|
|
+ log.error("同步回放地址失败:{}", oldEntity.getCode());
|
|
|
|
|
+ }
|
|
|
|
|
+ }else{
|
|
|
|
|
+ log.info("商城直播回调签名失败: {}", signStr);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/detail")
|
|
|
|
|
+ @ApiLog(title = "商家直播间详情", businessType = BusinessType.SEARCH)
|
|
|
|
|
+ @ApiOperation("商家直播间详情")
|
|
|
|
|
+ public ResultDTO findDetail(@RequestBody InDto inDto){
|
|
|
|
|
+ Long id = Long.valueOf(inDto.getData().get("id").toString());
|
|
|
|
|
+ return cardGroupLivesConfigService.findDetail(id, getSimpleUserInfo(true));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/createGroup")
|
|
|
|
|
+ @ApiLog(title = "创建聊天室", businessType = BusinessType.INSERT)
|
|
|
|
|
+ @ApiOperation("创建聊天室")
|
|
|
|
|
+ public ResultDTO createGroup(@RequestBody InDto inDto){
|
|
|
|
|
+ String code = inDto.getData().get("code").toString();
|
|
|
|
|
+ cardGroupLivesConfigService.createGroup(getSimpleUserInfo(true).toString(), code, code);
|
|
|
|
|
+ return successResult(null);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @PostMapping("/destroyGroup")
|
|
|
|
|
+ @ApiLog(title = "解散聊天室", businessType = BusinessType.UPDATE)
|
|
|
|
|
+ @ApiOperation("解散聊天室")
|
|
|
|
|
+ public ResultDTO destroyGroup(@RequestBody InDto inDto){
|
|
|
|
|
+ String code = inDto.getData().get("code").toString();
|
|
|
|
|
+ cardGroupLivesConfigService.destroyGroup(code);
|
|
|
|
|
+ return ResultDTO.buildEmptySuccess().setMsg("解散成功");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 直播即时剪辑
|
|
|
|
|
+ * @param endTime 剪辑结束时间
|
|
|
|
|
+ * @param liveStartTime 剪辑开始时间
|
|
|
|
|
+ * @param streamId 直播code
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @ApiOperation("直播即时剪辑")
|
|
|
|
|
+ @PostMapping("/getPlayBackUrl")
|
|
|
|
|
+ public String getPlayBackUrl(String endTime, String liveStartTime, String streamId){
|
|
|
|
|
+ String respJsonString = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 调用腾讯云直播剪辑获取商品拆卡直播回放地址
|
|
|
|
|
+ Credential cred = new Credential(secretId, secretKey);
|
|
|
|
|
+ // 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
|
|
|
+ HttpProfile httpProfile = new HttpProfile();
|
|
|
|
|
+ httpProfile.setEndpoint("vod.tencentcloudapi.com");
|
|
|
|
|
+ // 实例化一个client选项,可选的,没有特殊需求可以跳过
|
|
|
|
|
+ ClientProfile clientProfile = new ClientProfile();
|
|
|
|
|
+ clientProfile.setHttpProfile(httpProfile);
|
|
|
|
|
+ // 实例化要请求产品的client对象,clientProfile是可选的
|
|
|
|
|
+ VodClient client = new VodClient(cred, "", clientProfile);
|
|
|
|
|
+ // 实例化一个请求对象,每个接口都会对应一个request对象
|
|
|
|
|
+ LiveRealTimeClipRequest req = new LiveRealTimeClipRequest();
|
|
|
|
|
+ // 所有时间相关参数统一采用 ISO 8601 表示的 UTC 时间,格式为 YYYY-MM-dd'T'HH:mm:ss'Z'
|
|
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
|
|
|
|
|
+ sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
|
|
|
|
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
|
+ Date start = format.parse(liveStartTime);
|
|
|
|
|
+ Date end = format.parse(endTime);
|
|
|
|
|
+ String startTimestamp = sdf.format(start);
|
|
|
|
|
+ String endTimestamp = sdf.format(end);
|
|
|
|
|
+ req.setStreamId(streamId); // 推流直播码
|
|
|
|
|
+ req.setStartTime(startTimestamp); // 直播开始时间
|
|
|
|
|
+ req.setEndTime(endTimestamp); // 直播结束时间
|
|
|
|
|
+ req.setHost(host);
|
|
|
|
|
+ log.info("直播即时剪辑开始时间:{}, 结束时间:{}", liveStartTime, endTime);
|
|
|
|
|
+ // 返回的resp是一个LiveRealTimeClipResponse的实例,与请求对象对应
|
|
|
|
|
+ LiveRealTimeClipResponse resp = client.LiveRealTimeClip(req);
|
|
|
|
|
+ // 输出json格式的字符串回包
|
|
|
|
|
+ respJsonString = LiveRealTimeClipResponse.toJsonString(resp);
|
|
|
|
|
+ // 输出json格式的字符串回包
|
|
|
|
|
+ log.info("直播剪辑回调:{}" + respJsonString);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ log.error(e.toString());
|
|
|
|
|
+ }
|
|
|
|
|
+ return respJsonString;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 简单HLS剪辑
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @ApiOperation("简单HLS剪辑")
|
|
|
|
|
+ @PostMapping( "/simpleHlsClip")
|
|
|
|
|
+ public String simpleHlsClip(@RequestBody InDto inDto){
|
|
|
|
|
+ String url = inDto.getData().get("url").toString();
|
|
|
|
|
+ Float startTimeOffset = Float.valueOf(inDto.getData().get("startTimeOffset").toString());
|
|
|
|
|
+ Float endTimeOffset = Float.valueOf(inDto.getData().get("endTimeOffset").toString());
|
|
|
|
|
+ String respJsonString = null;
|
|
|
|
|
+ try{
|
|
|
|
|
+ // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
|
|
|
|
|
+ // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
|
|
|
|
|
+ Credential cred = new Credential(secretId, secretKey);
|
|
|
|
|
+ // 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
|
|
|
+ HttpProfile httpProfile = new HttpProfile();
|
|
|
|
|
+ httpProfile.setEndpoint("vod.tencentcloudapi.com");
|
|
|
|
|
+ // 实例化一个client选项,可选的,没有特殊需求可以跳过
|
|
|
|
|
+ ClientProfile clientProfile = new ClientProfile();
|
|
|
|
|
+ clientProfile.setHttpProfile(httpProfile);
|
|
|
|
|
+ // 实例化要请求产品的client对象,clientProfile是可选的
|
|
|
|
|
+ VodClient client = new VodClient(cred, "", clientProfile);
|
|
|
|
|
+ // 实例化一个请求对象,每个接口都会对应一个request对象
|
|
|
|
|
+ SimpleHlsClipRequest req = new SimpleHlsClipRequest();
|
|
|
|
|
+ req.setUrl(url); // 需要裁剪的腾讯云点播 HLS 视频 URL。
|
|
|
|
|
+ req.setStartTimeOffset(startTimeOffset); // 裁剪的开始偏移时间,单位秒。默认 0,即从视频开头开始裁剪。负数表示距离视频结束多少秒开始裁剪。例如 -10 表示从倒数第 10 秒开始裁剪。
|
|
|
|
|
+ req.setEndTimeOffset(endTimeOffset); // 裁剪的结束偏移时间,单位秒。默认 0,即裁剪到视频尾部。负数表示距离视频结束多少秒结束裁剪。例如 -10 表示到倒数第 10 秒结束裁剪。
|
|
|
|
|
+ log.info("简单HLS剪辑url:{}" + url + "===========剪辑开始偏移时间:{}" + startTimeOffset + "=============剪辑结束偏移时间:{}" + endTimeOffset);
|
|
|
|
|
+ // 返回的resp是一个SimpleHlsClipResponse的实例,与请求对象对应
|
|
|
|
|
+ SimpleHlsClipResponse resp = client.SimpleHlsClip(req);
|
|
|
|
|
+ respJsonString = SimpleHlsClipResponse.toJsonString(resp);
|
|
|
|
|
+ // 输出json格式的字符串回包
|
|
|
|
|
+ log.info("简单HLS剪辑回调:{}" + respJsonString);
|
|
|
|
|
+ } catch (TencentCloudSDKException e) {
|
|
|
|
|
+ log.error(e.toString());
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return respJsonString;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @ApiOperation("克隆直播间")
|
|
|
|
|
+ @ApiLog(title = "克隆直播间", businessType = BusinessType.INSERT)
|
|
|
|
|
+ @PostMapping( "/cloneLive")
|
|
|
|
|
+ public ResultDTO cloneLive(@RequestBody InDto inDto){
|
|
|
|
|
+ if(inDto == null) return ResultDTO.buildErrorResult("参数为空");
|
|
|
|
|
+ CloneLiveDTO cloneLiveDTO = new CloneLiveDTO();
|
|
|
|
|
+ cloneLiveDTO.setGroupInfoId(Long.parseLong(inDto.get("groupInfoId").toString()));
|
|
|
|
|
+ cloneLiveDTO.setMerchantId(Long.parseLong(inDto.get("merchantId").toString()));
|
|
|
|
|
+ cloneLiveDTO.setType(Integer.parseInt(inDto.get("type").toString()));
|
|
|
|
|
+ cloneLiveDTO.setMerchantName(inDto.get("merchantName").toString());
|
|
|
|
|
+ cardGroupLivesConfigService.cloneLive(cloneLiveDTO);
|
|
|
|
|
+ return ResultDTO.buildEmptySuccess();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private class result {
|
|
|
|
|
+ int likeNum;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|