@sgrsoft/vision-sdk 소개
페이지에 이미 있는 <video> 를 셀렉터로 지정하면 그 위에 <canvas> 가 겹쳐지며
WebGPU(미지원 시 WebGL)로 화질을 실시간 개선하는 프레임워크 비의존 라이브러리입니다.
낮은 비트레이트 영상도 선명하게 복원해 OTT·스트리밍 서비스의 CDN 트래픽과 운영 비용을 줄입니다.
@sgrsoft/vision-sdk 는 비공개 패키지입니다.
라이선스 계약이 완료되면 npm 조직(@sgrsoft)에 초대되어 설치·사용하실 수 있습니다.
도입 문의는 support@sgrsoft.com 또는 메인 페이지의 상담 채널을 이용해 주세요.
소개 #
재생은 당신의 플레이어가, 화면 개선은 이 라이브러리가 담당합니다.
영상을 로드·디코드·재생하지 않으며, 대상 <video> 의 출력 화면만 GPU 로 개선합니다.
따라서 hls.js·dash.js·video.js·native 등 어떤 재생 방식과도 함께 쓸 수 있습니다.
- 프레임워크 비의존 — React·Vue·Svelte·순수 JS 어디서나
- WebGPU 우선, WebGL 자동 폴백, 저사양 기기 강도 자동 감쇠
- 8종 프로필 + 업스케일(FSR/Lanczos) + 엣지 강조 + CNN 복원
- 의존성 0 · ESM · 타입 정의 포함
설치 (npm) #
npm install @sgrsoft/vision-sdk
비공개 스코프 패키지이므로, 초대된 계정으로 npm 로그인 후에만 설치됩니다. (계약 완료 시 @sgrsoft 조직 초대 → npm login → 설치)
ESM 전용 패키지입니다. 번들러(Vite/webpack/Rollup) 또는 네이티브 ESM 환경에서 import 합니다.
import { enhance } from "@sgrsoft/vision-sdk";
빠른 시작 #
<!-- 1) 페이지에 video 가 있고 -->
<video id="player" src="movie.mp4" controls></video>
// 2) 셀렉터만 넘기면 끝 — 캔버스가 video 위에 겹쳐지고 화질 개선 시작
import { enhance } from "@sgrsoft/vision-sdk";
const fx = enhance("#player", { enabled: true, profile: "default" });
별도 캔버스를 만들거나 렌더 루프를 돌릴 필요가 없습니다. 효과를 끄려면 fx.setEnabled(false),
정리하려면 fx.destroy() 를 호출합니다.
LLM 코드 생성 #
코딩 에이전트가 이 패키지를 정확히 사용하도록 돕는 압축 레퍼런스를 제공합니다. ChatGPT·Claude·Copilot 등에 아래 파일 내용을 컨텍스트로 붙여넣으면 정확한 코드를 생성합니다.
# 배포된 가이드
https://vision.sgrsoft.com/llms.txt
기본 사용법 #
셀렉터 문자열 또는 HTMLVideoElement 를 직접 넘길 수 있습니다.
const video = document.querySelector("video");
const fx = enhance(video, { enabled: true, profile: "ott" });
fx.update({ enabled: true, profile: "detail" }); // 프로필 변경
fx.setEnabled(false); // 잠깐 끄기(원본 노출)
fx.getState(); // { backend, enabled, unsupported }
fx.destroy(); // 정리 + 원본 복원
enhance() 하지 말고 같은 핸들의 update() 를 사용하세요. 렌더러 재생성 비용이 없습니다.프로필 #
상황별 권장 프리셋입니다. 개별 강도 옵션을 함께 지정하면 프로필 기본값을 덮어씁니다.
| profile | 용도 |
|---|---|
default | Cinematic — 자연스럽고 즉시 체감되는 실사용 메인 |
detail | Ultra Detail — 시연/마케팅용 와우 효과 |
ott | 저비트레이트 스트리밍 압축 노이즈 완화 |
education | 텍스트/판서 가독성 강조 |
cctv | 야간/저조도 대비 강조 |
anime | 라인 강조 + 색면 평탄화 |
oled | 깊은 black + 영화적 대비 |
retro | CRT scanline + warm gamma |
off | 효과 비활성(원본 출력) |
업스케일 #
저해상도 영상을 캔버스 해상도로 SR 처리합니다. 프리셋을 그대로 넘기는 것이 가장 간단합니다.
import { enhance, UPSCALE_PRESETS } from "@sgrsoft/vision-sdk";
enhance("#player", {
enabled: true, profile: "ott",
upscale: UPSCALE_PRESETS.quality, // 1080p + FSR EASU
});
프리셋: off · balanced(1080p+Lanczos) · quality(1080p+FSR) · dramatic · lowPower(720p).
직접 지정하려면 upscale: { enabled, algorithm, target, sharpness } 형태로 넘깁니다.
엣지 강조 #
unsharp(classic)과 RCAS(halo-free)를 하나의 API로 통합했습니다.
enhance("#player", {
enabled: true,
edgeEnhancement: { enabled: true, algorithm: "rcas", strength: 0.5 },
});
프레임워크 연동 #
React
import { useEffect, useRef } from "react";
import { enhance } from "@sgrsoft/vision-sdk";
function Player() {
const ref = useRef(null);
useEffect(() => {
const fx = enhance(ref.current, { enabled: true, profile: "default" });
return () => fx.destroy(); // 언마운트 시 정리
}, []);
return <video ref={ref} src="movie.mp4" controls />;
}
Vue 3
onMounted(() => { fx = enhance(video.value, { enabled: true }); });
onBeforeUnmount(() => fx?.destroy());
HLS / DASH 연동 #
재생은 평소처럼 hls.js·dash.js 로 하고, 같은 <video> 에 enhance() 만 얹습니다.
import Hls from "hls.js";
import { enhance } from "@sgrsoft/vision-sdk";
const video = document.querySelector("#player");
const hls = new Hls(); hls.loadSource(url); hls.attachMedia(video);
enhance(video, { enabled: true, profile: "ott" });
트래픽·비용 절감 #
낮은 비트레이트 영상을 전송하고 클라이언트에서 AI 화질 개선을 수행하면, 동일 체감 화질을 유지하면서 CDN 트래픽·저장공간·인프라 비용을 줄일 수 있습니다.
// 저비트레이트 소스 + OTT 프로필 + 업스케일
enhance("#player", {
enabled: true, profile: "ott",
upscale: UPSCALE_PRESETS.quality,
});
API · enhance() #
enhance(target, options?) => EnhanceHandle
| 인자 | 타입 | 설명 |
|---|---|---|
target | string | HTMLVideoElement | CSS 셀렉터 또는 video 엘리먼트. video 가 아니면 throw. |
options | VideoEnhancementOptions | 생략 시 { enabled:true, profile:"default" } |
API · 핸들 메서드 #
| 멤버 | 설명 |
|---|---|
update(options) | 옵션 갱신(프로필/강도/렌더러 등) |
setEnabled(boolean) | 효과 on/off 단축 |
getState() | { backend:"webgl"|"webgpu"|null, enabled, unsupported } |
destroy() | 캔버스 제거 + 원본 video 원복 |
video | 대상 video 엘리먼트 |
enhancer | 내부 VideoEnhancer 인스턴스(저수준 제어) |
API · 옵션 #
| 필드 | 타입 / 범위 | 설명 |
|---|---|---|
enabled | boolean | 필수. 효과 on/off |
profile | EnhancementProfile | 프로필 프리셋 |
renderer | "auto"|"webgpu"|"webgl" | 기본 "auto"(WebGPU→WebGL) |
sharpen contrast cleanup anime | 0..1 | 개별 강도(프로필 덮어씀) |
gamma | 0.5..2.0 | 감마 |
localContrast darkLift | 0..1 | 로컬 대비 / 암부 lift |
upscale | UpscaleParams | 업스케일(알고리즘/target/sharpness) |
edgeEnhancement | {enabled,algorithm,strength} | 엣지 강조 통합 API |
cnn cnn1 | CnnParams | CNN 복원(WebGPU 전용) |
autoReduceOnLowEnd | boolean | 저사양 자동 감쇠(기본 true) |
API · 타입 · Exports #
함수 enhance 외에 저수준 클래스/유틸/타입도 함께 export 합니다.
import {
enhance, VideoEnhancer,
WebGLVideoRenderer, WebGPUVideoRenderer, EnhancementPipeline,
UPSCALE_PRESETS, PROFILE_LIST, getProfileDefaults, isHighResDisplay,
resolveOutputSize, clampOutputSize, normalizeAlgorithm,
loadCnnWeightsFromUrl, parseCnnWeights, buildIdentityCnnLayers, buildSharpenCnnLayers,
} from "@sgrsoft/vision-sdk";
CNN 화질 복원 #
외부 가중치(.bin)를 주입해 multi-layer CNN 으로 디테일을 복원합니다. WebGPU 백엔드에서만 적용됩니다.
import { enhance, loadCnnWeightsFromUrl } from "@sgrsoft/vision-sdk";
const layers = await loadCnnWeightsFromUrl("/cnn-720to1080.bin", 1);
enhance("#player", {
enabled: true, renderer: "webgpu",
cnn: { enabled: true, layers },
});
렌더러 백엔드 #
renderer 로 백엔드를 선택합니다. 기본 "auto" 는 WebGPU 를 시도하고 실패 시 WebGL 로 폴백합니다.
현재 활성 백엔드는 getState().backend 로 확인할 수 있습니다.
| 값 | 동작 |
|---|---|
auto | WebGPU 시도 → 실패 시 WebGL (기본) |
webgpu | WebGPU 강제(미지원 시 WebGL 폴백) |
webgl / webgl2 | WebGL 만 사용(CNN 미적용) |
WebGPU vs WebGL 기능 차이 #
두 백엔드는 대부분의 후처리·업스케일을 동일하게 지원하지만, CNN 화질 복원은 WebGPU 에서만 동작합니다.
renderer:"auto"(기본)는 WebGPU 를 우선 시도하고 미지원 시 WebGL 로 폴백하며, 활성 백엔드는 getState().backend 로 확인합니다.
| 기능 | WebGPU | WebGL |
|---|---|---|
| 업스케일 (FSR · Lanczos · bilinear · nearest) | O | O |
| 엣지 강조 (RCAS · Unsharp) | O | O |
| 대비 · 감마 · 노이즈 제거 · 톤 보정 | O | O |
| 스캔라인 등 스타일 필터 | O | O |
CNN 화질 복원 (cnn · cnn1) | O | X (무시됨) |
| 연산 방식 | compute shader | fragment shader |
| 대표 가용 환경 | Chrome/Edge 113+ 등 | WebGL1 지원 대부분 |
renderer:"webgpu" 로 강제하거나, 런타임에 getState().backend === "webgpu" 인지 확인하세요. WebGL 로 폴백되면 cnn 옵션은 조용히 무시됩니다.원본/개선 비교 #
효과를 켠 상태에서 원본 <video> 를 다시 보이게 하고, 개선 캔버스 오버레이를
clip-path 로 절반만 남기면 좌우 동시 비교를 구현할 수 있습니다(데모의 “동시 비교” 참고).
const ov = document.querySelector("[data-vpe-enhancement]");
ov.style.clipPath = "inset(0 0 0 50%)"; // 오른쪽 절반 = 개선
fx.video.style.visibility = "visible"; // 왼쪽 = 원본
브라우저 지원 #
| Chrome / Edge 113+ | WebGPU |
| 그 외 WebGL1 지원 브라우저 | WebGL 폴백 |
| 둘 다 불가 | 효과 끄고 원본 노출(getState().unsupported === true) |
<video crossorigin="anonymous"> 와 서버 CORS 헤더가 필요합니다(canvas 오염 방지). 자세한 제약은 제약 · 한계 참고.제약 · 한계 #
이 라이브러리는 <video> 프레임을 GPU 텍스처로 업로드해 처리합니다. 따라서 프레임을 읽을 수 없는 환경에는 적용되지 않습니다. 도입 전 아래 제약을 반드시 확인하세요.
DRM 보호 콘텐츠 — 적용 불가
<video> 프레임의 canvas/GPU 캡처를 차단하므로,
효과가 적용되지 않거나 빈/검은 화면이 됩니다. (캡처 시도 시 보안 오류)
적용 가능한 경우: DRM 미적용(클리어) 스트림, 무료/프리뷰 콘텐츠, 광고 등 보호되지 않은 <video>.
DRM 콘텐츠가 핵심인 서비스는 적용 대상에서 제외하거나, 비보호 구간에만 사용하세요.
CORS — 교차 출처 영상
다른 도메인에서 불러오는 영상에 효과를 적용하려면 두 가지가 모두 필요합니다.
<video crossorigin="anonymous">속성- 영상 서버의
Access-Control-Allow-Origin등 CORS 응답 헤더
둘 중 하나라도 없으면 canvas 가 tainted 되어 GPU 업로드가 보안 오류로 실패하고, 효과 없이 원본이 노출됩니다. HLS/DASH 세그먼트(.ts/.m4s) 서버에도 동일하게 CORS 가 적용돼야 합니다. 같은 출처(same-origin) 영상은 제약이 없습니다.
성능 · 환경
- 처리량은 시청자 GPU 성능에 의존합니다. 저사양 PC·모바일에서는
autoReduceOnLowEnd(기본 true)로 강도를 자동 감쇠하지만, GPU 사용률·배터리·발열은 0 이 아닙니다. - WebGPU 미지원 시 WebGL 로 폴백하며 CNN 복원은 적용되지 않습니다(차이표).
- 체감 화질·실측 FPS·전력 영향은 콘텐츠·코덱·기기에 따라 다르므로 도입 전 PoC 측정을 권장합니다.