|
|
@@ -31,11 +31,15 @@ import com.tencentcloudapi.common.Credential;
|
|
31
|
31
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
|
32
|
32
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
|
33
|
33
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
|
|
34
|
+import com.tencentcloudapi.trtc.v20190722.TrtcClient;
|
|
|
35
|
+import com.tencentcloudapi.trtc.v20190722.models.*;
|
|
34
|
36
|
import com.tencentcloudapi.vod.v20180717.VodClient;
|
|
35
|
37
|
import com.tencentcloudapi.vod.v20180717.models.DescribeMediaInfosRequest;
|
|
36
|
38
|
import com.tencentcloudapi.vod.v20180717.models.DescribeMediaInfosResponse;
|
|
|
39
|
+import com.tencentyun.TLSSigAPIv2;
|
|
37
|
40
|
import lombok.extern.slf4j.Slf4j;
|
|
38
|
41
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
42
|
+import org.springframework.beans.factory.annotation.Value;
|
|
39
|
43
|
import org.springframework.stereotype.Service;
|
|
40
|
44
|
import org.springframework.transaction.annotation.Transactional;
|
|
41
|
45
|
import org.springframework.util.ResourceUtils;
|
|
|
@@ -63,6 +67,18 @@ import static com.ruoyi.common.utils.file.FileUploadUtils.getPathFileName;
|
|
63
|
67
|
@Service
|
|
64
|
68
|
@Slf4j
|
|
65
|
69
|
public class VideoServiceImpl implements VideoService {
|
|
|
70
|
+ // 腾讯云即时通信sdkAppId
|
|
|
71
|
+ @Value("${imConfig.sdkAppId}")
|
|
|
72
|
+ private long sdkAppId;
|
|
|
73
|
+ // 腾讯云即时通信密钥
|
|
|
74
|
+ @Value("${imConfig.sdkSecretKey}")
|
|
|
75
|
+ private String sdkSecretKey;
|
|
|
76
|
+ // 腾讯云个人账户secretId
|
|
|
77
|
+ @Value("${imConfig.secretId}")
|
|
|
78
|
+ private String secretId;
|
|
|
79
|
+ // 腾讯云个人账户密钥
|
|
|
80
|
+ @Value("${imConfig.secretKey}")
|
|
|
81
|
+ private String secretKey;
|
|
66
|
82
|
@Autowired
|
|
67
|
83
|
private CaseApplicationMapper caseApplicationMapper;
|
|
68
|
84
|
@Autowired
|
|
|
@@ -149,6 +165,98 @@ public class VideoServiceImpl implements VideoService {
|
|
149
|
165
|
return AjaxResult.success(caseAttachList);
|
|
150
|
166
|
}
|
|
151
|
167
|
|
|
|
168
|
+ /**
|
|
|
169
|
+ * 开启腾讯云录制
|
|
|
170
|
+ * @param roomId
|
|
|
171
|
+ * @return
|
|
|
172
|
+ */
|
|
|
173
|
+ @Override
|
|
|
174
|
+ public AjaxResult openCloudRecording(long caseId,String roomId) {
|
|
|
175
|
+ try {
|
|
|
176
|
+ String userId="recorder_"+roomId;
|
|
|
177
|
+
|
|
|
178
|
+ Credential cred = new Credential(secretId, secretKey);
|
|
|
179
|
+
|
|
|
180
|
+ // 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
|
181
|
+ HttpProfile httpProfile = new HttpProfile();
|
|
|
182
|
+ httpProfile.setEndpoint("trtc.tencentcloudapi.com");
|
|
|
183
|
+ // 实例化一个client选项,可选的,没有特殊需求可以跳过
|
|
|
184
|
+ ClientProfile clientProfile = new ClientProfile();
|
|
|
185
|
+ clientProfile.setHttpProfile(httpProfile);
|
|
|
186
|
+ // 实例化要请求产品的client对象,clientProfile是可选的
|
|
|
187
|
+ TrtcClient client = new TrtcClient(cred, "ap-beijing", clientProfile);
|
|
|
188
|
+
|
|
|
189
|
+ // 实例化一个请求对象,每个接口都会对应一个request对象
|
|
|
190
|
+ CreateCloudRecordingRequest req = new CreateCloudRecordingRequest();
|
|
|
191
|
+ req.setSdkAppId(sdkAppId); // SdkAppId – TRTC的[SdkAppId](https://cloud.tencent.com/document/product/647/46351#sdkappid),和录制的房间所对应的SdkAppId相同
|
|
|
192
|
+ req.setRoomId(roomId); // RoomId – TRTC的[RoomId](https://cloud.tencent.com/document/product/647/46351#roomid),录制的TRTC房间所对应的RoomId
|
|
|
193
|
+ req.setRoomIdType(1L);
|
|
|
194
|
+ /**
|
|
|
195
|
+ * 录制机器人用于进入TRTC房间拉流的[UserId](https://cloud.tencent.com/document/product/647/46351#userid),
|
|
|
196
|
+ * 注意这个UserId不能与其他TRTC房间内的主播或者其他录制任务等已经使用的UserId重复,建议可以把房间ID作为userId的标识的一部分,
|
|
|
197
|
+ * 即录制机器人进入房间的userid应保证独立且唯一
|
|
|
198
|
+ */
|
|
|
199
|
+ req.setUserId(userId);
|
|
|
200
|
+
|
|
|
201
|
+ TLSSigAPIv2 api = new TLSSigAPIv2(Long.valueOf(sdkAppId), sdkSecretKey);
|
|
|
202
|
+ String userSign = api.genUserSig(userId, 60 * 60 * 10);
|
|
|
203
|
+ req.setUserSig(userSign); // 录制机器人用于进入TRTC房间拉流的用户签名,当前 UserId 对应的验证签名,相当于登录密码
|
|
|
204
|
+ RecordParams recordParams = new RecordParams();
|
|
|
205
|
+ // 混流录制
|
|
|
206
|
+ recordParams.setMaxIdleTime(60L*5); // 5分钟内房间里面没有主播,自动停止录制
|
|
|
207
|
+ recordParams.setStreamType(0L); // 0:录制音频+视频流(默认); 1:仅录制音频流; 2:仅录制视频流
|
|
|
208
|
+ recordParams.setRecordMode(2L); // 1:单流录制,分别录制房间的订阅UserId的音频和视频,将录制文件上传至云存储; 2:混流录制,将房间内订阅UserId的音视频混录成一个音视频文件,将录制文件上传至云存储;
|
|
|
209
|
+ recordParams.setOutputFormat(0L); // 0:(默认)输出文件为hls格式。1:输出文件格式为hls+mp4。2:输出文件格式为hls+aac
|
|
|
210
|
+
|
|
|
211
|
+ StorageParams storageParams1 = new StorageParams();
|
|
|
212
|
+ CloudVod cloudVod1 = new CloudVod();
|
|
|
213
|
+ TencentVod tencentVod1 = new TencentVod();
|
|
|
214
|
+ // 录制的文件永久保存
|
|
|
215
|
+ tencentVod1.setExpireTime(0L);
|
|
|
216
|
+ // 录制文件名拼接前缀
|
|
|
217
|
+ tencentVod1.setUserDefineRecordId(caseId+"@");
|
|
|
218
|
+ cloudVod1.setTencentVod(tencentVod1); // 腾讯云点播相关参数。
|
|
|
219
|
+ storageParams1.setCloudVod(cloudVod1); // 必填】腾讯云云点播的账号信息,目前仅支持存储至腾讯云点播VOD。
|
|
|
220
|
+ req.setRecordParams(recordParams); // 云端录制控制参数
|
|
|
221
|
+ req.setStorageParams(storageParams1); // 云端录制文件上传到云存储的参数(目前只支持使用腾讯云点播作为存储)
|
|
|
222
|
+ // 返回的resp是一个CreateCloudRecordingResponse的实例,与请求对象对应
|
|
|
223
|
+ CreateCloudRecordingResponse resp = client.CreateCloudRecording(req);
|
|
|
224
|
+ // 输出json格式的字符串回包
|
|
|
225
|
+ String s = JSON.toJSONString(resp);
|
|
|
226
|
+ return AjaxResult.success(s);
|
|
|
227
|
+ } catch (TencentCloudSDKException e) {
|
|
|
228
|
+ return AjaxResult.error(e.toString());
|
|
|
229
|
+ }
|
|
|
230
|
+ }
|
|
|
231
|
+
|
|
|
232
|
+ @Override
|
|
|
233
|
+ public AjaxResult closeDeleteCloudRecording(String taskId) {
|
|
|
234
|
+ // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
|
|
235
|
+ // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
|
|
236
|
+ // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
|
|
237
|
+ Credential cred = new Credential(secretId, secretKey);
|
|
|
238
|
+ // 实例化一个http选项,可选的,没有特殊需求可以跳过
|
|
|
239
|
+ HttpProfile httpProfile = new HttpProfile();
|
|
|
240
|
+ httpProfile.setEndpoint("trtc.tencentcloudapi.com");
|
|
|
241
|
+ // 实例化一个client选项,可选的,没有特殊需求可以跳过
|
|
|
242
|
+ ClientProfile clientProfile = new ClientProfile();
|
|
|
243
|
+ clientProfile.setHttpProfile(httpProfile);
|
|
|
244
|
+ // 实例化要请求产品的client对象,clientProfile是可选的
|
|
|
245
|
+ TrtcClient client = new TrtcClient(cred, "ap-beijing", clientProfile);
|
|
|
246
|
+ // 实例化一个请求对象,每个接口都会对应一个request对象
|
|
|
247
|
+ DeleteCloudRecordingRequest req = new DeleteCloudRecordingRequest();
|
|
|
248
|
+
|
|
|
249
|
+ // 返回的resp是一个DeleteCloudRecordingResponse的实例,与请求对象对应
|
|
|
250
|
+ DeleteCloudRecordingResponse resp = null;
|
|
|
251
|
+ try {
|
|
|
252
|
+ resp = client.DeleteCloudRecording(req);
|
|
|
253
|
+ } catch (TencentCloudSDKException e) {
|
|
|
254
|
+ return AjaxResult.error(e.toString());
|
|
|
255
|
+ }
|
|
|
256
|
+ return AjaxResult.success(DeleteCloudRecordingResponse.toJsonString(resp));
|
|
|
257
|
+ }
|
|
|
258
|
+
|
|
|
259
|
+
|
|
152
|
260
|
/**
|
|
153
|
261
|
* 查询出音视频集合,并下载,在将云点播上面的音视频删除
|
|
154
|
262
|
* @param fileIds 点播平台唯一ID集合
|