新增功能
This commit is contained in:
@@ -17,7 +17,7 @@ class TrtcController extends BaseApiController
|
||||
public array $notNeedLogin = ['recordingNotify'];
|
||||
|
||||
/**
|
||||
* POST /api/trtc/recording-notify
|
||||
* POST /api/trtc/recording-notify 或 /api/trtc/recordingNotify(与控制台回调 URL 一致即可)
|
||||
* 可选安全:环境变量 TRTC_RECORDING_CALLBACK_TOKEN 非空时,Query 需带 ?token=xxx
|
||||
*/
|
||||
public function recordingNotify()
|
||||
@@ -37,28 +37,41 @@ class TrtcController extends BaseApiController
|
||||
return json(['code' => 0, 'msg' => 'ok']);
|
||||
}
|
||||
|
||||
$eventType = (int)($json['EventType'] ?? 0);
|
||||
$roomId = $this->extractRoomId($json);
|
||||
$taskId = trim((string)data_get($json, 'EventInfo.TaskId', ''));
|
||||
$urls = $this->extractRecordingUrls($json);
|
||||
|
||||
if ($roomId === '' || $urls === []) {
|
||||
Log::info('TRTC recording callback: skip (no room or no urls)', [
|
||||
'roomId' => $roomId,
|
||||
'eventType' => $json['EventType'] ?? null,
|
||||
]);
|
||||
if ($urls === []) {
|
||||
// 301–308 等为进度事件,无播放地址;311=VOD 上传完成带 VideoUrl(见文档 81113)
|
||||
$mayHaveUrl = in_array($eventType, [309, 310, 311], true);
|
||||
$payload = data_get($json, 'EventInfo.Payload');
|
||||
if ($urls === [] && $eventType === 311) {
|
||||
Log::warning('TRTC recording callback: 311 但未解析到 VideoUrl(可能 Status!=0 或字段名变更)', [
|
||||
'PayloadStatus' => is_array($payload) ? ($payload['Status'] ?? null) : null,
|
||||
'Errmsg' => is_array($payload) ? ($payload['Errmsg'] ?? $payload['ErrMsg'] ?? null) : null,
|
||||
'TaskId' => $taskId !== '' ? $taskId : null,
|
||||
'roomId' => $roomId !== '' ? $roomId : null,
|
||||
]);
|
||||
}
|
||||
Log::info(
|
||||
'TRTC recording callback: skip (no playback url in payload) '
|
||||
. 'EventType=' . $eventType
|
||||
. ' EventGroupId=' . (string)($json['EventGroupId'] ?? '')
|
||||
. ' TaskId=' . ($taskId !== '' ? $taskId : '-')
|
||||
. ' roomId=' . ($roomId !== '' ? $roomId : '-')
|
||||
. ' ' . ($mayHaveUrl ? 'expect_url' : 'progress_ok')
|
||||
);
|
||||
return json(['code' => 0, 'msg' => 'ok']);
|
||||
}
|
||||
|
||||
$record = CallRecord::where('room_id', $roomId)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
$record = $this->resolveCallRecordForNotify($roomId, $taskId);
|
||||
if (!$record) {
|
||||
// 兼容数字房间号与字符串
|
||||
$record = CallRecord::where('room_id', (string)(int)$roomId)
|
||||
->order('id', 'desc')
|
||||
->find();
|
||||
}
|
||||
if (!$record) {
|
||||
Log::warning('TRTC recording: no call_record for room', ['roomId' => $roomId]);
|
||||
Log::warning('TRTC recording: no call_record (try room_id + cloud_recording_task_id)', [
|
||||
'roomId' => $roomId,
|
||||
'TaskId' => $taskId,
|
||||
'EventType' => $eventType,
|
||||
]);
|
||||
return json(['code' => 0, 'msg' => 'ok']);
|
||||
}
|
||||
|
||||
@@ -88,18 +101,52 @@ class TrtcController extends BaseApiController
|
||||
$candidates = [
|
||||
data_get($data, 'EventInfo.RoomId'),
|
||||
data_get($data, 'EventInfo.RoomIdStr'),
|
||||
data_get($data, 'EventInfo.StrRoomId'),
|
||||
data_get($data, 'EventInfo.Payload.RoomId'),
|
||||
data_get($data, 'EventInfo.Payload.RoomIdStr'),
|
||||
data_get($data, 'RoomId'),
|
||||
data_get($data, 'room_id'),
|
||||
];
|
||||
foreach ($candidates as $v) {
|
||||
if ($v !== null && $v !== '') {
|
||||
return trim((string)$v);
|
||||
$s = trim((string)$v);
|
||||
if ($s !== '' && $s !== '0') {
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 先按 room_id,再按 CreateCloudRecording 返回的 TaskId(须库中仍保留 cloud_recording_task_id)
|
||||
*/
|
||||
private function resolveCallRecordForNotify(string $roomId, string $taskId): ?CallRecord
|
||||
{
|
||||
if ($roomId !== '') {
|
||||
$record = CallRecord::where('room_id', $roomId)->order('id', 'desc')->find();
|
||||
if ($record) {
|
||||
return $record;
|
||||
}
|
||||
if (ctype_digit($roomId)) {
|
||||
$norm = (string)(int)$roomId;
|
||||
$record = CallRecord::where('room_id', $norm)->order('id', 'desc')->find();
|
||||
if ($record) {
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($taskId !== '') {
|
||||
$record = CallRecord::where('cloud_recording_task_id', $taskId)->order('id', 'desc')->find();
|
||||
if ($record) {
|
||||
return $record;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从回调 JSON 中提取录制文件地址(混流/单路字段名在不同版本可能不同)
|
||||
*/
|
||||
@@ -117,9 +164,10 @@ class TrtcController extends BaseApiController
|
||||
return;
|
||||
}
|
||||
foreach ($node as $key => $val) {
|
||||
if (is_string($key) && in_array($key, ['VideoUrl', 'FileUrl', 'MediaUrl', 'Url', 'url'], true) && is_string($val)) {
|
||||
$keyLower = is_string($key) ? strtolower($key) : '';
|
||||
if (in_array($keyLower, ['videourl', 'fileurl', 'mediaurl', 'url', 'streamurl', 'playurl'], true) && is_string($val)) {
|
||||
$v = trim($val);
|
||||
if ($v !== '' && str_starts_with($v, 'http')) {
|
||||
if ($v !== '' && preg_match('#^https?://#i', $v) === 1) {
|
||||
$urls[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user