index.html 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Alt. youtube player</title>
  5. <style>
  6. /*
  7. Adapt to your needs,
  8. but it shouldn't be necessary to add much of css
  9. as the js-script will handle sizing.
  10. */
  11. * {padding: 0;margin: 0;} /* Not necessary when using frameworks */
  12. .player {
  13. width: 70vw;
  14. margin: 0 auto;
  15. }
  16. /*
  17. Note that the > restricts the img to be on the root level of .player
  18. */
  19. .player > img.thumb {
  20. width: 100%;
  21. }
  22. .player > iframe {
  23. width: 100%;
  24. height: 100%;
  25. }
  26. .player.play {
  27. cursor: pointer;
  28. }
  29. .player.stop {
  30. cursor: not-allowed;
  31. }
  32. .player.loading {
  33. cursor: wait;
  34. }
  35. </style>
  36. <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  37. </head>
  38. <body>
  39. <!--
  40. A player MUST:
  41. - Have a class «player»
  42. - Have a child element of img
  43. - with the class «thumb»
  44. - Have a child of the iframe
  45. - that has the query-param «enablejsapi=1»
  46. -->
  47. <div class="player">
  48. <img class="thumb" src="./thumb.png" alt="Thumbnail" />
  49. <iframe src="https://www.youtube-nocookie.com/embed/dcsvMySGmS8?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe>
  50. </div>
  51. <!-- additional players -->
  52. <div class="player">
  53. <img class="thumb" src="./thumb.png" alt="Thumbnail" />
  54. <iframe src="https://www.youtube-nocookie.com/embed/pouODQkJQG0?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe>
  55. </div>
  56. <div class="player">
  57. <img class="thumb" src="./thumb.png" alt="Thumbnail" />
  58. <iframe src="https://www.youtube-nocookie.com/embed/Y-JQ-RCyPpQ?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe>
  59. </div>
  60. <div class="player">
  61. <img class="thumb" src="./thumb.png" alt="Thumbnail" />
  62. <iframe src="https://www.youtube-nocookie.com/embed/4-079YIasck?enablejsapi=1" frameborder="0" allow="autoplay; encrypted-media; gyroscope" allowfullscreen></iframe>
  63. </div>
  64. <!-- You need this before the </body>-tag (closing) -->
  65. <script>
  66. // Hack to load Youtube iframe_api
  67. jQuery.getScript("http://www.youtube.com/iframe_api")
  68. var ytd = $.Deferred();
  69. window.onYouTubeIframeAPIReady = function () {
  70. ytd.resolve(window.YT);
  71. };
  72. $(document).ready(function () {
  73. // Store all instances of «Youtube Players»
  74. var ytp = [];
  75. // When a player opens
  76. var playerOpen = function (i, player) {
  77. if (!ytp[i])
  78. return;
  79. // Remove thumb and show iframe
  80. player.children('.thumb').slideUp();
  81. player.children('iframe').slideDown({
  82. complete: function () {
  83. // When fully opened, plat video and change cursor
  84. ytp[i].playVideo()
  85. player.removeClass('play loading').addClass('stop');
  86. }
  87. });
  88. // Close all the players that might be open.
  89. $('.player').each(function (idx) {
  90. if (i == idx) return;
  91. playerClose(i, $(this));
  92. })
  93. }
  94. // When a player is closing
  95. var playerClose = function (i, player) {
  96. if (!ytp[i])
  97. return;
  98. // Stop the video
  99. ytp[i].stopVideo();
  100. // Hide iframe and show thumg
  101. player.children('iframe').slideUp()
  102. player.children('.thumb').slideDown(function() {
  103. player.removeClass('stop loading').addClass('play');
  104. });
  105. }
  106. // Make sure Iframe has the same size as the thumb-img
  107. var adoptThumbSizeToIframe = function (player) {
  108. var ytvid = player.children('iframe');
  109. var thumb = player.children('.thumb');
  110. var hidden = thumb.is(':hidden');
  111. // Hack to read size
  112. if (hidden)
  113. thumb.show();
  114. // Adopt the size of the thumbnail to the iframe
  115. ytvid.css({
  116. height: thumb.height(),
  117. width: thumb.width(),
  118. });
  119. if (hidden)
  120. thumb.hide();
  121. }
  122. // On scroll, check that we are withing bounding. Close if not.
  123. window.addEventListener('scroll', function (e) {
  124. var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
  125. var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
  126. var d = $(document).scrollTop();
  127. $('.player').each(function (i) {
  128. if ($(this).children('iframe:visible').length == 0)
  129. return; // player not open (already showing thumb)
  130. var x = $(this).offset()['top'];
  131. var xoff = $(this).height() / 15;
  132. if ((x + $(this).height() - xoff) < d || (x + xoff) > (d + h))
  133. playerClose(i, $(this));
  134. /*
  135. No horizontal test... but...
  136. var y = $(this).offset()['left'];
  137. var yoff = ($(this).width() / 15);
  138. */
  139. })
  140. })
  141. window.addEventListener('resize', function () {
  142. $('.player').each(function() {
  143. console.log("Resize");
  144. adoptThumbSizeToIframe($(this));
  145. })
  146. })
  147. // Youtube API is reacy
  148. ytd.done(function (YT) {
  149. /*
  150. Initialize player on all of them.
  151. Could be optimized and wait with init until the player should start,
  152. and destroy it when it's closed.
  153. */
  154. $(".player").each(function (i) {
  155. var player = $(this).addClass('loading');
  156. var ytvid = player.children('iframe').hide();
  157. adoptThumbSizeToIframe(player);
  158. // Generate and add id to the iframe
  159. ytvid.attr('id', 'player-' + (i+1));
  160. ytp.push(new YT.Player(ytvid.attr('id'), {
  161. events: {
  162. 'onReady': function (e) {
  163. player.removeClass('loading').addClass('play');
  164. player.bind('click', function () {
  165. playerOpen(i, player);
  166. })
  167. },
  168. 'onStateChange': function (e) {
  169. // Add event specific data here
  170. switch (e.data) {
  171. case YT.PlayerState.ENDED:
  172. playerClose(i, player)
  173. break;
  174. case YT.PlayerState.PLAYING:
  175. // console.log("PLAYING");
  176. break;
  177. case YT.PlayerState.PAUSED:
  178. player.removeClass('stop loading').addClass('play');
  179. break;
  180. case YT.PlayerState.BUFFERING:
  181. player.removeClass('stop play').addClass('loading');
  182. break;
  183. case YT.PlayerState.CUED:
  184. //console.log("CUED");
  185. break;
  186. }
  187. },
  188. }
  189. }));
  190. })
  191. })
  192. });
  193. </script>
  194. </body>
  195. </html>