新增功能
This commit is contained in:
@@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||
namespace app\api\controller;
|
||||
|
||||
use app\common\model\tcm\CallRecord;
|
||||
use app\common\service\FileService;
|
||||
use think\facade\Log;
|
||||
|
||||
class TrtcController extends BaseApiController
|
||||
@@ -69,6 +70,7 @@ class TrtcController extends BaseApiController
|
||||
}
|
||||
}
|
||||
$merged = array_values(array_unique(array_merge($prev, $urls)));
|
||||
$merged = $this->mirrorRecordingUrlsIfEnabled($merged);
|
||||
|
||||
$record->save([
|
||||
'recording_urls' => json_encode($merged, JSON_UNESCAPED_UNICODE),
|
||||
@@ -126,4 +128,73 @@ class TrtcController extends BaseApiController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将腾讯云录制地址拉取到本服务器 public/uploads(需在 .env 开启 trtc.recording_mirror_to_storage=1)
|
||||
* @param array<int, string> $urls
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private function mirrorRecordingUrlsIfEnabled(array $urls): array
|
||||
{
|
||||
if (!(int)config('trtc.recording_mirror_to_storage', 0)) {
|
||||
return $urls;
|
||||
}
|
||||
$out = [];
|
||||
foreach ($urls as $u) {
|
||||
$u = trim((string)$u);
|
||||
if ($u === '' || strncmp($u, 'http', 4) !== 0) {
|
||||
$out[] = $u;
|
||||
continue;
|
||||
}
|
||||
$local = $this->downloadRecordingToPublic($u);
|
||||
$out[] = $local !== null ? FileService::getFileUrl($local) : $u;
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
private function downloadRecordingToPublic(string $url): ?string
|
||||
{
|
||||
$dirRel = 'uploads/video/trtc_recording/' . date('Ymd');
|
||||
$dirAbs = public_path() . $dirRel;
|
||||
if (!is_dir($dirAbs) && !mkdir($dirAbs, 0755, true) && !is_dir($dirAbs)) {
|
||||
Log::warning('TRTC mirror: mkdir failed', ['dir' => $dirAbs]);
|
||||
|
||||
return null;
|
||||
}
|
||||
$ext = '.mp4';
|
||||
if (preg_match('/\.([a-z0-9]+)(\?|#|$)/i', $url, $m)) {
|
||||
$ext = '.' . strtolower($m[1]);
|
||||
}
|
||||
$name = 'trtc_' . date('His') . '_' . bin2hex(random_bytes(4)) . $ext;
|
||||
$target = $dirAbs . DIRECTORY_SEPARATOR . $name;
|
||||
$ctx = stream_context_create([
|
||||
'http' => ['timeout' => 600],
|
||||
'ssl' => ['verify_peer' => true, 'verify_peer_name' => true],
|
||||
]);
|
||||
try {
|
||||
$src = @fopen($url, 'rb', false, $ctx);
|
||||
if ($src === false) {
|
||||
return null;
|
||||
}
|
||||
$dst = @fopen($target, 'wb');
|
||||
if ($dst === false) {
|
||||
fclose($src);
|
||||
|
||||
return null;
|
||||
}
|
||||
stream_copy_to_stream($src, $dst);
|
||||
fclose($src);
|
||||
fclose($dst);
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('TRTC mirror download failed: ' . $e->getMessage());
|
||||
|
||||
return null;
|
||||
}
|
||||
if (!is_file($target) || filesize($target) < 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return str_replace('\\', '/', $dirRel . '/' . $name);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user