emb-vision-sdk
v0.1.16
Published
프레임워크 비의존 실시간 비디오 화질 개선. <video> 를 셀렉터로 선택하면 위에 canvas 가 겹쳐지고 WebGPU/WebGL 로 화질이 개선됩니다.
Maintainers
Readme
emb-vision-sdk
- 📖 제품 소개: https://emb-vision-demo.web.app
- ▶️ 라이브 데모: https://emb-vision-demo.web.app/demo
- 🛠️ 개발자 가이드: https://emb-vision-demo.web.app/doc
프레임워크에 의존하지 않는 실시간 비디오 화질 개선 라이브러리입니다.
페이지에 이미 있는 <video> 엘리먼트를 셀렉터로 지정하기만 하면, 그 위에 <canvas> 가
정확히 겹쳐지면서 WebGPU(미지원 시 WebGL 자동 폴백) 로 화질이 개선됩니다.
원본 영상은 자동으로 숨겨지고 캔버스가 그 자리를 대신합니다.
- ✅ React / Vue / Svelte / 순수 JS — 어디서나 동작 (그냥
<video>만 있으면 됨) - ✅ HLS·DASH·MP4 등 재생 방식 무관 (영상은 당신의 플레이어가 재생, 우리는 화면만 개선)
- ✅ WebGPU 우선 + WebGL 폴백, 저사양 기기 자동 감쇠
- ✅ 8종 프로필 프리셋 + 업스케일(720p→1080p 등) + 엣지 강조
- ✅ 의존성 0, ESM, 타입 정의 포함
설치
npm install emb-vision-sdk가장 빠른 사용법
<video id="player" src="movie.mp4" controls></video>import { enhance } from "emb-vision-sdk";
// 셀렉터만 넘기면 끝. 캔버스가 video 위에 겹쳐지고 화질 개선이 시작됩니다.
const fx = enhance("#player", { enabled: true, profile: "default" });이게 전부입니다. 별도의 캔버스를 만들거나 렌더 루프를 돌릴 필요가 없습니다.
사용 패턴
효과 켜기 / 끄기 / 프로필 바꾸기
const fx = enhance("#player", { enabled: true, profile: "default" });
fx.update({ enabled: true, profile: "detail" }); // 프로필 변경
fx.setEnabled(false); // 잠깐 끄기 (원본 노출)
fx.setEnabled(true); // 다시 켜기
fx.getState(); // { backend: "webgpu", enabled: true, unsupported: false }
fx.destroy(); // 정리 — 캔버스 제거 + 원본 video 원복셀렉터 대신 엘리먼트 직접 전달
const video = document.querySelector("video")!;
enhance(video, { enabled: true, profile: "ott" });React
import { useEffect, useRef } from "react";
import { enhance } from "emb-vision-sdk";
function Player() {
const ref = useRef<HTMLVideoElement>(null);
useEffect(() => {
if (!ref.current) return;
const fx = enhance(ref.current, { enabled: true, profile: "default" });
return () => fx.destroy(); // 언마운트 시 정리
}, []);
return <video ref={ref} src="movie.mp4" controls />;
}Vue 3
<script setup>
import { onMounted, onBeforeUnmount, ref } from "vue";
import { enhance } from "emb-vision-sdk";
const video = ref(null);
let fx;
onMounted(() => { fx = enhance(video.value, { enabled: true, profile: "default" }); });
onBeforeUnmount(() => fx?.destroy());
</script>
<template>
<video ref="video" src="movie.mp4" controls />
</template>HLS / DASH 플레이어와 함께
이 라이브러리는 영상을 재생하지 않습니다. 재생은 평소처럼 hls.js·dash.js·video.js
등으로 하고, 같은 <video> 에 enhance() 만 걸면 됩니다.
import Hls from "hls.js";
import { enhance } from "emb-vision-sdk";
const video = document.querySelector("#player");
const hls = new Hls();
hls.loadSource("https://example.com/stream.m3u8");
hls.attachMedia(video);
enhance(video, { enabled: true, profile: "ott" }); // 그대로 위에 얹기옵션
enhance(target, {
enabled: true, // 필수: 효과 on/off
profile: "default", // 프로필 프리셋 (아래 표)
renderer: "auto", // "auto" | "webgpu" | "webgl"
// 개별 강도 — 명시하면 프로필 기본값을 덮어씀 (모두 선택)
sharpen: 0.4, // 0..1 선명도(언샤프)
contrast: 0.3, // 0..1 대비(S-curve)
cleanup: 0.3, // 0..1 압축 노이즈/블록 제거
gamma: 1.0, // 0.5..2.0
localContrast: 0.2, // 0..1 로컬 대비(텍스트/디테일 체감)
darkLift: 0.0, // 0..1 암부만 끌어올림
// 업스케일 (저해상도 → 고해상도)
upscale: {
enabled: true,
algorithm: "fsr", // "lanczos"|"fsr"|"bilinear"|"nearest" (미지정 시 bilinear)
target: "1080p", // "720p"|"1080p"|"1440p"|"2x"|"3x"|"source"|"custom" (미지정 시 layout × DPR 자동)
sharpness: 0.06,
},
// 엣지 강조 (sharpen + rcas 통합 단일 API)
edgeEnhancement: { enabled: true, algorithm: "rcas", strength: 0.6 }, // strength 0..1 (default 프로필 기본 0.6)
autoReduceOnLowEnd: true, // 저사양 기기에서 강도 자동 감쇠 (기본 true)
// 라이선스 (아래 "라이선스" 섹션 참고)
licenseKey: "VSK-XXXXX-XXXXX-XXXXX-XXXXX",
});프로필 프리셋
| profile | 용도 |
| --- | --- |
| default | Cinematic — 자연스럽고 즉시 체감되는 실사용 메인 |
| detail | Ultra Detail — 시연/마케팅용 와우 효과 |
| ott | 저비트레이트 스트리밍(480p/720p) 압축 노이즈 완화 |
| education | 텍스트/판서 가독성 강조 |
| cctv | 야간/저조도 대비 강조 |
| anime | 라인 강조 + 색면 평탄화 |
| oled | 깊은 black + 영화적 대비 |
| retro | CRT scanline + warm gamma (프로필 지정만으로 scanline 자동 적용) |
| off | 효과 비활성 |
업스케일 (선택)
upscale 에 원하는 조합을 직접 지정하세요.
import { enhance } from "emb-vision-sdk";
enhance("#player", {
enabled: true,
profile: "ott",
upscale: {
enabled: true,
target: "1080p", // source | 720p | 1080p | 1440p | 2x | 3x | custom
algorithm: "fsr", // none | nearest | bilinear | lanczos | fsr
sharpness: 0.06, // 0..0.2 (그 이상은 halo)
},
});API
enhance(target, options?)
| 인자 | 타입 | 설명 |
| --- | --- | --- |
| target | string \| HTMLVideoElement | CSS 셀렉터 또는 video 엘리먼트 |
| options | VideoEnhancementOptions | 생략 시 { enabled: true, profile: "default" } |
반환값 handle:
| 멤버 | 설명 |
| --- | --- |
| update(options) | 옵션 갱신 (프로필/강도/렌더러 등) |
| setEnabled(boolean) | 효과 on/off 단축 |
| getState() | { backend, enabled, unsupported, license } (license: none/pending/ok/invalid) |
| destroy() | 캔버스 제거 + 원본 video 원복 |
| video | 대상 video 엘리먼트 |
| enhancer | 내부 VideoEnhancer 인스턴스 (고급 제어용) |
고급 사용자를 위해
VideoEnhancer,WebGLVideoRenderer,WebGPUVideoRenderer,EnhancementPipeline,PROFILE_LIST, CNN 가중치 로더 등도 함께 export 됩니다.
동작 방식 (참고)
<video>의 부모가position: static이면 자동으로relative로 만든 뒤, 그 안에 절대 위치 오버레이 + 캔버스를 삽입합니다. DOM 을 감싸지 않아 기존 레이아웃을 거의 건드리지 않습니다.- 원본 video 는
visibility: hidden으로 숨기되 레이아웃 박스는 유지하므로, 반응형 크기·비율(letterbox/pillarbox)이 그대로 따라갑니다. - 렌더링은
requestVideoFrameCallback(미지원 시requestAnimationFrame) 기반이라 영상이 멈추면 GPU 작업도 멈춥니다.
브라우저 지원
| 환경 | 동작 |
| --- | --- |
| Chrome/Edge 113+ | WebGPU |
| 그 외 WebGL1 지원 브라우저 | WebGL 폴백 |
| 둘 다 불가 | 효과 끄고 원본 영상 그대로 노출 (getState().unsupported === true) |
주의사항
- 교차 출처(CORS) 영상에 효과를 적용하려면
<video>에crossorigin="anonymous"가 필요하고, 영상 서버가 적절한 CORS 헤더를 보내야 합니다. (캔버스 오염 방지) enhance()호출 시점에<video>가 DOM 에 존재해야 합니다.
라이선스 (License)
emb-vision-sdk 는 라이선스 키로 활성화되는 상용 SDK 입니다. 설치 후 발급받은
라이선스 키로 사용이 제어되며, 키 없이 또는 검증 실패 시에는 화질 개선이
적용되지 않고 원본 영상이 그대로 재생됩니다.
라이선스 키 적용
const fx = enhance("#player", {
enabled: true,
profile: "ott",
licenseKey: "VSK-XXXXX-XXXXX-XXXXX-XXXXX", // 발급받은 키
});- 키가 주어지면
enhance()가 검증 통과 전까지 효과를 적용하지 않습니다(원본 재생). 통과하면 자동으로 화질 개선이 시작됩니다. - 검증은 허용 도메인(origin) 바인딩 + 만료일을 서버에서 확인합니다.
계약 시 등록한 도메인에서만 동작하며,
http://localhost는 개발 편의를 위해 항상 허용됩니다. - 상태는
getState().license로 확인할 수 있습니다 —none(키 미지정) ·pending(검증 중) ·ok(통과) ·invalid(없음/만료/폐기/도메인 불일치/네트워크 오류). - 검증 실패 시 브라우저 콘솔에 사유(키/도메인/만료)가 안내됩니다.
키 발급 / 문의
라이선스 키 발급·도입 문의: [email protected]
ⓒ SGRSOFT. All Rights Reserved. — 무단 복제·재배포 금지, 계약 범위 내 사용.
