twitch.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*!
  2. * MediaElement.js
  3. * http://www.mediaelementjs.com/
  4. *
  5. * Wrapper that mimics native HTML5 MediaElement (audio and video)
  6. * using a variety of technologies (pure JavaScript, Flash, iframe)
  7. *
  8. * Copyright 2010-2017, John Dyer (http://j.hn/)
  9. * License: MIT
  10. *
  11. */(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
  12. 'use strict';
  13. var TwitchApi = {
  14. promise: null,
  15. load: function load(settings) {
  16. if (typeof Twitch !== 'undefined') {
  17. TwitchApi.promise = new Promise(function (resolve) {
  18. resolve();
  19. }).then(function () {
  20. TwitchApi._createPlayer(settings);
  21. });
  22. } else {
  23. TwitchApi.promise = TwitchApi.promise || mejs.Utils.loadScript('https://player.twitch.tv/js/embed/v1.js');
  24. TwitchApi.promise.then(function () {
  25. TwitchApi._createPlayer(settings);
  26. });
  27. }
  28. },
  29. _createPlayer: function _createPlayer(settings) {
  30. var player = new Twitch.Player(settings.id, settings);
  31. window['__ready__' + settings.id](player);
  32. },
  33. getTwitchId: function getTwitchId(url) {
  34. var twitchId = '';
  35. if (url.indexOf('?') > 0) {
  36. twitchId = TwitchApi.getTwitchIdFromParam(url);
  37. if (twitchId === '') {
  38. twitchId = TwitchApi.getTwitchIdFromUrl(url);
  39. }
  40. } else {
  41. twitchId = TwitchApi.getTwitchIdFromUrl(url);
  42. }
  43. return twitchId;
  44. },
  45. getTwitchIdFromParam: function getTwitchIdFromParam(url) {
  46. if (url === undefined || url === null || !url.trim().length) {
  47. return null;
  48. }
  49. var parts = url.split('?'),
  50. parameters = parts[1].split('&');
  51. var twitchId = '';
  52. for (var i = 0, total = parameters.length; i < total; i++) {
  53. var paramParts = parameters[i].split('=');
  54. if (~paramParts[0].indexOf('channel')) {
  55. twitchId = paramParts[1];
  56. break;
  57. } else if (~paramParts[0].indexOf('video')) {
  58. twitchId = 'v' + paramParts[1];
  59. break;
  60. }
  61. }
  62. return twitchId;
  63. },
  64. getTwitchIdFromUrl: function getTwitchIdFromUrl(url) {
  65. if (url === undefined || url === null || !url.trim().length) {
  66. return null;
  67. }
  68. var parts = url.split('?');
  69. url = parts[0];
  70. var id = url.substring(url.lastIndexOf('/') + 1);
  71. return (/^\d+$/i.test(id) ? 'v' + id : id
  72. );
  73. },
  74. getTwitchType: function getTwitchType(id) {
  75. return (/^v\d+/i.test(id) ? 'video' : 'channel'
  76. );
  77. }
  78. };
  79. var TwitchIframeRenderer = {
  80. name: 'twitch_iframe',
  81. options: {
  82. prefix: 'twitch_iframe'
  83. },
  84. canPlayType: function canPlayType(type) {
  85. return ~['video/twitch', 'video/x-twitch'].indexOf(type.toLowerCase());
  86. },
  87. create: function create(mediaElement, options, mediaFiles) {
  88. var twitch = {},
  89. apiStack = [],
  90. readyState = 4,
  91. twitchId = TwitchApi.getTwitchId(mediaFiles[0].src);
  92. var twitchPlayer = null,
  93. paused = true,
  94. ended = false,
  95. hasStartedPlaying = false,
  96. volume = 1,
  97. duration = Infinity,
  98. time = 0;
  99. twitch.options = options;
  100. twitch.id = mediaElement.id + '_' + options.prefix;
  101. twitch.mediaElement = mediaElement;
  102. var props = mejs.html5media.properties,
  103. assignGettersSetters = function assignGettersSetters(propName) {
  104. var capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
  105. twitch['get' + capName] = function () {
  106. if (twitchPlayer !== null) {
  107. var value = null;
  108. switch (propName) {
  109. case 'currentTime':
  110. time = twitchPlayer.getCurrentTime();
  111. return time;
  112. case 'duration':
  113. duration = twitchPlayer.getDuration();
  114. return duration;
  115. case 'volume':
  116. volume = twitchPlayer.getVolume();
  117. return volume;
  118. case 'paused':
  119. paused = twitchPlayer.isPaused();
  120. return paused;
  121. case 'ended':
  122. ended = twitchPlayer.getEnded();
  123. return ended;
  124. case 'muted':
  125. return twitchPlayer.getMuted();
  126. case 'buffered':
  127. return {
  128. start: function start() {
  129. return 0;
  130. },
  131. end: function end() {
  132. return 0;
  133. },
  134. length: 1
  135. };
  136. case 'src':
  137. return TwitchApi.getTwitchType(twitchId) === 'channel' ? twitchPlayer.getChannel() : twitchPlayer.getVideo();
  138. case 'readyState':
  139. return readyState;
  140. }
  141. return value;
  142. } else {
  143. return null;
  144. }
  145. };
  146. twitch['set' + capName] = function (value) {
  147. if (twitchPlayer !== null) {
  148. switch (propName) {
  149. case 'src':
  150. var url = typeof value === 'string' ? value : value[0].src,
  151. videoId = TwitchApi.getTwitchId(url);
  152. if (TwitchApi.getTwitchType(twitchId) === 'channel') {
  153. twitchPlayer.setChannel(videoId);
  154. } else {
  155. twitchPlayer.setVideo(videoId);
  156. }
  157. break;
  158. case 'currentTime':
  159. twitchPlayer.seek(value);
  160. setTimeout(function () {
  161. var event = mejs.Utils.createEvent('timeupdate', twitch);
  162. mediaElement.dispatchEvent(event);
  163. }, 50);
  164. break;
  165. case 'muted':
  166. twitchPlayer.setMuted(value);
  167. setTimeout(function () {
  168. var event = mejs.Utils.createEvent('volumechange', twitch);
  169. mediaElement.dispatchEvent(event);
  170. }, 50);
  171. break;
  172. case 'volume':
  173. volume = value;
  174. twitchPlayer.setVolume(value);
  175. setTimeout(function () {
  176. var event = mejs.Utils.createEvent('volumechange', twitch);
  177. mediaElement.dispatchEvent(event);
  178. }, 50);
  179. break;
  180. case 'readyState':
  181. var event = mejs.Utils.createEvent('canplay', twitch);
  182. mediaElement.dispatchEvent(event);
  183. break;
  184. default:
  185. break;
  186. }
  187. } else {
  188. apiStack.push({ type: 'set', propName: propName, value: value });
  189. }
  190. };
  191. };
  192. for (var i = 0, total = props.length; i < total; i++) {
  193. assignGettersSetters(props[i]);
  194. }
  195. var methods = mejs.html5media.methods,
  196. assignMethods = function assignMethods(methodName) {
  197. twitch[methodName] = function () {
  198. if (twitchPlayer !== null) {
  199. switch (methodName) {
  200. case 'play':
  201. paused = false;
  202. return twitchPlayer.play();
  203. case 'pause':
  204. paused = true;
  205. return twitchPlayer.pause();
  206. case 'load':
  207. return null;
  208. }
  209. } else {
  210. apiStack.push({ type: 'call', methodName: methodName });
  211. }
  212. };
  213. };
  214. for (var _i = 0, _total = methods.length; _i < _total; _i++) {
  215. assignMethods(methods[_i]);
  216. }
  217. function sendEvents(events) {
  218. for (var _i2 = 0, _total2 = events.length; _i2 < _total2; _i2++) {
  219. var event = mejs.Utils.createEvent(events[_i2], twitch);
  220. mediaElement.dispatchEvent(event);
  221. }
  222. }
  223. window['__ready__' + twitch.id] = function (_twitchPlayer) {
  224. mediaElement.twitchPlayer = twitchPlayer = _twitchPlayer;
  225. if (apiStack.length) {
  226. for (var _i3 = 0, _total3 = apiStack.length; _i3 < _total3; _i3++) {
  227. var stackItem = apiStack[_i3];
  228. if (stackItem.type === 'set') {
  229. var propName = stackItem.propName,
  230. capName = '' + propName.substring(0, 1).toUpperCase() + propName.substring(1);
  231. twitch['set' + capName](stackItem.value);
  232. } else if (stackItem.type === 'call') {
  233. twitch[stackItem.methodName]();
  234. }
  235. }
  236. }
  237. var twitchIframe = document.getElementById(twitch.id).firstChild;
  238. twitchIframe.style.width = '100%';
  239. twitchIframe.style.height = '100%';
  240. var events = ['mouseover', 'mouseout'],
  241. assignEvents = function assignEvents(e) {
  242. var event = mejs.Utils.createEvent(e.type, twitch);
  243. mediaElement.dispatchEvent(event);
  244. };
  245. for (var _i4 = 0, _total4 = events.length; _i4 < _total4; _i4++) {
  246. twitchIframe.addEventListener(events[_i4], assignEvents, false);
  247. }
  248. var timer = void 0;
  249. twitchPlayer.addEventListener(Twitch.Player.READY, function () {
  250. paused = false;
  251. ended = false;
  252. sendEvents(['rendererready', 'loadedmetadata', 'loadeddata', 'canplay']);
  253. });
  254. twitchPlayer.addEventListener(Twitch.Player.PLAY, function () {
  255. if (!hasStartedPlaying) {
  256. hasStartedPlaying = true;
  257. }
  258. paused = false;
  259. ended = false;
  260. sendEvents(['play', 'playing', 'progress']);
  261. timer = setInterval(function () {
  262. twitchPlayer.getCurrentTime();
  263. sendEvents(['timeupdate']);
  264. }, 250);
  265. });
  266. twitchPlayer.addEventListener(Twitch.Player.PAUSE, function () {
  267. paused = true;
  268. ended = false;
  269. if (!twitchPlayer.getEnded()) {
  270. sendEvents(['pause']);
  271. }
  272. });
  273. twitchPlayer.addEventListener(Twitch.Player.ENDED, function () {
  274. paused = true;
  275. ended = true;
  276. sendEvents(['ended']);
  277. clearInterval(timer);
  278. hasStartedPlaying = false;
  279. timer = null;
  280. });
  281. };
  282. var height = mediaElement.originalNode.height,
  283. width = mediaElement.originalNode.width,
  284. twitchContainer = document.createElement('div'),
  285. type = TwitchApi.getTwitchType(twitchId),
  286. twitchSettings = {
  287. id: twitch.id,
  288. width: width,
  289. height: height,
  290. playsinline: false,
  291. autoplay: mediaElement.originalNode.autoplay,
  292. muted: mediaElement.originalNode.muted
  293. };
  294. twitchSettings[type] = twitchId;
  295. twitchContainer.id = twitch.id;
  296. twitchContainer.style.width = '100%';
  297. twitchContainer.style.height = '100%';
  298. mediaElement.originalNode.parentNode.insertBefore(twitchContainer, mediaElement.originalNode);
  299. mediaElement.originalNode.style.display = 'none';
  300. mediaElement.originalNode.autoplay = false;
  301. twitch.setSize = function (width, height) {
  302. if (TwitchApi !== null && !isNaN(width) && !isNaN(height)) {
  303. twitchContainer.setAttribute('width', width);
  304. twitchContainer.setAttribute('height', height);
  305. }
  306. };
  307. twitch.hide = function () {
  308. twitch.pause();
  309. twitchContainer.style.display = 'none';
  310. };
  311. twitch.show = function () {
  312. twitchContainer.style.display = '';
  313. };
  314. twitch.destroy = function () {};
  315. TwitchApi.load(twitchSettings);
  316. return twitch;
  317. }
  318. };
  319. mejs.Utils.typeChecks.push(function (url) {
  320. return (/\/\/(www|player).twitch.tv/i.test(url) ? 'video/x-twitch' : null
  321. );
  322. });
  323. mejs.Renderers.add(TwitchIframeRenderer);
  324. },{}]},{},[1]);