From 5337b8b0427be3ec51c33087f39180a3810d1a19 Mon Sep 17 00:00:00 2001 From: saseungmin Date: Tue, 15 Jul 2025 22:04:48 +0900 Subject: [PATCH 1/2] feat: add support for multiple concurrent players - Enable simultaneous usage of multiple player instances - Implement independent instance management for each player - Support concurrent playback without interference --- .changeset/itchy-rooms-crash.md | 9 +++++++++ README-ko_kr.md | 22 ++++++++++++++++++++++ README.md | 22 ++++++++++++++++++++++ src/VimeoView.tsx | 2 +- src/VimeoView.web.tsx | 4 ++-- src/module/WebVimeoPlayerController.ts | 11 ++--------- src/module/WebviewVimeoPlayerController.ts | 13 ++----------- 7 files changed, 60 insertions(+), 23 deletions(-) create mode 100644 .changeset/itchy-rooms-crash.md diff --git a/.changeset/itchy-rooms-crash.md b/.changeset/itchy-rooms-crash.md new file mode 100644 index 0000000..c472e35 --- /dev/null +++ b/.changeset/itchy-rooms-crash.md @@ -0,0 +1,9 @@ +--- +"react-native-vimeo-bridge": minor +--- + +feat: add support for multiple concurrent players + +- Enable simultaneous usage of multiple player instances +- Implement independent instance management for each player +- Support concurrent playback without interference diff --git a/README-ko_kr.md b/README-ko_kr.md index 923f556..764e926 100644 --- a/README-ko_kr.md +++ b/README-ko_kr.md @@ -16,6 +16,7 @@ React Native에서 Vimeo 플레이어를 사용하기 위해 복잡한 설정과 - ✅ **풍부한 API** - Vimeo Player JS API의 모든 핵심 기능 지원 - ✅ **React Native 개발** - Expo의 Hook 기반 방식처럼, 직관적이고 사용하기 쉬운 API를 제공 - ✅ **Expo 호환** - Expo 프로젝트에서도 바로 사용 가능 +- ✅ **다중 인스턴스 지원** - 여러 플레이어를 독립적으로 관리 가능 ## 빠른 시작 @@ -142,6 +143,27 @@ function App() { } ``` +### 다중 플레이어 지원 + +여러 플레이어를 동시에 사용할 수 있습니다. +각 플레이어는 독립적인 인스턴스로 관리되며, 컴포넌트 unmount 시 자동으로 정리됩니다. + +```tsx +import { useVimeoPlayer, VimeoView } from 'react-native-vimeo-bridge'; + +function App() { + const player1 = useVimeoPlayer(vimeoUrl1); + const player2 = useVimeoPlayer(vimeoUrl2); + + return ( + + + + + ); +} +``` + ### 임베드 옵션 설정 Vimeo Player의 [임베드 옵션](https://developer.vimeo.com/player/sdk/embed)을 통해 초기 설정을 커스터마이징할 수 있습니다. diff --git a/README.md b/README.md index c385164..23f0cbd 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ With the lack of actively maintained Vimeo player libraries for React Native, `r - ✅ **Rich API Support** - Access to all core Vimeo Player JS API features - ✅ **React Native Development** - Provides an intuitive, easy-to-use Hook-based API, much like Expo's approach - ✅ **Expo Compatible** - Ready to use in Expo projects +- ✅ **Multiple instance support** - manage multiple players independently ## Quick Start @@ -142,6 +143,27 @@ function App() { } ``` +### Multiple Player Support + +Multiple players can be used simultaneously. +Each player is managed as an independent instance and automatically cleaned up when the component unmounts. + +```tsx +import { useVimeoPlayer, VimeoView } from 'react-native-vimeo-bridge'; + +function App() { + const player1 = useVimeoPlayer(vimeoUrl1); + const player2 = useVimeoPlayer(vimeoUrl2); + + return ( + + + + + ); +} +``` + ### Embed Options Customize initial settings through Vimeo Player [embed options](https://developer.vimeo.com/player/sdk/embed). diff --git a/src/VimeoView.tsx b/src/VimeoView.tsx index 99e086e..27ec852 100644 --- a/src/VimeoView.tsx +++ b/src/VimeoView.tsx @@ -213,7 +213,7 @@ function VimeoView({ player, height = 200, width = screenWidth, style, webViewPr useEffect(() => { if (isReady && webViewRef.current) { - const controller = WebviewVimeoPlayerController.getInstance(webViewRef); + const controller = WebviewVimeoPlayerController.createInstance(webViewRef); playerRef.current = controller; diff --git a/src/VimeoView.web.tsx b/src/VimeoView.web.tsx index 8d713cb..b36edca 100644 --- a/src/VimeoView.web.tsx +++ b/src/VimeoView.web.tsx @@ -16,7 +16,7 @@ function VimeoView({ player, height = 200, width, style, iframeStyle }: VimeoVie useEffect(() => { WebVimeoPlayerController.initialize().then(() => { setIsInitialized(true); - playerRef.current = WebVimeoPlayerController.getInstance(); + playerRef.current = WebVimeoPlayerController.createInstance(); }); }, []); @@ -24,7 +24,7 @@ function VimeoView({ player, height = 200, width, style, iframeStyle }: VimeoVie const source = player.getSource(); if (isInitialized && containerRef.current && source) { - const containerId = `vimeo-player`; + const containerId = `vimeo-player-${Date.now()}`; containerRef.current.id = containerId; const options = player.getOptions(); diff --git a/src/module/WebVimeoPlayerController.ts b/src/module/WebVimeoPlayerController.ts index 3847f41..fc2fe0f 100644 --- a/src/module/WebVimeoPlayerController.ts +++ b/src/module/WebVimeoPlayerController.ts @@ -2,14 +2,9 @@ import type { EmbedOptions, EventCallback, VimeoPlayer } from '../types/vimeo'; class WebVimeoPlayerController { private player: VimeoPlayer | null = null; - private static instance: WebVimeoPlayerController | null = null; - static getInstance(): WebVimeoPlayerController { - if (!WebVimeoPlayerController.instance) { - WebVimeoPlayerController.instance = new WebVimeoPlayerController(); - } - - return WebVimeoPlayerController.instance; + static createInstance(): WebVimeoPlayerController { + return new WebVimeoPlayerController(); } static initialize(): Promise { @@ -165,8 +160,6 @@ class WebVimeoPlayerController { } this.player = null; } - - WebVimeoPlayerController.instance = null; } } diff --git a/src/module/WebviewVimeoPlayerController.ts b/src/module/WebviewVimeoPlayerController.ts index 3b91832..6fdea5d 100644 --- a/src/module/WebviewVimeoPlayerController.ts +++ b/src/module/WebviewVimeoPlayerController.ts @@ -5,20 +5,13 @@ class WebviewVimeoPlayerController { private webViewRef: React.RefObject; private commandId: number = 0; private pendingCommands: Map void> = new Map(); - private static instance: WebviewVimeoPlayerController | null = null; constructor(webViewRef: React.RefObject) { this.webViewRef = webViewRef; } - static getInstance(webViewRef: React.RefObject): WebviewVimeoPlayerController { - if (!WebviewVimeoPlayerController.instance) { - WebviewVimeoPlayerController.instance = new WebviewVimeoPlayerController(webViewRef); - } else { - WebviewVimeoPlayerController.instance.webViewRef = webViewRef; - } - - return WebviewVimeoPlayerController.instance; + static createInstance(webViewRef: React.RefObject): WebviewVimeoPlayerController { + return new WebviewVimeoPlayerController(webViewRef); } getPendingCommands(): Map void> { @@ -148,8 +141,6 @@ class WebviewVimeoPlayerController { dispose(): void { this.pendingCommands.clear(); this.destroy(); - - WebviewVimeoPlayerController.instance = null; } } From 788f07fc854d3d912fde92843188168b7fd41403 Mon Sep 17 00:00:00 2001 From: saseungmin Date: Tue, 15 Jul 2025 22:13:24 +0900 Subject: [PATCH 2/2] refactor: suggested review --- src/VimeoView.web.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VimeoView.web.tsx b/src/VimeoView.web.tsx index b36edca..f570faa 100644 --- a/src/VimeoView.web.tsx +++ b/src/VimeoView.web.tsx @@ -24,7 +24,7 @@ function VimeoView({ player, height = 200, width, style, iframeStyle }: VimeoVie const source = player.getSource(); if (isInitialized && containerRef.current && source) { - const containerId = `vimeo-player-${Date.now()}`; + const containerId = `vimeo-player-${Math.random().toString(36).substring(2, 15)}`; containerRef.current.id = containerId; const options = player.getOptions();