vidply 1.0.5 → 1.0.7
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/LICENSE +22 -22
- package/README.md +608 -593
- package/dist/vidply.css +2422 -1807
- package/dist/vidply.esm.js +1480 -93
- package/dist/vidply.esm.js.map +3 -3
- package/dist/vidply.esm.min.js +3 -3
- package/dist/vidply.esm.min.meta.json +48 -25
- package/dist/vidply.js +1480 -93
- package/dist/vidply.js.map +3 -3
- package/dist/vidply.min.css +1 -1
- package/dist/vidply.min.js +3 -3
- package/dist/vidply.min.meta.json +48 -25
- package/package.json +2 -2
- package/src/controls/CaptionManager.js +278 -248
- package/src/controls/ControlBar.js +2033 -2026
- package/src/controls/KeyboardManager.js +233 -233
- package/src/controls/SettingsDialog.js +417 -417
- package/src/controls/TranscriptManager.js +1803 -728
- package/src/core/Player.js +1616 -1134
- package/src/i18n/i18n.js +66 -66
- package/src/i18n/translations.js +616 -561
- package/src/icons/Icons.js +187 -183
- package/src/index.js +95 -95
- package/src/renderers/HLSRenderer.js +302 -302
- package/src/renderers/HTML5Renderer.js +298 -298
- package/src/renderers/VimeoRenderer.js +257 -257
- package/src/renderers/YouTubeRenderer.js +274 -274
- package/src/styles/vidply.css +2422 -1807
- package/src/utils/DOMUtils.js +154 -154
- package/src/utils/EventEmitter.js +53 -53
- package/src/utils/StorageManager.js +156 -0
- package/src/utils/TimeUtils.js +87 -87
|
@@ -1,274 +1,274 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* YouTube Renderer
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export class YouTubeRenderer {
|
|
6
|
-
constructor(player) {
|
|
7
|
-
this.player = player;
|
|
8
|
-
this.youtube = null;
|
|
9
|
-
this.videoId = null;
|
|
10
|
-
this.isReady = false;
|
|
11
|
-
this.iframe = null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
async init() {
|
|
15
|
-
// Extract video ID from URL
|
|
16
|
-
this.videoId = this.extractVideoId(this.player.element.src);
|
|
17
|
-
|
|
18
|
-
if (!this.videoId) {
|
|
19
|
-
throw new Error('Invalid YouTube URL');
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Load YouTube IFrame API
|
|
23
|
-
await this.loadYouTubeAPI();
|
|
24
|
-
|
|
25
|
-
// Create iframe
|
|
26
|
-
this.createIframe();
|
|
27
|
-
|
|
28
|
-
// Initialize player
|
|
29
|
-
await this.initializePlayer();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
extractVideoId(url) {
|
|
33
|
-
const patterns = [
|
|
34
|
-
/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\s]+)/,
|
|
35
|
-
/youtube\.com\/embed\/([^&\s]+)/
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
for (const pattern of patterns) {
|
|
39
|
-
const match = url.match(pattern);
|
|
40
|
-
if (match && match[1]) {
|
|
41
|
-
return match[1];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async loadYouTubeAPI() {
|
|
49
|
-
// Check if API is already loaded
|
|
50
|
-
if (window.YT && window.YT.Player) {
|
|
51
|
-
return Promise.resolve();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
// Check if script is already being loaded
|
|
56
|
-
if (window.onYouTubeIframeAPIReady) {
|
|
57
|
-
const originalCallback = window.onYouTubeIframeAPIReady;
|
|
58
|
-
window.onYouTubeIframeAPIReady = () => {
|
|
59
|
-
originalCallback();
|
|
60
|
-
resolve();
|
|
61
|
-
};
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Load the API script
|
|
66
|
-
const tag = document.createElement('script');
|
|
67
|
-
tag.src = 'https://www.youtube.com/iframe_api';
|
|
68
|
-
|
|
69
|
-
window.onYouTubeIframeAPIReady = () => {
|
|
70
|
-
resolve();
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
tag.onerror = () => reject(new Error('Failed to load YouTube API'));
|
|
74
|
-
|
|
75
|
-
const firstScriptTag = document.getElementsByTagName('script')[0];
|
|
76
|
-
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
createIframe() {
|
|
81
|
-
// Hide original element
|
|
82
|
-
this.player.element.style.display = 'none';
|
|
83
|
-
|
|
84
|
-
// Create container for iframe
|
|
85
|
-
this.iframe = document.createElement('div');
|
|
86
|
-
this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;
|
|
87
|
-
this.iframe.style.width = '100%';
|
|
88
|
-
this.iframe.style.height = '100%';
|
|
89
|
-
|
|
90
|
-
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
async initializePlayer() {
|
|
94
|
-
return new Promise((resolve) => {
|
|
95
|
-
this.youtube = new window.YT.Player(this.iframe.id, {
|
|
96
|
-
videoId: this.videoId,
|
|
97
|
-
width: '100%',
|
|
98
|
-
height: '100%',
|
|
99
|
-
playerVars: {
|
|
100
|
-
controls: 0,
|
|
101
|
-
disablekb: 1,
|
|
102
|
-
fs: 0,
|
|
103
|
-
modestbranding: 1,
|
|
104
|
-
rel: 0,
|
|
105
|
-
showinfo: 0,
|
|
106
|
-
iv_load_policy: 3,
|
|
107
|
-
autoplay: this.player.options.autoplay ? 1 : 0,
|
|
108
|
-
mute: this.player.options.muted ? 1 : 0,
|
|
109
|
-
start: this.player.options.startTime || 0
|
|
110
|
-
},
|
|
111
|
-
events: {
|
|
112
|
-
onReady: (event) => {
|
|
113
|
-
this.isReady = true;
|
|
114
|
-
this.attachEvents();
|
|
115
|
-
resolve();
|
|
116
|
-
},
|
|
117
|
-
onStateChange: (event) => this.handleStateChange(event),
|
|
118
|
-
onError: (event) => this.handleError(event)
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
attachEvents() {
|
|
125
|
-
// Set up polling for time updates (YouTube doesn't provide timeupdate events)
|
|
126
|
-
this.timeUpdateInterval = setInterval(() => {
|
|
127
|
-
if (this.isReady && this.youtube) {
|
|
128
|
-
const currentTime = this.youtube.getCurrentTime();
|
|
129
|
-
const duration = this.youtube.getDuration();
|
|
130
|
-
|
|
131
|
-
this.player.state.currentTime = currentTime;
|
|
132
|
-
this.player.state.duration = duration;
|
|
133
|
-
|
|
134
|
-
this.player.emit('timeupdate', currentTime);
|
|
135
|
-
}
|
|
136
|
-
}, 250);
|
|
137
|
-
|
|
138
|
-
// Initial metadata
|
|
139
|
-
if (this.youtube.getDuration) {
|
|
140
|
-
this.player.state.duration = this.youtube.getDuration();
|
|
141
|
-
this.player.emit('loadedmetadata');
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
handleStateChange(event) {
|
|
146
|
-
const states = window.YT.PlayerState;
|
|
147
|
-
|
|
148
|
-
switch (event.data) {
|
|
149
|
-
case states.PLAYING:
|
|
150
|
-
this.player.state.playing = true;
|
|
151
|
-
this.player.state.paused = false;
|
|
152
|
-
this.player.state.ended = false;
|
|
153
|
-
this.player.state.buffering = false;
|
|
154
|
-
this.player.emit('play');
|
|
155
|
-
this.player.emit('playing');
|
|
156
|
-
|
|
157
|
-
if (this.player.options.onPlay) {
|
|
158
|
-
this.player.options.onPlay.call(this.player);
|
|
159
|
-
}
|
|
160
|
-
break;
|
|
161
|
-
|
|
162
|
-
case states.PAUSED:
|
|
163
|
-
this.player.state.playing = false;
|
|
164
|
-
this.player.state.paused = true;
|
|
165
|
-
this.player.emit('pause');
|
|
166
|
-
|
|
167
|
-
if (this.player.options.onPause) {
|
|
168
|
-
this.player.options.onPause.call(this.player);
|
|
169
|
-
}
|
|
170
|
-
break;
|
|
171
|
-
|
|
172
|
-
case states.ENDED:
|
|
173
|
-
this.player.state.playing = false;
|
|
174
|
-
this.player.state.paused = true;
|
|
175
|
-
this.player.state.ended = true;
|
|
176
|
-
this.player.emit('ended');
|
|
177
|
-
|
|
178
|
-
if (this.player.options.onEnded) {
|
|
179
|
-
this.player.options.onEnded.call(this.player);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (this.player.options.loop) {
|
|
183
|
-
this.youtube.seekTo(0);
|
|
184
|
-
this.youtube.playVideo();
|
|
185
|
-
}
|
|
186
|
-
break;
|
|
187
|
-
|
|
188
|
-
case states.BUFFERING:
|
|
189
|
-
this.player.state.buffering = true;
|
|
190
|
-
this.player.emit('waiting');
|
|
191
|
-
break;
|
|
192
|
-
|
|
193
|
-
case states.CUED:
|
|
194
|
-
this.player.emit('loadedmetadata');
|
|
195
|
-
break;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
handleError(event) {
|
|
200
|
-
const errors = {
|
|
201
|
-
2: 'Invalid video ID',
|
|
202
|
-
5: 'HTML5 player error',
|
|
203
|
-
100: 'Video not found',
|
|
204
|
-
101: 'Video not allowed to be played in embedded players',
|
|
205
|
-
150: 'Video not allowed to be played in embedded players'
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
const error = new Error(errors[event.data] || 'YouTube player error');
|
|
209
|
-
this.player.handleError(error);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
play() {
|
|
213
|
-
if (this.isReady && this.youtube) {
|
|
214
|
-
this.youtube.playVideo();
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
pause() {
|
|
219
|
-
if (this.isReady && this.youtube) {
|
|
220
|
-
this.youtube.pauseVideo();
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
seek(time) {
|
|
225
|
-
if (this.isReady && this.youtube) {
|
|
226
|
-
this.youtube.seekTo(time, true);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
setVolume(volume) {
|
|
231
|
-
if (this.isReady && this.youtube) {
|
|
232
|
-
this.youtube.setVolume(volume * 100);
|
|
233
|
-
this.player.state.volume = volume;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
setMuted(muted) {
|
|
238
|
-
if (this.isReady && this.youtube) {
|
|
239
|
-
if (muted) {
|
|
240
|
-
this.youtube.mute();
|
|
241
|
-
} else {
|
|
242
|
-
this.youtube.unMute();
|
|
243
|
-
}
|
|
244
|
-
this.player.state.muted = muted;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
setPlaybackSpeed(speed) {
|
|
249
|
-
if (this.isReady && this.youtube) {
|
|
250
|
-
this.youtube.setPlaybackRate(speed);
|
|
251
|
-
this.player.state.playbackSpeed = speed;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
destroy() {
|
|
256
|
-
if (this.timeUpdateInterval) {
|
|
257
|
-
clearInterval(this.timeUpdateInterval);
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (this.youtube && this.youtube.destroy) {
|
|
261
|
-
this.youtube.destroy();
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (this.iframe && this.iframe.parentNode) {
|
|
265
|
-
this.iframe.parentNode.removeChild(this.iframe);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// Show original element
|
|
269
|
-
if (this.player.element) {
|
|
270
|
-
this.player.element.style.display = '';
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
1
|
+
/**
|
|
2
|
+
* YouTube Renderer
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export class YouTubeRenderer {
|
|
6
|
+
constructor(player) {
|
|
7
|
+
this.player = player;
|
|
8
|
+
this.youtube = null;
|
|
9
|
+
this.videoId = null;
|
|
10
|
+
this.isReady = false;
|
|
11
|
+
this.iframe = null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async init() {
|
|
15
|
+
// Extract video ID from URL
|
|
16
|
+
this.videoId = this.extractVideoId(this.player.element.src);
|
|
17
|
+
|
|
18
|
+
if (!this.videoId) {
|
|
19
|
+
throw new Error('Invalid YouTube URL');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Load YouTube IFrame API
|
|
23
|
+
await this.loadYouTubeAPI();
|
|
24
|
+
|
|
25
|
+
// Create iframe
|
|
26
|
+
this.createIframe();
|
|
27
|
+
|
|
28
|
+
// Initialize player
|
|
29
|
+
await this.initializePlayer();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
extractVideoId(url) {
|
|
33
|
+
const patterns = [
|
|
34
|
+
/(?:youtube\.com\/watch\?v=|youtu\.be\/)([^&\s]+)/,
|
|
35
|
+
/youtube\.com\/embed\/([^&\s]+)/
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
for (const pattern of patterns) {
|
|
39
|
+
const match = url.match(pattern);
|
|
40
|
+
if (match && match[1]) {
|
|
41
|
+
return match[1];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async loadYouTubeAPI() {
|
|
49
|
+
// Check if API is already loaded
|
|
50
|
+
if (window.YT && window.YT.Player) {
|
|
51
|
+
return Promise.resolve();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
// Check if script is already being loaded
|
|
56
|
+
if (window.onYouTubeIframeAPIReady) {
|
|
57
|
+
const originalCallback = window.onYouTubeIframeAPIReady;
|
|
58
|
+
window.onYouTubeIframeAPIReady = () => {
|
|
59
|
+
originalCallback();
|
|
60
|
+
resolve();
|
|
61
|
+
};
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Load the API script
|
|
66
|
+
const tag = document.createElement('script');
|
|
67
|
+
tag.src = 'https://www.youtube.com/iframe_api';
|
|
68
|
+
|
|
69
|
+
window.onYouTubeIframeAPIReady = () => {
|
|
70
|
+
resolve();
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
tag.onerror = () => reject(new Error('Failed to load YouTube API'));
|
|
74
|
+
|
|
75
|
+
const firstScriptTag = document.getElementsByTagName('script')[0];
|
|
76
|
+
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
createIframe() {
|
|
81
|
+
// Hide original element
|
|
82
|
+
this.player.element.style.display = 'none';
|
|
83
|
+
|
|
84
|
+
// Create container for iframe
|
|
85
|
+
this.iframe = document.createElement('div');
|
|
86
|
+
this.iframe.id = `youtube-player-${Math.random().toString(36).substr(2, 9)}`;
|
|
87
|
+
this.iframe.style.width = '100%';
|
|
88
|
+
this.iframe.style.height = '100%';
|
|
89
|
+
|
|
90
|
+
this.player.element.parentNode.insertBefore(this.iframe, this.player.element);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async initializePlayer() {
|
|
94
|
+
return new Promise((resolve) => {
|
|
95
|
+
this.youtube = new window.YT.Player(this.iframe.id, {
|
|
96
|
+
videoId: this.videoId,
|
|
97
|
+
width: '100%',
|
|
98
|
+
height: '100%',
|
|
99
|
+
playerVars: {
|
|
100
|
+
controls: 0,
|
|
101
|
+
disablekb: 1,
|
|
102
|
+
fs: 0,
|
|
103
|
+
modestbranding: 1,
|
|
104
|
+
rel: 0,
|
|
105
|
+
showinfo: 0,
|
|
106
|
+
iv_load_policy: 3,
|
|
107
|
+
autoplay: this.player.options.autoplay ? 1 : 0,
|
|
108
|
+
mute: this.player.options.muted ? 1 : 0,
|
|
109
|
+
start: this.player.options.startTime || 0
|
|
110
|
+
},
|
|
111
|
+
events: {
|
|
112
|
+
onReady: (event) => {
|
|
113
|
+
this.isReady = true;
|
|
114
|
+
this.attachEvents();
|
|
115
|
+
resolve();
|
|
116
|
+
},
|
|
117
|
+
onStateChange: (event) => this.handleStateChange(event),
|
|
118
|
+
onError: (event) => this.handleError(event)
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
attachEvents() {
|
|
125
|
+
// Set up polling for time updates (YouTube doesn't provide timeupdate events)
|
|
126
|
+
this.timeUpdateInterval = setInterval(() => {
|
|
127
|
+
if (this.isReady && this.youtube) {
|
|
128
|
+
const currentTime = this.youtube.getCurrentTime();
|
|
129
|
+
const duration = this.youtube.getDuration();
|
|
130
|
+
|
|
131
|
+
this.player.state.currentTime = currentTime;
|
|
132
|
+
this.player.state.duration = duration;
|
|
133
|
+
|
|
134
|
+
this.player.emit('timeupdate', currentTime);
|
|
135
|
+
}
|
|
136
|
+
}, 250);
|
|
137
|
+
|
|
138
|
+
// Initial metadata
|
|
139
|
+
if (this.youtube.getDuration) {
|
|
140
|
+
this.player.state.duration = this.youtube.getDuration();
|
|
141
|
+
this.player.emit('loadedmetadata');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
handleStateChange(event) {
|
|
146
|
+
const states = window.YT.PlayerState;
|
|
147
|
+
|
|
148
|
+
switch (event.data) {
|
|
149
|
+
case states.PLAYING:
|
|
150
|
+
this.player.state.playing = true;
|
|
151
|
+
this.player.state.paused = false;
|
|
152
|
+
this.player.state.ended = false;
|
|
153
|
+
this.player.state.buffering = false;
|
|
154
|
+
this.player.emit('play');
|
|
155
|
+
this.player.emit('playing');
|
|
156
|
+
|
|
157
|
+
if (this.player.options.onPlay) {
|
|
158
|
+
this.player.options.onPlay.call(this.player);
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
|
|
162
|
+
case states.PAUSED:
|
|
163
|
+
this.player.state.playing = false;
|
|
164
|
+
this.player.state.paused = true;
|
|
165
|
+
this.player.emit('pause');
|
|
166
|
+
|
|
167
|
+
if (this.player.options.onPause) {
|
|
168
|
+
this.player.options.onPause.call(this.player);
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
|
|
172
|
+
case states.ENDED:
|
|
173
|
+
this.player.state.playing = false;
|
|
174
|
+
this.player.state.paused = true;
|
|
175
|
+
this.player.state.ended = true;
|
|
176
|
+
this.player.emit('ended');
|
|
177
|
+
|
|
178
|
+
if (this.player.options.onEnded) {
|
|
179
|
+
this.player.options.onEnded.call(this.player);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (this.player.options.loop) {
|
|
183
|
+
this.youtube.seekTo(0);
|
|
184
|
+
this.youtube.playVideo();
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
|
|
188
|
+
case states.BUFFERING:
|
|
189
|
+
this.player.state.buffering = true;
|
|
190
|
+
this.player.emit('waiting');
|
|
191
|
+
break;
|
|
192
|
+
|
|
193
|
+
case states.CUED:
|
|
194
|
+
this.player.emit('loadedmetadata');
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
handleError(event) {
|
|
200
|
+
const errors = {
|
|
201
|
+
2: 'Invalid video ID',
|
|
202
|
+
5: 'HTML5 player error',
|
|
203
|
+
100: 'Video not found',
|
|
204
|
+
101: 'Video not allowed to be played in embedded players',
|
|
205
|
+
150: 'Video not allowed to be played in embedded players'
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
const error = new Error(errors[event.data] || 'YouTube player error');
|
|
209
|
+
this.player.handleError(error);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
play() {
|
|
213
|
+
if (this.isReady && this.youtube) {
|
|
214
|
+
this.youtube.playVideo();
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
pause() {
|
|
219
|
+
if (this.isReady && this.youtube) {
|
|
220
|
+
this.youtube.pauseVideo();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
seek(time) {
|
|
225
|
+
if (this.isReady && this.youtube) {
|
|
226
|
+
this.youtube.seekTo(time, true);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
setVolume(volume) {
|
|
231
|
+
if (this.isReady && this.youtube) {
|
|
232
|
+
this.youtube.setVolume(volume * 100);
|
|
233
|
+
this.player.state.volume = volume;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
setMuted(muted) {
|
|
238
|
+
if (this.isReady && this.youtube) {
|
|
239
|
+
if (muted) {
|
|
240
|
+
this.youtube.mute();
|
|
241
|
+
} else {
|
|
242
|
+
this.youtube.unMute();
|
|
243
|
+
}
|
|
244
|
+
this.player.state.muted = muted;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
setPlaybackSpeed(speed) {
|
|
249
|
+
if (this.isReady && this.youtube) {
|
|
250
|
+
this.youtube.setPlaybackRate(speed);
|
|
251
|
+
this.player.state.playbackSpeed = speed;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
destroy() {
|
|
256
|
+
if (this.timeUpdateInterval) {
|
|
257
|
+
clearInterval(this.timeUpdateInterval);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (this.youtube && this.youtube.destroy) {
|
|
261
|
+
this.youtube.destroy();
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (this.iframe && this.iframe.parentNode) {
|
|
265
|
+
this.iframe.parentNode.removeChild(this.iframe);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Show original element
|
|
269
|
+
if (this.player.element) {
|
|
270
|
+
this.player.element.style.display = '';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|