blueimp-gallery-youtube.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * blueimp Gallery YouTube Video Factory JS
  3. * https://github.com/blueimp/Gallery
  4. *
  5. * Copyright 2013, Sebastian Tschan
  6. * https://blueimp.net
  7. *
  8. * Licensed under the MIT license:
  9. * https://opensource.org/licenses/MIT
  10. */
  11. /* global define, YT */
  12. ;(function (factory) {
  13. 'use strict'
  14. if (typeof define === 'function' && define.amd) {
  15. // Register as an anonymous AMD module:
  16. define(['./blueimp-helper', './blueimp-gallery-video'], factory)
  17. } else {
  18. // Browser globals:
  19. factory(window.blueimp.helper || window.jQuery, window.blueimp.Gallery)
  20. }
  21. })(function ($, Gallery) {
  22. 'use strict'
  23. if (!window.postMessage) {
  24. return Gallery
  25. }
  26. $.extend(Gallery.prototype.options, {
  27. // The list object property (or data attribute) with the YouTube video id:
  28. youTubeVideoIdProperty: 'youtube',
  29. // Optional object with parameters passed to the YouTube video player:
  30. // https://developers.google.com/youtube/player_parameters
  31. youTubePlayerVars: {
  32. wmode: 'transparent'
  33. },
  34. // Require a click on the native YouTube player for the initial playback:
  35. youTubeClickToPlay: true
  36. })
  37. var textFactory =
  38. Gallery.prototype.textFactory || Gallery.prototype.imageFactory
  39. var YouTubePlayer = function (videoId, playerVars, clickToPlay) {
  40. this.videoId = videoId
  41. this.playerVars = playerVars
  42. this.clickToPlay = clickToPlay
  43. this.element = document.createElement('div')
  44. this.listeners = {}
  45. }
  46. $.extend(YouTubePlayer.prototype, {
  47. canPlayType: function () {
  48. return true
  49. },
  50. on: function (type, func) {
  51. this.listeners[type] = func
  52. return this
  53. },
  54. loadAPI: function () {
  55. var that = this
  56. var onYouTubeIframeAPIReady = window.onYouTubeIframeAPIReady
  57. var apiUrl = '//www.youtube.com/iframe_api'
  58. var scriptTags = document.getElementsByTagName('script')
  59. var i = scriptTags.length
  60. var scriptTag
  61. window.onYouTubeIframeAPIReady = function () {
  62. if (onYouTubeIframeAPIReady) {
  63. onYouTubeIframeAPIReady.apply(this)
  64. }
  65. if (that.playOnReady) {
  66. that.play()
  67. }
  68. }
  69. while (i) {
  70. i -= 1
  71. if (scriptTags[i].src === apiUrl) {
  72. return
  73. }
  74. }
  75. scriptTag = document.createElement('script')
  76. scriptTag.src = apiUrl
  77. scriptTags[0].parentNode.insertBefore(scriptTag, scriptTags[0])
  78. },
  79. onReady: function () {
  80. this.ready = true
  81. if (this.playOnReady) {
  82. this.play()
  83. }
  84. },
  85. onPlaying: function () {
  86. if (this.playStatus < 2) {
  87. this.listeners.playing()
  88. this.playStatus = 2
  89. }
  90. },
  91. onPause: function () {
  92. Gallery.prototype.setTimeout.call(this, this.checkSeek, null, 2000)
  93. },
  94. checkSeek: function () {
  95. if (
  96. this.stateChange === YT.PlayerState.PAUSED ||
  97. this.stateChange === YT.PlayerState.ENDED
  98. ) {
  99. // check if current state change is actually paused
  100. this.listeners.pause()
  101. delete this.playStatus
  102. }
  103. },
  104. onStateChange: function (event) {
  105. switch (event.data) {
  106. case YT.PlayerState.PLAYING:
  107. this.hasPlayed = true
  108. this.onPlaying()
  109. break
  110. case YT.PlayerState.PAUSED:
  111. case YT.PlayerState.ENDED:
  112. this.onPause()
  113. break
  114. }
  115. // Save most recent state change to this.stateChange
  116. this.stateChange = event.data
  117. },
  118. onError: function (event) {
  119. this.listeners.error(event)
  120. },
  121. play: function () {
  122. var that = this
  123. if (!this.playStatus) {
  124. this.listeners.play()
  125. this.playStatus = 1
  126. }
  127. if (this.ready) {
  128. if (
  129. !this.hasPlayed &&
  130. (this.clickToPlay ||
  131. (window.navigator &&
  132. /iP(hone|od|ad)/.test(window.navigator.platform)))
  133. ) {
  134. // Manually trigger the playing callback if clickToPlay
  135. // is enabled and to workaround a limitation in iOS,
  136. // which requires synchronous user interaction to start
  137. // the video playback:
  138. this.onPlaying()
  139. } else {
  140. this.player.playVideo()
  141. }
  142. } else {
  143. this.playOnReady = true
  144. if (!(window.YT && YT.Player)) {
  145. this.loadAPI()
  146. } else if (!this.player) {
  147. this.player = new YT.Player(this.element, {
  148. videoId: this.videoId,
  149. playerVars: this.playerVars,
  150. events: {
  151. onReady: function () {
  152. that.onReady()
  153. },
  154. onStateChange: function (event) {
  155. that.onStateChange(event)
  156. },
  157. onError: function (event) {
  158. that.onError(event)
  159. }
  160. }
  161. })
  162. }
  163. }
  164. },
  165. pause: function () {
  166. if (this.ready) {
  167. this.player.pauseVideo()
  168. } else if (this.playStatus) {
  169. delete this.playOnReady
  170. this.listeners.pause()
  171. delete this.playStatus
  172. }
  173. }
  174. })
  175. $.extend(Gallery.prototype, {
  176. YouTubePlayer: YouTubePlayer,
  177. textFactory: function (obj, callback) {
  178. var options = this.options
  179. var videoId = this.getItemProperty(obj, options.youTubeVideoIdProperty)
  180. if (videoId) {
  181. if (this.getItemProperty(obj, options.urlProperty) === undefined) {
  182. obj[options.urlProperty] = '//www.youtube.com/watch?v=' + videoId
  183. }
  184. if (
  185. this.getItemProperty(obj, options.videoPosterProperty) === undefined
  186. ) {
  187. obj[options.videoPosterProperty] =
  188. '//img.youtube.com/vi/' + videoId + '/maxresdefault.jpg'
  189. }
  190. return this.videoFactory(
  191. obj,
  192. callback,
  193. new YouTubePlayer(
  194. videoId,
  195. options.youTubePlayerVars,
  196. options.youTubeClickToPlay
  197. )
  198. )
  199. }
  200. return textFactory.call(this, obj, callback)
  201. }
  202. })
  203. return Gallery
  204. })