From 59f96a12a67f5a13c02ffc218d26ac9ec506129f Mon Sep 17 00:00:00 2001 From: claude-bot Date: Fri, 15 May 2026 21:58:37 +0900 Subject: [PATCH] feat(routes): add short /file/video/:id alias for video stream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 외부 공유용으로 더 짧은 영상 파일 URL 을 제공: /file/video/:videoId ← 신규 (영상 주소 복사 결과) /api/video/:videoId/file ← 호환용 alias 로 유지 (기존 링크 안 깨지게) /api/video/:videoId ← 메타 JSON (변경 없음) 핸들러는 한 함수를 두 라우트에 공유. 우클릭 "영상 주소 복사" 가 이제 새 짧은 경로를 클립보드에 넣음. Co-Authored-By: Claude Opus 4.7 --- public/folder.js | 2 +- public/public-folder.js | 2 +- src/routes/public.ts | 17 +++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/public/folder.js b/public/folder.js index f949560..2042d6b 100644 --- a/public/folder.js +++ b/public/folder.js @@ -60,7 +60,7 @@ }) function copyVideoUrl(id) { - var url = location.origin + '/api/video/' + encodeURIComponent(id) + '/file' + var url = location.origin + '/file/video/' + encodeURIComponent(id) if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(url).then(function () { flashToast('주소가 복사되었습니다.') diff --git a/public/public-folder.js b/public/public-folder.js index 212df42..0c3def1 100644 --- a/public/public-folder.js +++ b/public/public-folder.js @@ -34,7 +34,7 @@ }) function copyVideoUrl(id) { - var url = location.origin + '/api/video/' + encodeURIComponent(id) + '/file' + var url = location.origin + '/file/video/' + encodeURIComponent(id) if (navigator.clipboard && navigator.clipboard.writeText) { navigator.clipboard.writeText(url).then(function () { flashToast('주소가 복사되었습니다.') diff --git a/src/routes/public.ts b/src/routes/public.ts index 51908ab..b3b913c 100644 --- a/src/routes/public.ts +++ b/src/routes/public.ts @@ -1,4 +1,4 @@ -import { Router } from 'express' +import { Router, type RequestHandler } from 'express' import path from 'node:path' import { promises as fs } from 'node:fs' import { @@ -57,16 +57,19 @@ publicRouter.get('/player/:videoId', async (req, res, next) => { } }) -/** 영상 파일 스트리밍. ?edited=1 이면 편집본을, 아니면 원본을 보낸다. */ -publicRouter.get('/api/video/:videoId/file', async (req, res, next) => { +/** + * 영상 파일 스트리밍. + * - 짧은 외부 공유용 경로: /file/video/:videoId + * - 기존 경로: /api/video/:videoId/file (호환용으로 유지) + * - ?edited=0 이면 원본을 강제하고, 기본은 편집본 있으면 편집본. + */ +const streamVideoHandler: RequestHandler = async (req, res, next) => { try { const found = await findVideoAnywhere(req.params.videoId) if (!found) { res.status(404).end() return } - // 기본 동작: 편집본(edited)이 있으면 그것을 재생한다. 원본을 강제로 보고 싶으면 ?edited=0. - // 명시적으로 ?edited=1 을 줘도 편집본이 있을 때만 적용된다. const editedParam = typeof req.query.edited === 'string' ? req.query.edited : '' const wantOriginal = editedParam === '0' || editedParam === 'false' const fileName = @@ -80,7 +83,9 @@ publicRouter.get('/api/video/:videoId/file', async (req, res, next) => { } catch (err) { next(err) } -}) +} +publicRouter.get('/file/video/:videoId', streamVideoHandler) +publicRouter.get('/api/video/:videoId/file', streamVideoHandler) /** 비디오 메타 조회 (플레이어/관리자 양쪽에서 사용) */ publicRouter.get('/api/video/:videoId', async (req, res, next) => {