@frameset/plex-player 1.0.6 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/vue/index.js DELETED
@@ -1,304 +0,0 @@
1
- /**
2
- * @frameset/plex-player - Vue Component
3
- * Professional Video Player by FRAMESET Studio
4
- * https://frameset.dev
5
- */
6
-
7
- import {
8
- defineComponent,
9
- ref,
10
- onMounted,
11
- onBeforeUnmount,
12
- watch,
13
- provide,
14
- inject,
15
- h
16
- } from 'vue';
17
-
18
- // Import core player
19
- import PlexPlayer from '../core/index.js';
20
-
21
- // Provide/inject key
22
- const PlexPlayerKey = Symbol('PlexPlayer');
23
-
24
- /**
25
- * Composable to access player instance
26
- */
27
- export function usePlexPlayer() {
28
- return inject(PlexPlayerKey, ref(null));
29
- }
30
-
31
- /**
32
- * PlexPlayer Vue Component
33
- */
34
- export const PlexPlayerVue = defineComponent({
35
- name: 'PlexPlayer',
36
-
37
- props: {
38
- src: {
39
- type: String,
40
- default: '',
41
- },
42
- playlist: {
43
- type: Array,
44
- default: () => [],
45
- },
46
- autoplay: {
47
- type: Boolean,
48
- default: false,
49
- },
50
- muted: {
51
- type: Boolean,
52
- default: false,
53
- },
54
- loop: {
55
- type: Boolean,
56
- default: false,
57
- },
58
- volume: {
59
- type: Number,
60
- default: 1,
61
- },
62
- poster: {
63
- type: String,
64
- default: '',
65
- },
66
- preload: {
67
- type: String,
68
- default: 'metadata',
69
- },
70
- keyboard: {
71
- type: Boolean,
72
- default: true,
73
- },
74
- touch: {
75
- type: Boolean,
76
- default: true,
77
- },
78
- pip: {
79
- type: Boolean,
80
- default: true,
81
- },
82
- cast: {
83
- type: Boolean,
84
- default: true,
85
- },
86
- fullscreen: {
87
- type: Boolean,
88
- default: true,
89
- },
90
- controlsHideDelay: {
91
- type: Number,
92
- default: 3000,
93
- },
94
- theme: {
95
- type: Object,
96
- default: () => ({}),
97
- },
98
- subtitles: {
99
- type: Object,
100
- default: () => ({}),
101
- },
102
- ads: {
103
- type: Object,
104
- default: () => ({}),
105
- },
106
- i18n: {
107
- type: Object,
108
- default: () => ({}),
109
- },
110
- },
111
-
112
- emits: [
113
- 'play',
114
- 'pause',
115
- 'ended',
116
- 'timeupdate',
117
- 'progress',
118
- 'volumechange',
119
- 'fullscreenchange',
120
- 'error',
121
- 'ready',
122
- ],
123
-
124
- setup(props, { emit, slots, expose }) {
125
- const containerRef = ref(null);
126
- const playerRef = ref(null);
127
- const isReady = ref(false);
128
-
129
- // Provide player to child components
130
- provide(PlexPlayerKey, playerRef);
131
-
132
- onMounted(() => {
133
- if (!containerRef.value) return;
134
-
135
- // Create player instance
136
- const player = new PlexPlayer({
137
- container: containerRef.value,
138
- autoplay: props.autoplay,
139
- muted: props.muted,
140
- loop: props.loop,
141
- volume: props.volume,
142
- poster: props.poster,
143
- preload: props.preload,
144
- keyboard: props.keyboard,
145
- touch: props.touch,
146
- pip: props.pip,
147
- cast: props.cast,
148
- fullscreen: props.fullscreen,
149
- controlsHideDelay: props.controlsHideDelay,
150
- theme: props.theme,
151
- subtitles: props.subtitles,
152
- ads: props.ads,
153
- i18n: props.i18n,
154
- });
155
-
156
- playerRef.value = player;
157
-
158
- // Bind events
159
- player.on('play', () => emit('play'));
160
- player.on('pause', () => emit('pause'));
161
- player.on('ended', () => emit('ended'));
162
- player.on('timeupdate', (data) => emit('timeupdate', data.currentTime));
163
- player.on('progress', (data) => emit('progress', data.buffered));
164
- player.on('volumechange', (data) => emit('volumechange', data));
165
- player.on('fullscreenchange', (data) => emit('fullscreenchange', data.isFullscreen));
166
- player.on('error', (error) => emit('error', error));
167
-
168
- isReady.value = true;
169
- emit('ready', player);
170
-
171
- // Load initial source
172
- if (props.src) {
173
- player.load(props.src);
174
- } else if (props.playlist.length > 0) {
175
- player.loadPlaylist(props.playlist);
176
- }
177
- });
178
-
179
- onBeforeUnmount(() => {
180
- if (playerRef.value) {
181
- playerRef.value.destroy();
182
- playerRef.value = null;
183
- }
184
- });
185
-
186
- // Watch for src changes
187
- watch(() => props.src, (newSrc) => {
188
- if (playerRef.value && newSrc) {
189
- playerRef.value.load(newSrc);
190
- }
191
- });
192
-
193
- // Watch for playlist changes
194
- watch(() => props.playlist, (newPlaylist) => {
195
- if (playerRef.value && newPlaylist?.length > 0) {
196
- playerRef.value.loadPlaylist(newPlaylist);
197
- }
198
- }, { deep: true });
199
-
200
- // Watch for volume changes
201
- watch(() => props.volume, (newVolume) => {
202
- if (playerRef.value) {
203
- playerRef.value.setVolume(newVolume);
204
- }
205
- });
206
-
207
- // Watch for muted changes
208
- watch(() => props.muted, (newMuted) => {
209
- if (playerRef.value) {
210
- if (newMuted) {
211
- playerRef.value.mute();
212
- } else {
213
- playerRef.value.unmute();
214
- }
215
- }
216
- });
217
-
218
- // Expose methods
219
- expose({
220
- play: () => playerRef.value?.play(),
221
- pause: () => playerRef.value?.pause(),
222
- togglePlay: () => playerRef.value?.togglePlay(),
223
- seek: (time) => playerRef.value?.seek(time),
224
- seekPercent: (percent) => playerRef.value?.seekPercent(percent),
225
- setVolume: (vol) => playerRef.value?.setVolume(vol),
226
- getVolume: () => playerRef.value?.getVolume(),
227
- mute: () => playerRef.value?.mute(),
228
- unmute: () => playerRef.value?.unmute(),
229
- toggleMute: () => playerRef.value?.toggleMute(),
230
- setPlaybackRate: (rate) => playerRef.value?.setPlaybackRate(rate),
231
- enterFullscreen: () => playerRef.value?.enterFullscreen(),
232
- exitFullscreen: () => playerRef.value?.exitFullscreen(),
233
- toggleFullscreen: () => playerRef.value?.toggleFullscreen(),
234
- enterPiP: () => playerRef.value?.enterPiP(),
235
- exitPiP: () => playerRef.value?.exitPiP(),
236
- togglePiP: () => playerRef.value?.togglePiP(),
237
- cast: () => playerRef.value?.cast(),
238
- getState: () => playerRef.value?.getState(),
239
- getPlayer: () => playerRef.value,
240
- next: () => playerRef.value?.next(),
241
- previous: () => playerRef.value?.previous(),
242
- playAt: (index) => playerRef.value?.playAt(index),
243
- });
244
-
245
- return () => h(
246
- 'div',
247
- {
248
- ref: containerRef,
249
- class: 'plex-player-container',
250
- style: {
251
- width: '100%',
252
- aspectRatio: '16 / 9',
253
- position: 'relative',
254
- },
255
- },
256
- slots.default?.()
257
- );
258
- },
259
- });
260
-
261
- // Composables
262
- export function usePlexPlayerState() {
263
- const player = usePlexPlayer();
264
- const state = ref(null);
265
-
266
- watch(player, (p) => {
267
- if (!p) return;
268
-
269
- const updateState = () => {
270
- state.value = p.getState();
271
- };
272
-
273
- p.on('timeupdate', updateState);
274
- p.on('play', updateState);
275
- p.on('pause', updateState);
276
- p.on('volumechange', updateState);
277
-
278
- updateState();
279
- }, { immediate: true });
280
-
281
- return state;
282
- }
283
-
284
- export function usePlexPlayerTime() {
285
- const player = usePlexPlayer();
286
- const time = ref({ current: 0, duration: 0 });
287
-
288
- watch(player, (p) => {
289
- if (!p) return;
290
-
291
- p.on('timeupdate', (data) => {
292
- time.value = {
293
- current: data.currentTime,
294
- duration: data.duration,
295
- };
296
- });
297
- }, { immediate: true });
298
-
299
- return time;
300
- }
301
-
302
- // Named exports
303
- export { PlexPlayer };
304
- export default PlexPlayerVue;