---
url: /ko/guide/getting-started/overview.md
---
# 개요

React Native에서 YouTube 플레이어를 붙이려면 iframe 설정, 이벤트 연결, 재생 제어, 플랫폼 차이를 한 번에 처리해야 하는 경우가 많습니다.
`react-native-youtube-bridge`는 [YouTube IFrame Player API](https://developers.google.com/youtube/iframe_api_reference)를 React Native에 맞는 방식으로 감싼 라이브러리이며, 핵심은 세 가지입니다.
- `useYouTubePlayer`로 플레이어 인스턴스를 만든다.
- `YoutubeView`로 플레이어를 렌더링한다.
- `useYouTubeEvent`로 상태, 진행률, 음소거, 에러를 구독한다.
## 왜 이 라이브러리를 쓰나
- 네이티브 YouTube 플레이어 모듈 없이 사용 가능
- iOS, Android, Web 지원
- 현대적인 React 코드에 잘 맞는 Hook 기반 API
- 빠른 임베드부터 고급 외부 WebView 전략까지 확장 가능
## 핵심 사용 모델
```tsx
import { YoutubeView, useYouTubePlayer } from 'react-native-youtube-bridge';
function App() {
const player = useYouTubePlayer('AbZH7XWDW_k');
return ;
}
```
플레이어 인스턴스가 API의 중심입니다.
- 생성 시 옵션을 설정하고
- `YoutubeView`에 전달해 렌더링하고
- 메서드로 제어하고
- `useYouTubeEvent`로 변화를 구독합니다.
---
url: /ko/guide/getting-started/installation.md
---
# 설치
먼저 메인 패키지를 설치합니다.
```sh [npm]
npm install react-native-youtube-bridge
```
```sh [yarn]
yarn add react-native-youtube-bridge
```
```sh [pnpm]
pnpm add react-native-youtube-bridge
```
```sh [bun]
bun add react-native-youtube-bridge
```
```sh [deno]
deno add npm:react-native-youtube-bridge
```
## peer dependency
iOS와 Android에서는 `react-native-webview`가 필요합니다.
```sh [npm]
npm install react-native-webview
```
```sh [yarn]
yarn add react-native-webview
```
```sh [pnpm]
pnpm add react-native-webview
```
```sh [bun]
bun add react-native-webview
```
```sh [deno]
deno add npm:react-native-webview
```
## 최소 조건
| 패키지 | 버전 |
| ---------------------- | ---------- |
| `react` | `>=16.8.0` |
| `react-native` | `>=0.60.0` |
| `react-native-webview` | `>=11.0.0` |
## 설치 후 사용 가능한 것
- `useYouTubePlayer`
- `useYouTubeEvent`
- `YoutubeView`
- 공개 타입들
- `useYoutubeOEmbed`
일반적인 사용만 한다면 `@react-native-youtube-bridge/web`는 바로 설치할 필요가 없습니다.
---
url: /ko/guide/getting-started/quick-start.md
---
# 빠른 시작
## 예제 & 데모
- [🤖 Expo Snack](https://snack.expo.dev/@harang/react-native-youtube-bridge) - Expo Snack에서 바로 체험
가장 작은 예제는 아래와 같습니다.
```tsx
import { YoutubeView, useYouTubePlayer } from 'react-native-youtube-bridge';
function App() {
const player = useYouTubePlayer('AbZH7XWDW_k');
return ;
}
```
## source 입력 형태
```tsx
const playerA = useYouTubePlayer('AbZH7XWDW_k');
const playerB = useYouTubePlayer({ videoId: 'AbZH7XWDW_k' });
const playerC = useYouTubePlayer({ url: 'https://www.youtube.com/watch?v=AbZH7XWDW_k' });
```
## 초기 옵션 추가
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k', {
autoplay: true,
controls: true,
playsinline: true,
rel: false,
muted: true,
});
```
## 다음 단계
- source 모델은 [기본 사용법](/ko/guide/usage/basic-usage.md)에서 확인하세요.
- 이벤트 구독은 [이벤트 처리](/ko/guide/usage/handling-events.md)에서 확인하세요.
- 재생 제어는 [플레이어 제어](/ko/guide/usage/player-controls.md)에서 확인하세요.
---
url: /ko/guide/getting-started/ai.md
---
# AI
AI가 이 라이브러리의 기능, 버전별 문서, 프로젝트 규칙을 더 잘 이해해서 개발이나 트러블슈팅 과정에서 더 정확한 도움을 줄 수 있도록, 이 프로젝트는 다음 기능들을 제공합니다.
## llms.txt
[`llms.txt`](https://llmstxt.org/)는 LLM이 프로젝트 문서를 더 쉽게 탐색하고 활용할 수 있도록 돕는 표준입니다. 이 사이트는 다음 파일들을 제공합니다.
- [llms.txt](https://react-native-youtube-bridge-docs.pages.dev/ko/llms.txt): `2.x` 문서용 구조화된 인덱스 파일
```txt
https://react-native-youtube-bridge-docs.pages.dev/ko/llms.txt
```
- [llms-full.txt](https://react-native-youtube-bridge-docs.pages.dev/ko/llms-full.txt): `2.x` 문서 전체를 하나로 합친 파일
```txt
https://react-native-youtube-bridge-docs.pages.dev/ko/llms-full.txt
```
사용 목적에 따라 적절한 파일을 선택하면 됩니다.
- `llms.txt`는 더 작고 가벼워서 필요한 문서만 선택적으로 가져올 때 적합합니다.
- `llms-full.txt`는 해당 버전 문서 전체를 한 번에 제공하므로, 넓은 범위의 이해나 큰 리팩터링 작업에 적합합니다.
## Markdown docs
모든 문서 페이지는 AI에게 직접 전달할 수 있는 Markdown 버전도 함께 제공합니다.
예시:
```txt
https://react-native-youtube-bridge-docs.pages.dev/ko/guide/getting-started/overview.md
https://react-native-youtube-bridge-docs.pages.dev/ko/guide/getting-started/quick-start.md
https://react-native-youtube-bridge-docs.pages.dev/ko/guide/usage/player-controls.md
```
특정 기능 하나만 물어볼 때는 전체 문서보다 관련 Markdown 페이지 하나를 제공하는 편이 더 효율적입니다.
---
url: /ko/guide/usage/basic-usage.md
---
# 기본 사용법
## 플레이어 만들기
```tsx
import { YoutubeView, useYouTubePlayer } from 'react-native-youtube-bridge';
function App() {
const player = useYouTubePlayer('AbZH7XWDW_k');
return ;
}
```
## source 입력 형태
```tsx
useYouTubePlayer('AbZH7XWDW_k');
useYouTubePlayer({ videoId: 'AbZH7XWDW_k' });
useYouTubePlayer({ url: 'https://www.youtube.com/watch?v=AbZH7XWDW_k' });
```
source가 유효하지 않으면 에러 이벤트가 발생합니다.
---
url: /ko/guide/usage/player-controls.md
---
# 플레이어 제어
`useYouTubePlayer`가 반환하는 플레이어 객체에는 직접 호출할 수 있는 메서드, 비동기 getter, 동적 비디오 로드 메서드가 포함됩니다.
> 비동기 getter 메서드는 플레이어가 준비된 뒤 사용하는 것을 권장합니다. `YoutubeView`가 내부 controller를 연결하기 전에는 getter가 `undefined`를 반환할 수 있으므로, 값에 의존해야 한다면 `ready` 이벤트 이후에 호출하세요.
## 재생 제어
```tsx
player.play();
player.pause();
player.stop();
player.seekTo(30, true);
```
## 볼륨과 음소거
```tsx
player.setVolume(50);
player.mute();
player.unMute();
const volume = await player.getVolume();
const muted = await player.isMuted();
```
## 상태와 비디오 정보 조회
```tsx
const [currentTime, duration, state, loadedFraction, url, embedCode] = await Promise.all([
player.getCurrentTime(),
player.getDuration(),
player.getPlayerState(),
player.getVideoLoadedFraction(),
player.getVideoUrl(),
player.getVideoEmbedCode(),
]);
```
## 재생 속도
```tsx
const currentRate = await player.getPlaybackRate();
const availableRates = await player.getAvailablePlaybackRates();
player.setPlaybackRate(1.5);
```
## 다른 비디오 로드 또는 큐잉
```tsx
player.loadVideoById('M7lc1UVf-VE');
player.cueVideoById('M7lc1UVf-VE', 30);
```
- `loadVideoById`는 바로 로드를 시작합니다.
- `cueVideoById`는 재생 없이 다음 비디오를 준비합니다.
## 크기 변경
```tsx
player.setSize(640, 360);
```
초기 렌더 이후 imperative하게 크기를 바꿔야 할 때 유용합니다.
---
url: /ko/guide/usage/handling-events.md
---
# 이벤트 처리
`useYouTubeEvent`는 reactive state 구독과 callback 기반 side effect를 모두 지원합니다.
## 1. state 방식
```tsx
const playbackRate = useYouTubeEvent(player, 'playbackRateChange', 1);
const isMuted = useYouTubeEvent(player, 'muteChange', false);
const progress = useYouTubeEvent(player, 'progress', 1000);
```
## 2. callback 방식
```tsx
useYouTubeEvent(player, 'ready', (playerInfo) => {
console.log('ready', playerInfo);
});
useYouTubeEvent(player, 'error', (error) => {
console.error(error);
});
useYouTubeEvent(player, 'autoplayBlocked', () => {
console.log('autoplay blocked');
});
```
## callback dependency array
callback가 바뀌는 값에 의존한다면 네 번째 인자로 dependency array를 전달하세요.
```tsx
useYouTubeEvent(
player,
'stateChange',
(state) => {
console.log('state', state, analyticsLabel);
},
[analyticsLabel],
);
```
## 이벤트 목록
| 이벤트 | payload | 설명 |
| ----------------------- | ----------------- | -------------------------------------------------------------- |
| `ready` | `PlayerInfo` | 첫 전체 플레이어 스냅샷 |
| `stateChange` | `PlayerState` | `UNSTARTED`, `PLAYING`, `PAUSED`, `BUFFERING`, `ENDED`, `CUED` |
| `error` | `YoutubeError` | YouTube 또는 bridge 레벨 에러 |
| `progress` | `ProgressData` | `currentTime`, `duration`, `percentage`, `loadedFraction` |
| `playbackRateChange` | `number` | 현재 재생 속도 |
| `playbackQualityChange` | `PlaybackQuality` | 현재 화질 |
| `autoplayBlocked` | `undefined` | 브라우저/플랫폼 autoplay 제한 |
| `muteChange` | `boolean` | 현재 음소거 상태 |
## `ready` payload
`ready`에서는 아래 같은 초기 정보를 받을 수 있습니다.
- `availablePlaybackRates`
- `availableQualityLevels`
- `currentTime`
- `duration`
- `muted`
- `playbackQuality`
- `playbackRate`
- `playerState`
- `size`
- `volume`
## `progress` payload
```ts
{
currentTime: number;
duration: number;
percentage: number;
loadedFraction: number;
}
```
### progress interval 동작
- 세 번째 인자는 밀리초 단위 interval
- 기본값은 `1000`
- interval 기반 업데이트가 필요 없으면 `0`
```tsx
const progress = useYouTubeEvent(player, 'progress', 500);
```
`seekTo()` 이후에도 progress가 한 번 더 빠르게 갱신되어 UI가 바로 따라오도록 설계되어 있습니다.
## mute tracking 주의점
`muteChange`를 구독할 때만 muted tracking이 활성화됩니다.
---
url: /ko/guide/usage/player-config.md
---
# 플레이어 설정
초기 옵션은 `useYouTubePlayer`의 두 번째 인자로 전달합니다.
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k', {
autoplay: true,
controls: true,
playsinline: true,
rel: false,
muted: true,
});
```
## 주요 옵션
- `autoplay`
- `controls`
- `loop`
- `muted`
- `startTime`
- `endTime`
- `playsinline`
- `rel`
- `origin`
---
url: /ko/guide/usage/styling-and-layout.md
---
# 스타일과 레이아웃
`YoutubeView`가 실제 렌더링 표면을 담당합니다.
```tsx
```
## 주요 스타일 props
```tsx
```
- `iframeStyle`: Web 전용
- `webViewStyle`: iOS / Android 전용
- `webViewProps`: iOS / Android 전용
## `webViewProps` 자세히
`webViewProps`는 bridge 기본 동작을 깨지 않으면서 네이티브 WebView를 튜닝할 때 유용합니다.
```tsx
```
다만 bridge가 `ref`, `source.uri`, `style`, `onMessage`, `javaScriptEnabled`, `onError`는 직접 관리하므로 `webViewProps`는 부분 커스터마이징 레이어로 생각하는 게 좋습니다.
---
url: /ko/guide/usage/inline-html-vs-webview.md
---
# Inline HTML vs WebView
iOS와 Android에서는 두 가지 렌더링 전략을 지원합니다.
## Inline HTML 모드
```tsx
```
- 기본 모드
- 앱 내부에서 HTML을 직접 로드
- 대부분의 앱에서 가장 단순한 선택
## 외부 WebView 모드
```tsx
```
- 외부 플레이어 페이지를 로드
- inline HTML 제약이나 호스팅 요구사항이 있을 때 유용
- 기본 호스팅 페이지: `https://react-native-youtube-bridge.pages.dev`
## `webViewUrl` 의미
- `useInlineHtml: true`일 때는 HTML `baseUrl`
- `useInlineHtml: false`일 때는 WebView `uri` override
## 정확한 origin 규칙
커스텀 origin을 쓰는 경우 문서 origin과 YouTube iframe `origin`을 정확히 맞춰야 합니다.
inline HTML 모드에서는:
- `webViewUrl`이 HTML `baseUrl`이 되고
- iframe `origin`은 그 페이지 origin과 정확히 일치해야 하며
- port가 있다면 포함해야 하고
- `baseUrl`은 trailing slash를 포함하고
- `origin`은 trailing slash 없이 써야 합니다.
예시:
- base URL: `https://localhost:8081/`
- origin: `https://localhost:8081`
## 언제 외부 WebView로 전환할까
다음과 같다면 외부 WebView 모드를 우선 고려하세요.
- inline HTML에서 `embed not allowed`가 발생할 때
- 직접 호스팅하는 플레이어 페이지가 필요할 때
- 페이지 환경을 더 세밀하게 제어해야 할 때
---
url: /ko/guide/usage/custom-webview-player.md
---
# 커스텀 WebView 플레이어
직접 호스팅하는 외부 플레이어 페이지가 필요할 때만 `@react-native-youtube-bridge/web`를 사용하면 됩니다.
## 전형적인 흐름
1. `@react-native-youtube-bridge/web`로 작은 웹 플레이어 페이지 작성
2. 해당 페이지를 배포
3. `YoutubeView`의 `webViewUrl`로 전달
## 설치
```bash
npm install @react-native-youtube-bridge/web
```
## 최소 예제
```tsx
import { YoutubePlayer } from '@react-native-youtube-bridge/web';
function CustomPlayerPage() {
return ;
}
export default CustomPlayerPage;
```
## 네이티브에서 사용
```tsx
```
## query-string 계약
네이티브 `YoutubeView`는 외부 플레이어 페이지를 로드할 때 URL query에 아래 값을 붙입니다.
- `videoId`
- `startTime`
- `endTime`
- `origin`
- `autoplay`
- `controls`
- `loop`
- `muted`
- `playsinline`
- `rel`
즉 커스텀 페이지는 다음 중 하나여야 합니다.
- stock `@react-native-youtube-bridge/web` 플레이어를 그대로 사용하거나
- 직접 wrapper를 만들더라도 같은 query contract를 유지해야 합니다.
## 메시지 브리지 기대사항
React Native WebView 안에서 실행될 때는 플레이어 이벤트와 command 결과를 `window.ReactNativeWebView.postMessage(...)`로 다시 전달해야 합니다. stock `@react-native-youtube-bridge/web`를 쓰면 이 부분은 이미 처리되어 있습니다.
---
url: /ko/guide/usage/metadata-with-oembed.md
---
# oEmbed 메타데이터
재생 자체에는 필요 없지만, UI를 더 풍부하게 만들 때 유용합니다.
`useYoutubeOEmbed`는 YouTube URL에 대한 메타데이터를 가져오며 아래 값을 반환합니다.
- `oEmbed`
- `isLoading`
- `error`
```tsx
const { oEmbed, isLoading, error } = useYoutubeOEmbed(
'https://www.youtube.com/watch?v=AbZH7XWDW_k',
);
```
## 자주 쓰는 `oEmbed` 필드
- `title`
- `thumbnail_url`
- `author_name`
- `author_url`
- `provider_name`
- `width`
- `height`
## 활용 예시
- 플레이어 위에 비디오 제목 표시
- 썸네일/미리보기 카드 구성
- 더 풍부한 미디어 목록 UI 구성
---
url: /ko/guide/usage/errors-and-troubleshooting.md
---
# 오류와 트러블슈팅
## 잘못된 source
다음 형식 중 하나를 사용하세요.
- `'AbZH7XWDW_k'`
- `{ videoId: 'AbZH7XWDW_k' }`
- `{ url: 'https://www.youtube.com/watch?v=AbZH7XWDW_k' }`
## 자주 보는 에러 코드
| 코드 | 의미 |
| ------ | ----------------------- |
| `2` | 잘못된 YouTube 파라미터 값 |
| `5` | HTML5 플레이어 오류 |
| `100` | 비디오를 찾을 수 없거나 비공개 |
| `101` | embedded playback 불가 |
| `150` | embedded playback 제한 |
| `1000` | WebView 메시지 파싱 실패 |
| `1001` | 네이티브 WebView 로딩 오류 |
| `1002` | 잘못된 YouTube 비디오 ID |
| `1003` | YouTube API 로딩 실패 |
| `1004` | 알 수 없는 bridge/player 오류 |
## autoplay blocked
오디오가 켜져 있으면 환경에 따라 autoplay가 막힐 수 있습니다. autoplay가 중요하면 `muted`와 함께 테스트하고, 필요하면 `autoplayBlocked` 이벤트를 받아 UI에서 대응하세요.
## `embed not allowed`
inline HTML 모드에서 YouTube iframe 제한이 걸리면:
1. `useInlineHtml={false}`로 전환
2. 기본 호스팅 페이지 또는 커스텀 페이지 사용
3. 대상 `origin`이 호스팅된 페이지 origin과 맞는지 확인
## origin mismatch
커스텀 `webViewUrl`을 쓰는 경우, 페이지 origin과 iframe `origin`을 맞춰야 합니다. 페이지 자체가 열려도 origin mismatch로 iframe 동작이 깨질 수 있습니다.
## WebView 로딩 문제
네이티브 WebView가 로드되지 않는다면:
- URL에 실제로 접근 가능한지 확인하고
- 호스팅한 페이지가 올바른 플레이어를 렌더링하는지 확인하고
- 전달한 source URL과 origin 설정이 맞는지 확인하고
- `webViewProps.source.headers`나 호스팅 규칙이 로드를 방해하지 않는지도 확인하세요.
---
url: /ko/guide/usage/api-reference.md
---
# API 레퍼런스
## 주요 export
```ts
export {
useYouTubeEvent,
useYouTubePlayer,
YoutubeView,
useYoutubeOEmbed,
} from 'react-native-youtube-bridge';
```
## 핵심 API
- `useYouTubePlayer(source, config?)`
- `YoutubeView`
- `useYouTubeEvent(player, event, ...)`
- `useYoutubeOEmbed(url?)`
## 플레이어 메서드
- `play`, `pause`, `stop`, `seekTo`
- `setVolume`, `getVolume`, `mute`, `unMute`, `isMuted`
- `getCurrentTime`, `getDuration`, `getVideoUrl`, `getVideoEmbedCode`
- `getPlaybackRate`, `setPlaybackRate`, `getAvailablePlaybackRates`
- `getPlayerState`, `getVideoLoadedFraction`
- `loadVideoById`, `cueVideoById`, `setSize`
> 비동기 getter 메서드의 값을 안정적으로 사용해야 한다면 `ready` 이벤트 이후에 호출하세요. 렌더 표면이 아직 연결되기 전에는 `undefined`를 반환할 수 있습니다.
## 이벤트
- `ready`
- `stateChange`
- `error`
- `progress`
- `playbackRateChange`
- `playbackQualityChange`
- `autoplayBlocked`
- `muteChange`
## 중요한 타입
- `YoutubeSource`
- `YoutubePlayerVars`
- `YoutubeError`
- `ProgressData`
- `PlayerInfo`
- `PlayerState`
- `YoutubeViewProps`
## `YoutubeView` props
### `player`
`useYouTubePlayer`에서 반환된 `YoutubePlayer` 인스턴스입니다. 훅과 메서드 호출에서 사용하는 컨트롤러를 렌더 표면에 연결하려면 같은 인스턴스를 `YoutubeView`에 전달하세요.
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k');
return ;
```
### `width` / `height`
플레이어의 렌더링 크기를 제어합니다. 두 prop 모두 숫자, `'auto'`, 또는 `'100%'` 같은 퍼센트 문자열을 받을 수 있습니다.
```tsx
```
### `style`
플레이어 컨테이너에 React Native view 스타일을 적용합니다.
```tsx
```
### `iframeStyle` (web only)
React Native Web에서 iframe wrapper에 CSS 속성을 적용합니다.
### `useInlineHtml` (iOS / Android, 기본값: `true`)
`true`이면 네이티브 WebView에 inline HTML을 전달합니다. `false`이면 WebView가 기본 호스팅 플레이어 페이지(`https://react-native-youtube-bridge.pages.dev`) 또는 `webViewUrl`로 전달한 URL을 로드합니다.
### `webViewUrl` (iOS / Android)
WebView source URL을 재정의하거나, `useInlineHtml`이 `true`일 때 HTML 콘텐츠의 `baseUrl`로 사용됩니다.
inline HTML을 사용할 때는 `webViewUrl`의 origin이 YouTube IFrame API `origin` 값과 정확히 일치해야 합니다. 필요한 경우 포트를 포함하고, `baseUrl`에는 trailing slash를 붙이고, `origin`에는 trailing slash를 붙이지 마세요.
### `webViewStyle` (iOS / Android)
내부 WebView에 직접 React Native view 스타일을 적용합니다.
### `webViewProps` (iOS / Android)
라이브러리가 내부적으로 제어하는 prop은 유지하면서 내부 WebView에 추가 prop을 전달합니다. `ref`, `source`, `style`, `onMessage`, `javaScriptEnabled`, `onError`는 내부에서 관리되므로 덮어쓸 수 없습니다.
## `YoutubeViewProps` type
[Go to source](https://github.com/react-native-bridges/react-native-youtube-bridge/blob/main/packages/react-native-youtube-bridge/src/types/youtube.ts#L17)
````tsx title="YoutubeViewProps"
/**
* `YoutubeView` 컴포넌트의 props입니다.
* @example
* ```tsx
* const player = useYouTubePlayer('AbZH7XWDW_k');
*
*
* ```
*/
export type YoutubeViewProps = {
/**
* 플레이어 인스턴스입니다.
* @example
* ```tsx
* const player = useYouTubePlayer('AbZH7XWDW_k');
*
*
* ```
*/
player: YoutubePlayer;
/**
* 플레이어의 너비입니다.
*/
width?: number | 'auto' | `${number}%`;
/**
* 플레이어의 높이입니다.
*/
height?: number | 'auto' | `${number}%`;
/**
* 플레이어의 스타일입니다.
*/
style?: StyleProp;
/**
* iframe wrapper의 스타일입니다.
* @platform web
*/
iframeStyle?: CSSProperties;
/**
* true로 설정하면 플레이어가 inline HTML을 사용합니다.
* @remarks
* false이면 플레이어가 기본 URI(https://react-native-youtube-bridge.pages.dev)의 webview를 사용합니다.
* 커스텀 webview를 사용하려면 `webViewUrl`을 직접 설정하세요.
* @defaultValue true
* @platform ios, android
*/
useInlineHtml?: boolean;
/**
* WebView source로 사용할 URL입니다.
* @remarks
* `useInlineHtml`이 `true`이면 이 값은 HTML 콘텐츠의 `baseUrl`로 설정됩니다.
* 이 경우 `webViewUrl`의 origin은 YouTube IFrame API `origin`과 정확히 일치해야 합니다.
* - 필요한 경우 포트를 포함하세요. (예: baseUrl `https://localhost:8081/` ⇄ origin `https://localhost:8081`).
* - `baseUrl`에는 trailing slash를 사용하되, `origin`에는 사용하지 마세요. (scheme + host [+ port] only).
*
* `useInlineHtml`이 `false`이면 이 값은 WebView source의 기본 URI(https://react-native-youtube-bridge.pages.dev)를 대체합니다.
* @platform ios, android
*/
webViewUrl?: string;
/**
* WebView의 스타일입니다.
* @platform ios, android
*/
webViewStyle?: StyleProp;
/**
* WebView에 전달할 props입니다.
* @platform ios, android
*/
webViewProps?: Omit<
WebViewProps,
'ref' | 'source' | 'style' | 'onMessage' | 'javaScriptEnabled' | 'onError'
> & {
source?: Omit;
};
};
````
---
url: /ko/guide/migration-from-1.x.md
---
# 1.x에서 마이그레이션
이 문서는 `react-native-youtube-bridge` 1.x에서 2.x로 이동하는 방법을 설명합니다.
2.x API는 `expo-audio`, `expo-video` 같은 현대적인 Expo API처럼 Hook 중심으로 다시 설계되었습니다.
## 변경 사항 개요
| 항목 | 1.x | 2.x |
| ------- | ---------------------------- | ---------------------------------- |
| API 스타일 | imperative, ref 기반 | declarative, hook 기반 |
| 렌더링 API | `YoutubePlayer` 컴포넌트 | `useYouTubePlayer` + `YoutubeView` |
| 이벤트 처리 | callback props | `useYouTubeEvent` hook |
| 상태 관리 | 직접 `useState` 관리 | reactive event subscription |
| 플레이어 제어 | `playerRef.current.method()` | `player.method()` |
| 초기 설정 | 컴포넌트 props / `playerVars` | hook config |
## 1. 컴포넌트 API 교체
### 이전 방식: 1.x
```tsx
import { YoutubePlayer } from 'react-native-youtube-bridge';
;
```
### 현재 방식: 2.x
```tsx
import { YoutubeView, useYouTubePlayer } from 'react-native-youtube-bridge';
const player = useYouTubePlayer('AbZH7XWDW_k', {
autoplay: true,
controls: true,
playsinline: true,
rel: false,
muted: true,
});
;
```
## 2. 플레이어 설정을 `useYouTubePlayer`로 이동
1.x에서는 대부분의 플레이어 옵션을 컴포넌트의 `playerVars`로 전달했습니다.
```tsx
```
2.x에서는 같은 옵션을 `useYouTubePlayer`의 두 번째 인자로 전달합니다.
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k', {
autoplay: true,
controls: true,
muted: true,
});
;
```
`height`, `width`, `style`, `iframeStyle`, `webViewStyle`, `webViewProps`, `useInlineHtml`, `webViewUrl` 같은 렌더링 관련 prop은 `YoutubeView`에 남겨둡니다.
## 3. 이벤트를 `useYouTubeEvent`로 이동
`useYouTubeEvent`는 state-style 구독과 callback-style side effect를 모두 지원합니다.
### 이전 방식: 1.x callback props
```tsx
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const [playbackRate, setPlaybackRate] = useState(1);
const [availableRates, setAvailableRates] = useState([1]);
const handleReady = useCallback((playerInfo) => {
if (playerInfo?.availablePlaybackRates) {
setAvailableRates(playerInfo.availablePlaybackRates);
}
}, []);
const handleStateChange = useCallback((state) => {
setIsPlaying(state === PlayerState.PLAYING);
}, []);
const handleProgress = useCallback((progress) => {
setCurrentTime(progress.currentTime);
setDuration(progress.duration);
}, []);
;
```
### 현재 방식: 2.x event hook
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k');
// State-style 구독
const playbackRate = useYouTubeEvent(player, 'playbackRateChange', 1);
const progress = useYouTubeEvent(player, 'progress', 1000);
const state = useYouTubeEvent(player, 'stateChange');
const currentTime = progress?.currentTime ?? 0;
const duration = progress?.duration ?? 0;
const isPlaying = state === PlayerState.PLAYING;
// Callback-style side effect
const [availableRates, setAvailableRates] = useState([1]);
useYouTubeEvent(player, 'ready', (playerInfo) => {
if (playerInfo.availablePlaybackRates) {
setAvailableRates(playerInfo.availablePlaybackRates);
}
});
useYouTubeEvent(player, 'autoplayBlocked', () => {
console.log('Autoplay was blocked');
});
useYouTubeEvent(player, 'error', (error) => {
console.error('Player error:', error);
});
return ;
```
## 4. ref 기반 제어를 직접 메서드 호출로 교체
### 이전 방식: 1.x ref methods
```tsx
const playerRef = useRef(null);
const play = () => playerRef.current?.play();
const pause = () => playerRef.current?.pause();
const stop = () => playerRef.current?.stop();
const seekTo = (time: number) => playerRef.current?.seekTo(time, true);
const setVolume = (volume: number) => playerRef.current?.setVolume(volume);
const mute = () => playerRef.current?.mute();
const unMute = () => playerRef.current?.unMute();
const getPlayerInfo = async () => {
const currentTime = await playerRef.current?.getCurrentTime();
const duration = await playerRef.current?.getDuration();
const state = await playerRef.current?.getPlayerState();
};
;
```
### 현재 방식: 2.x direct player methods
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k');
const play = () => player.play();
const pause = () => player.pause();
const stop = () => player.stop();
const seekTo = (time: number) => player.seekTo(time, true);
const setVolume = (volume: number) => player.setVolume(volume);
const mute = () => player.mute();
const unMute = () => player.unMute();
const getPlayerInfo = async () => {
const currentTime = await player.getCurrentTime();
const duration = await player.getDuration();
const state = await player.getPlayerState();
};
;
```
> 비동기 getter 값을 안정적으로 사용해야 한다면 `ready` 이벤트 이후에 호출하세요. `YoutubeView`가 내부 controller를 연결하기 전에는 getter가 `undefined`를 반환할 수 있습니다.
## 5. source 처리 방식 업데이트
두 버전 모두 비디오 ID와 YouTube URL을 지원하지만, 2.x에서는 `source`를 `YoutubePlayer`가 아니라 `useYouTubePlayer`에 전달합니다.
```tsx
const playerA = useYouTubePlayer('AbZH7XWDW_k');
const playerB = useYouTubePlayer({ videoId: 'AbZH7XWDW_k' });
const playerC = useYouTubePlayer({ url: 'https://youtube.com/watch?v=AbZH7XWDW_k' });
```
## 6. 렌더링 모드 마이그레이션
렌더링 모드 관련 prop은 렌더 표면에 속하므로 `YoutubeView`로 이동합니다.
### 이전 방식: 1.x
```tsx
```
### 현재 방식: 2.x
```tsx
const player = useYouTubePlayer('AbZH7XWDW_k');
;
```
## 마이그레이션 체크리스트
### 필수 변경
- [ ] `YoutubePlayer` import를 `YoutubeView`와 `useYouTubePlayer`로 교체
- [ ] `source`를 컴포넌트에서 `useYouTubePlayer(source)`로 이동
- [ ] `playerVars`를 `useYouTubePlayer(source, config)`의 두 번째 인자로 이동
- [ ] 이벤트 handler props를 `useYouTubeEvent` hook으로 교체
- [ ] 일반적인 재생 제어용 `useRef` 제거
- [ ] `playerRef.current?.method()`를 `player.method()`로 교체
- [ ] `height`, `width`, 스타일, WebView 옵션 같은 렌더링 prop은 `YoutubeView`에 유지
### 선택 개선
- [ ] 수동 `useState` 미러링을 state-style `useYouTubeEvent` 구독으로 단순화
- [ ] `useYouTubeEvent(player, 'error', ...)`로 에러 처리 추가
- [ ] muted 상태 UI가 필요하면 `muteChange` 사용
- [ ] 1.x prop 안정성을 위해서만 쓰던 불필요한 callback memoization 제거
## Breaking changes 요약
- `YoutubePlayer`가 `useYouTubePlayer` + `YoutubeView`로 대체되었습니다.
- 이벤트 prop은 제거되고 `useYouTubeEvent`를 사용합니다.
- ref 기반 제어는 직접 player method 호출로 바뀌었습니다.
- `playerVars`는 컴포넌트 prop에서 hook config로 이동했습니다.
- 직접 관리하던 상태는 reactive event 값으로 대체할 수 있습니다.
대부분의 앱은 화면 단위로 천천히 마이그레이션할 수 있습니다. 먼저 `useYouTubePlayer`로 player를 만들고 `YoutubeView`로 렌더링한 뒤, 이벤트와 ref 호출을 hook/direct method 방식으로 옮기면 됩니다.
---
url: /ko/index.md
---
# React Native Youtube Bridge
React Native를 위한 쉬운 YouTube 재생
> iOS, Android, Web를 지원하는 Hook 기반 YouTube IFrame 플레이어
[빠른 시작](/ko/guide/getting-started/quick-start.html) | [GitHub](https://github.com/react-native-bridges/react-native-youtube-bridge)
## Features
- 🌐 **크로스 플랫폼 플레이어**: iOS, Android, Web에서 동일한 플레이어 흐름을 사용할 수 있습니다.
- 🪝 **Hook 기반 API**: useYouTubePlayer로 플레이어를 만들고 YoutubeView로 렌더링합니다.
- 🧠 **타입 안전 이벤트**: ready, state, progress, mute, error 이벤트를 TypeScript와 함께 다룰 수 있습니다.
- 🎥 **네이티브 YouTube 모듈 불필요**: 네이티브 YouTube 플레이어 모듈 대신 YouTube IFrame Player API를 사용합니다.
- 🧩 **유연한 렌더링 모드**: 기본 inline HTML 또는 필요 시 외부 WebView 플레이어 페이지를 사용할 수 있습니다.
- 🚀 **Expo 친화적**: Expo와 최신 React Native 프로젝트에서 쉽게 사용할 수 있습니다.