@@ -28,7 +28,10 @@ class LiteYTEmbed extends HTMLElement {
28
28
* TODO: Consider using webp if supported, falling back to jpg
29
29
*/
30
30
if ( ! this . style . backgroundImage ) {
31
- this . style . backgroundImage = `url("https://i.ytimg.com/vi/${ this . videoId } /hqdefault.jpg")` ;
31
+ this . style =
32
+ `background-image: url('https://i.ytimg.com/vi/${ this . videoId } /hqdefault.jpg');
33
+ background-image: -webkit-image-set(url("https://i.ytimg.com/vi/${ this . videoId } /hqdefault.webp") 1x, url("https://i.ytimg.com/vi/${ this . videoId } /hqdefault.jpg") 1x);
34
+ background-image: image-set(url("https://i.ytimg.com/vi/${ this . videoId } /hqdefault.webp") type("image/webp"), url("https://i.ytimg.com/vi/${ this . videoId } /hqdefault.jpg") type("image/jpeg"));` ;
32
35
}
33
36
34
37
// Set up play button, and its visually hidden label
@@ -44,6 +47,7 @@ class LiteYTEmbed extends HTMLElement {
44
47
playBtnLabelEl . textContent = this . playLabel ;
45
48
playBtnEl . append ( playBtnLabelEl ) ;
46
49
}
50
+ playBtnEl . removeAttribute ( 'href' ) ;
47
51
48
52
// On hover (or tap), warm up the TCP connections we're (likely) about to use.
49
53
this . addEventListener ( 'pointerover' , LiteYTEmbed . warmConnections , { once : true } ) ;
@@ -52,6 +56,7 @@ class LiteYTEmbed extends HTMLElement {
52
56
// TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
53
57
// We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
54
58
this . addEventListener ( 'click' , this . addIframe ) ;
59
+ this . needsYTApiForAutoplay = navigator . vendor . includes ( 'Apple' ) || [ 'Firefox' , 'Android' ] . some ( userAgent => navigator . userAgent . includes ( userAgent ) ) ;
55
60
}
56
61
57
62
// // TODO: Support the the user changing the [videoid] attribute
@@ -95,13 +100,54 @@ class LiteYTEmbed extends HTMLElement {
95
100
LiteYTEmbed . preconnected = true ;
96
101
}
97
102
98
- addIframe ( e ) {
103
+ fetchYTPlayerApi ( ) {
104
+ if ( window . YT || ( window . YT && window . YT . Player ) ) return ;
105
+
106
+ this . ytApiPromise = new Promise ( ( res , rej ) => {
107
+ var el = document . createElement ( 'script' ) ;
108
+ el . src = 'https://www.youtube.com/iframe_api' ;
109
+ el . async = true ;
110
+ el . onload = ( ) => {
111
+ YT . ready ( res ) ;
112
+ } ;
113
+ el . onerror = rej ;
114
+ this . append ( el ) ;
115
+ } ) ;
116
+ }
117
+
118
+ async addYTPlayerIframe ( params ) {
119
+ this . fetchYTPlayerApi ( ) ;
120
+ await this . ytApiPromise ;
121
+
122
+ const videoPlaceholderEl = document . createElement ( 'div' )
123
+ this . append ( videoPlaceholderEl ) ;
124
+
125
+ const paramsObj = Object . fromEntries ( params . entries ( ) ) ;
126
+
127
+ new YT . Player ( videoPlaceholderEl , {
128
+ width : '100%' ,
129
+ videoId : this . videoId ,
130
+ playerVars : paramsObj ,
131
+ events : {
132
+ onReady : event => {
133
+ event . target . playVideo ( ) ;
134
+ } ,
135
+ } ,
136
+ } ) ;
137
+ }
138
+
139
+ async addIframe ( e ) {
99
140
if ( this . classList . contains ( 'lyt-activated' ) ) return ;
100
141
e . preventDefault ( ) ;
101
142
this . classList . add ( 'lyt-activated' ) ;
102
143
103
144
const params = new URLSearchParams ( this . getAttribute ( 'params' ) || [ ] ) ;
104
145
params . append ( 'autoplay' , '1' ) ;
146
+ params . append ( 'playsinline' , '1' ) ;
147
+
148
+ if ( this . needsYTApiForAutoplay ) {
149
+ return this . addYTPlayerIframe ( params ) ;
150
+ }
105
151
106
152
const iframeEl = document . createElement ( 'iframe' ) ;
107
153
iframeEl . width = 560 ;
0 commit comments