EMB visionVISION
데모 바로가기

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 코드를 생성합니다.

ChatGPT Claude Copilot Cursor
# 에이전트에게 그대로 요청
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()
SwiftUI 옵션 변경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)
}
iPadOS 도 동일 SwiftUI 코드로 동작합니다(NSViewRepresentable). 예제는 swift run 으로 즉시 실행할 수 있습니다.

AVPlayer · 소스 전환 #

HLS 는 AVPlayer 가 기본 지원하므로 별도 플레이어가 필요 없습니다. 같은 AVPlayerreplaceCurrentItem 으로 소스를 바꿔도 SDK 가 자동 재연결합니다(KVO).

let player = AVPlayer()                 // 빈 플레이어 먼저
// VisionVideoView(player: player, ...) 를 띄운 뒤
player.replaceCurrentItem(with: AVPlayerItem(url: newURL)) // 끊김 없이 전환
소스 전환·지연 로드에도 프레임이 끊기지 않도록 VisionMetalViewplayer.currentItem 교체를 감지해 비디오 출력을 다시 연결합니다.

전체화면 #

전체화면·회전·컨트롤 UI 는 호출측에서 구성합니다(SDK 는 프레임만 그립니다). 예제 앱 example/iosfullScreenCover + 가로 자동 회전 + 컨트롤 자동 숨김 패턴이 구현돼 있습니다.

.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초 후 비동기로 검증합니다. 통과하면 그대로 유지, 실패하면 효과를 끄고 원본으로 되돌립니다(결과는 프로세스 내 캐시 → 뷰 재생성 시 재요청 없음).

웹과의 핵심 차이 — 네이티브는 도메인(Origin) 대신 앱 번들 ID 를 서버에 전송합니다. 라이선스의 allowedOrigins 에 앱의 번들 ID 가 포함돼야 통과합니다(웹 도메인과 같은 리스트에 함께). localhost 면제 같은 건 없습니다.
번들 ID 위변조 방지 — app 식별자는 SDK 가 Bundle.main.bundleIdentifier (Info.plist, 빌드/서명 시 고정)에서 직접 읽습니다. 개발자가 주입·조작할 수 있는 파라미터가 없습니다.
개발 빌드 면제 (웹 localhost 대응) — 시뮬레이터이거나 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) — 적용 불가, 원본 자동 폴백

FairPlay 등 DRM 으로 보호된 영상에는 화질 개선을 적용할 수 없습니다. 보호 콘텐츠는 secure surface 로 렌더링돼 프레임 캡처가 차단되기 때문입니다. 대신 SDK 가 보호 콘텐츠를 자동 감지(asset.hasProtectedContent + 프레임 미수신 안전망)해 빈 화면 없이 원본을 그대로 재생합니다(AVPlayerLayer 폴백). 소스가 클리어로 바뀌면 자동 복귀합니다.

적용 가능: DRM 미적용(클리어) HLS·프로그레시브 스트림, 무료/프리뷰·광고 등 보호되지 않은 영상.

성능 · 환경

  • 처리량은 기기 GPU 에 의존합니다. 저사양 기기는 autoReduceOnLowEnd(기본 true)로 강도를 자동 감쇠하지만 GPU·발열·배터리는 0 이 아닙니다.
  • 렌더 해상도(0.1.6+) — 패스 체인을 영상 해상도에서 처리한 뒤 출력 화면(drawable)으로 스케일합니다. 플레이어 뷰가 영상보다 작아도 선명도가 유지됩니다(Android 와 동일 동작).
  • 렌더러 생성 실패(리소스 누락 등) 시 화면이 비어 보일 수 있으니 SPM/번들 구성을 확인하세요.
  • 체감 화질·FPS·전력은 콘텐츠·코덱·기기에 따라 다르므로 도입 전 실기기 PoC 측정을 권장합니다.