EMBRACE Vision SDK — iOS / iPadOS
AVPlayer 가 재생하는 영상 프레임을 Metal 로
실시간 개선하는 네이티브 SDK입니다. SwiftUI
VisionVideoView 한 줄로 적용하며, 웹 SDK 와
동일한 옵션·프로필·라이선스 계약을 공유합니다. iOS 15+ ·
iPadOS 12+.
licenseKey 를 지정하면
효과가 즉시 적용되고 2초 후 검증되며, 실패 시 원본으로 되돌립니다.
네이티브는 도메인 대신 앱 번들 ID 로 검증합니다(아래
라이선스). 키 발급 문의:
support@sgrsoft.com.
소개 #
재생은 당신의 AVPlayer 가, 화면 개선은 이 SDK
가
담당합니다. 영상을 로드·디코드·재생하지 않으며,
AVPlayerItemVideoOutput → CVMetalTextureCache → Metal 패스 체인
→ MTKView
로 프레임의 출력 화면만 개선합니다. HLS 등 어떤 재생 방식과도 함께
쓸 수 있습니다.
-
SwiftUI
VisionVideoView(권장) + 명령형VisionEnhancer - 9종 프로필 + 업스케일(FSR/Lanczos) + 엣지 강조 + CNN(Metal compute)
- 웹 SDK 와 1:1 미러 — 같은 프로필·옵션·라이선스 키 체계
- iOS·iPadOS 공용, XCFramework(SPM) 바이너리 배포
설치 (Swift Package Manager) #
// Package.swift
.package(url: "https://github.com/SGRsoft-Dev/vision-ios-sdk.git", from: "0.1.9")
Xcode: File ▸ Add Package Dependencies… 에 위 URL 을
입력하면 SGRVision(XCFramework) 이 추가됩니다. 지원:
iOS 15+ · iPadOS 12+.
import SGRVision
빠른 시작 #
import SwiftUI
import AVFoundation
import SGRVision
struct PlayerScreen: View {
let player = AVPlayer(url: hlsURL) // 재생은 사용자가 제어
var body: some View {
VisionVideoView(
player: player,
options: VisionOptions(profile: .default, licenseKey: "{licenseKey}"),
onLicense: { state in } // .pending → .ok / .invalid
)
.aspectRatio(16.0/9.0, contentMode: .fit)
.onAppear { player.play() }
}
}
별도 렌더 루프나 캔버스가 필요 없습니다.
{licenseKey} 에 발급받은 키를 넣으면 효과가 바로
시작되고 2초 후 검증됩니다(실패 시 원본으로 되돌림).
비율·레이아웃은 호출측 책임입니다.
licenseKey: "VSK-ZP02Z-K3FJ9-4C4DQ-8EM6A"
이 체험 키는 번들 ID
com.sgr.vision.ios.example(예제 앱)에만 바인딩돼
있습니다. 본인 앱에서 쓰려면 앱의 번들 ID 를 등록한 키를
support@sgrsoft.com
으로 발급받으세요(웹의 localhost 면제 같은 건 네이티브엔
없습니다).
LLM 코드 생성 #
코딩 에이전트가 iOS SDK 를 정확히 사용하도록 돕는 압축 레퍼런스
ios-llms.txt 를 제공합니다. 읽히면
옵션·프로필·라이선스(번들 ID)·제약을 한 번에 이해하고 Swift 코드를
생성합니다.
# 에이전트에게 그대로 요청
https://emb-vision-demo.web.app/ios-llms.txt 읽고 SwiftUI 적용 예제코드 알려줘
JavaScript · /llms.txt ↗ iOS · /ios-llms.txt ↗ Android · /android-llms.txt ↗
기본 사용법 #
명령형 컨트롤러 VisionEnhancer 로 옵션을
갱신/토글하고 상태를 조회합니다(웹 enhance() 핸들
미러).
let enhancer = VisionEnhancer(player: player,
options: VisionOptions(profile: .ott))
enhancer.update(VisionOptions(profile: .cctv, contrast: 0.4)) // 옵션 갱신
enhancer.setEnabled(false) // 잠깐 끄기(원본)
let state = enhancer.getState() // VisionState
enhancer.destroy()
VisionVideoView 는 현재
updateUIView 가 비어 있어, 옵션을 바꾸면
.id(...) 값을 바꿔 뷰를 재생성해 적용합니다(예제
방식). 라이선스 결과는 뷰 재생성 없이 라이브로 반영됩니다.
프로필 #
상황별 권장 프리셋입니다. 개별 강도 옵션을 함께 지정하면 프로필 기본값을 덮어씁니다. (웹과 동일한 9종)
| profile | 용도 |
|---|---|
.default |
Cinematic — 자연스럽고 즉시 체감되는 실사용 메인 |
.detail |
Ultra Detail — 시연/마케팅용 와우 효과 |
.ott |
저비트레이트 스트리밍 압축 노이즈 완화 |
.education |
텍스트/판서 가독성 강조 |
.cctv |
야간/저조도 대비 강조 |
.anime |
라인 강조 + 색면 평탄화 |
.oled |
깊은 black + 영화적 대비 |
.retro |
CRT scanline + warm gamma |
.off |
효과 비활성(원본 출력) |
업스케일 #
저해상도 영상을 출력 해상도로 SR 처리합니다.
UpscaleParams 로 원하는 조합을 직접 구성합니다.
// 권장 조합: 1080p + FSR EASU
VisionOptions(
profile: .ott,
upscale: UpscaleParams(enabled: true, algorithm: .fsr,
target: .p1080, sharpness: 0.06)
)
| 용도 | UpscaleParams (예시) |
|---|---|
| 비활성 | upscale 생략(nil) |
| 안정 | .lanczos · .p1080 · 0.04 |
| 고품질 | .fsr · .p1080 · 0.06 |
| 강조 | .fsr · .p1080 · 0.10 |
| 저전력 | .bilinear · .p720 · 0.03 |
엣지 강조 #
unsharp(classic)과 RCAS(halo-free)를 하나의 API로 통합했습니다.
VisionOptions(
profile: .default,
edgeEnhancement: EdgeEnhancementParams(enabled: true,
algorithm: .rcas, strength: 0.5)
)
SwiftUI / UIKit #
SwiftUI (권장)
VisionVideoView(player: player,
options: VisionOptions(profile: .default),
onLicense: { state in })
UIKit
VisionMetalView(MTKView 서브클래스)를
직접 호스팅하거나
UIHostingController(rootView: VisionVideoView(...))
로 감쌉니다.
if let view = VisionMetalView(player: player,
options: VisionOptions(profile: .ott)) {
view.frame = container.bounds
container.addSubview(view)
}
NSViewRepresentable). 예제는
swift run 으로 즉시 실행할 수 있습니다.
AVPlayer · 소스 전환 #
HLS 는 AVPlayer 가 기본 지원하므로 별도 플레이어가
필요 없습니다. 같은 AVPlayer 에
replaceCurrentItem 으로 소스를 바꿔도 SDK 가
자동 재연결합니다(KVO).
let player = AVPlayer() // 빈 플레이어 먼저
// VisionVideoView(player: player, ...) 를 띄운 뒤
player.replaceCurrentItem(with: AVPlayerItem(url: newURL)) // 끊김 없이 전환
VisionMetalView 가
player.currentItem 교체를 감지해 비디오 출력을 다시
연결합니다.
전체화면 #
전체화면·회전·컨트롤 UI 는 호출측에서 구성합니다(SDK 는 프레임만
그립니다). 예제 앱 example/ios 에
fullScreenCover + 가로 자동 회전 + 컨트롤 자동 숨김
패턴이 구현돼 있습니다.
.fullScreenCover(isPresented: $fullscreen) {
ZStack {
Color.black.ignoresSafeArea()
VisionVideoView(player: player, options: options)
.aspectRatio(16.0/9.0, contentMode: .fit)
}
}
API · VisionVideoView #
VisionVideoView(player: AVPlayer,
options: VisionOptions,
onLicense: ((LicenseState) -> Void)? = nil)
| 인자 | 설명 |
|---|---|
player |
재생을 제어하는 AVPlayer(사용자 소유).
currentItem 교체 자동 추종.
|
options |
VisionOptions — 프로필/강도/업스케일/라이선스
등
|
onLicense |
licenseKey 지정 시 상태 변화
콜백(메인스레드): .pending → .ok/.invalid
|
API · VisionEnhancer #
| 멤버 | 설명 |
|---|---|
init(player:options:) |
명령형 컨트롤러 생성(웹 enhance() 미러)
|
update(_ options:) |
옵션 갱신(프로필/강도/업스케일) |
setEnabled(_ :) |
효과 on/off 단축 |
getState() |
VisionState { enabled, profile, rendererKind, license,
uniforms }
|
licenseState |
현재 LicenseState |
destroy() |
렌더러 정리 |
API · VisionOptions #
웹 VideoEnhancementOptions 와 동일 필드명·의미. 개별
강도는 프로필 기본값을 덮어씁니다.
| 필드 | 타입 / 범위 | 설명 |
|---|---|---|
enabled |
Bool | 효과 on/off (기본 true) |
profile |
VisionProfile? | 프로필 프리셋(.default 등) |
sharpen contrast
cleanup anime
|
Double? 0..1 | 개별 강도 |
gamma |
Double? 0.5..2.0 | 감마 |
localContrast darkLift |
Double? 0..1 | 로컬 대비 / 암부 lift |
scanline |
ScanlineParams? | 스캔라인(enabled/intensity/spacing) |
upscale |
UpscaleParams? | 업스케일(algorithm/target/sharpness) |
edgeEnhancement |
EdgeEnhancementParams? | 엣지 강조 통합 API(.off/.classic/.rcas) |
cnn1 cnn |
Cnn1Params? / CnnParams? | CNN 복원(Metal compute) |
renderer |
VisionRenderer? | .auto / .metal (iOS 단일 백엔드) |
autoReduceOnLowEnd |
Bool? | 저사양 자동 감쇠(기본 true) |
licenseKey |
String? | 지정 시 효과 즉시 적용→2초 후 검증, 실패 시 OFF(원본) |
업스케일 enum — UpscaleAlgorithm:
.none/.nearest/.bilinear/.lanczos/.fsr ·
UpscaleTarget:
.source/.p720/.p1080/.p1440/.x2/.x3/.custom.
API · 타입 · Exports #
// 뷰/컨트롤러
VisionVideoView, VisionEnhancer, VisionMetalView, MetalRenderer
// 옵션/타입
VisionOptions, VisionProfile, VisionRenderer, UpscaleAlgorithm, UpscaleTarget,
EdgeAlgorithm, ScanlineParams, UpscaleParams, EdgeEnhancementParams,
Cnn1Params, CnnParams, CnnLayer, EnhancementUniforms, VisionState,
LicenseState, LicenseResult, LicenseClient
// 네임스페이스 (모듈명 충돌로 SGRVision 이 아니라 VisionSDK)
VisionSDK.version // SDK 버전
VisionSDK.specVersion // 프로필 스펙 버전
VisionSDK.profiles // 프로필 목록
라이선스 (번들 ID 바인딩) #
낙관적 게이팅 — licenseKey 지정 시 효과가
즉시 적용되고, 2초 후 비동기로 검증합니다. 통과하면
그대로 유지, 실패하면 효과를 끄고
원본으로 되돌립니다(결과는 프로세스 내 캐시 → 뷰 재생성 시
재요청 없음).
allowedOrigins 에 앱의 번들 ID 가 포함돼야
통과합니다(웹 도메인과 같은 리스트에 함께). localhost 면제 같은 건
없습니다.
Bundle.main.bundleIdentifier (Info.plist, 빌드/서명
시 고정)에서 직접 읽습니다. 개발자가 주입·조작할 수 있는
파라미터가 없습니다.
embedded.mobileprovision 이 있는 개발/Ad-hoc 빌드는
라이선스 검증을 건너뛰고 바로 구동됩니다.
App Store·TestFlight 등 릴리스 빌드만 검증되며, 출시 빌드는
이 신호를 위조할 수 없어 면제를 악용할 수 없습니다.
상태 조회:
// SwiftUI
VisionVideoView(player: player,
options: VisionOptions(profile: .default, licenseKey: key),
onLicense: { state in /* .none/.pending/.ok/.invalid */ })
// 명령형
enhancer.getState().license // LicenseState
체험 키 VSK-ZP02Z-K3FJ9-4C4DQ-8EM6A 는 번들 ID
com.sgr.vision.ios.example (예제 앱)에만
바인딩됩니다. 본인 앱은 번들 ID 를 등록한 키를
support@sgrsoft.com 으로
발급받으세요. 검증 서버 주소는 SDK 에 고정 내장됩니다.
CNN 화질 복원 #
외부 가중치(81 floats/layer)를 주입해 multi-layer CNN 으로 디테일을 복원합니다. iOS 는 단일 Metal 백엔드라 항상 compute 로 동작합니다(웹의 WebGPU 전용 제약 없음).
VisionOptions(
profile: .default,
cnn: CnnParams(enabled: true, layers: layers) // [CnnLayer]
)
Metal Toolchain #
SDK 셰이더는 Xcode 빌드(시뮬레이터·실기기) 시
default.metallib 로 컴파일됩니다.
cannot execute tool 'metal' 에러가 나면 최초 1회
Metal Toolchain 을 받습니다.
xcodebuild -downloadComponent MetalToolchain
MetalRenderer 는 컴파일된
default.metallib(Xcode) 와
.metal 소스(SwiftPM) 양쪽 로드를 지원합니다. 리소스가
누락되면 렌더러 생성이 실패하고 화면이 비어 보일 수 있습니다.
제약 · 한계 #
이 SDK 는 AVPlayer 프레임을 Metal 텍스처로 업로드해
처리합니다. 프레임을 읽을 수 없는 환경에는 적용되지 않으므로 도입
전 아래 제약을 확인하세요.
DRM(FairPlay) — 적용 불가, 원본 자동 폴백
asset.hasProtectedContent
+ 프레임 미수신 안전망)해 빈 화면 없이 원본을 그대로 재생합니다(AVPlayerLayer 폴백). 소스가 클리어로 바뀌면
자동 복귀합니다.
적용 가능: DRM 미적용(클리어) HLS·프로그레시브 스트림, 무료/프리뷰·광고 등 보호되지 않은 영상.
성능 · 환경
-
처리량은 기기 GPU 에 의존합니다. 저사양 기기는
autoReduceOnLowEnd(기본 true)로 강도를 자동 감쇠하지만 GPU·발열·배터리는 0 이 아닙니다. - 렌더 해상도(0.1.6+) — 패스 체인을 영상 해상도에서 처리한 뒤 출력 화면(drawable)으로 스케일합니다. 플레이어 뷰가 영상보다 작아도 선명도가 유지됩니다(Android 와 동일 동작).
- 렌더러 생성 실패(리소스 누락 등) 시 화면이 비어 보일 수 있으니 SPM/번들 구성을 확인하세요.
- 체감 화질·FPS·전력은 콘텐츠·코덱·기기에 따라 다르므로 도입 전 실기기 PoC 측정을 권장합니다.