vedio.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. (function($){
  2. 'use strict';
  3. /**
  4. * Constructor
  5. */
  6. var Video = function($element) {
  7. /**
  8. * Make the reference to the passed
  9. * in element globally accessible within
  10. * the Video constructor
  11. */
  12. this.$element = $element;
  13. /**
  14. * Kick off the application
  15. */
  16. this.init();
  17. };
  18. /* Alias prototype */
  19. var proto = Video.prototype;
  20. /**
  21. * Top level function
  22. */
  23. proto.init = function() {
  24. return this.setupHandlers()
  25. .createChildren()
  26. .enable();
  27. };
  28. /**
  29. * Used to bind 'this' for functions
  30. */
  31. proto.setupHandlers = function() {
  32. this.onPlayPauseHandler = this.playPause.bind(this);
  33. this.onMuteHandler = this.mute.bind(this);
  34. this.onTimeUpdateHandler = this.progress.bind(this);
  35. this.onSeekHandler = this.seek.bind(this);
  36. this.onFullscreenHandler = this.fullscreenMode.bind(this);
  37. this.onVolumeHandler = this.adjustVolume.bind(this);
  38. return this;
  39. };
  40. /**
  41. * Create jQuery selectors here
  42. */
  43. proto.createChildren = function() {
  44. this.$video = this.$element.find('.js-media');
  45. this.$media = this.$video[0];
  46. this.$playBtn = this.$element.find('[data-playPause]');
  47. this.$muteBtn = this.$element.find('[data-mute]');
  48. this.$volume = this.$element.find('[data-volume]');
  49. this.$timeBar = this.$element.find('[data-time]');
  50. this.$bufferBar = this.$element.find('[data-buffer]');
  51. this.$progress = this.$element.find('[data-progress]');
  52. this.$currentTime = this.$element.find('[data-currentTime]');
  53. this.$duration = this.$element.find('[data-duration]');
  54. this.$fullscreen = this.$element.find('[data-fullscreen]');
  55. return this;
  56. };
  57. /**
  58. * Event listeners and functions that need
  59. * to run on initialization
  60. */
  61. proto.enable = function() {
  62. this.$playBtn.on('click', this.onPlayPauseHandler);
  63. this.$muteBtn.on('click', this.onMuteHandler);
  64. this.$video.on('timeupdate', this.onTimeUpdateHandler)
  65. .on('loadedmetadata', function() {
  66. this.updateTimeDisplay(0, this.$media.duration);
  67. }.bind(this))
  68. .on('ended', function() {
  69. this.$playBtn.removeClass('fa-play fa-pause')
  70. .addClass('fa-undo');
  71. this.updateTime(100);
  72. }.bind(this))
  73. ;
  74. this.$progress.on('mousedown', this.onSeekHandler)
  75. .on('mouseup', this.onSeekHandler);
  76. this.$fullscreen.on('click', this.onFullscreenHandler);
  77. this.$volume.on('volumeChange', this.onVolumeHandler);
  78. return this;
  79. };
  80. /**
  81. * Get New Location
  82. *
  83. * Uses offsets within the tracking bar
  84. * to find the position in seconds that the
  85. * corresponds to in seconds of the video.
  86. *
  87. * Returns an object that has the new position
  88. * of the seek bar and the actual time time
  89. * seconds
  90. */
  91. proto.getNewLocation = function(e) {
  92. var seekBarOffset = this.$progress.offset().left;
  93. var mouseOffset = e.pageX;
  94. var mousePosInBar = mouseOffset - seekBarOffset;
  95. var seekBarWidth = this.$progress.width();
  96. var duration = this.$media.duration;
  97. var dist = Math.floor((mousePosInBar / seekBarWidth) * 100);
  98. var actualSeconds = (dist / 100) * duration;
  99. var newLocation = (actualSeconds/duration) * 100;
  100. var info = {
  101. newTime: newLocation,
  102. actualTime: actualSeconds
  103. };;
  104. return info;
  105. };
  106. /**
  107. * Seek
  108. *
  109. * Called on mousedown and mouseup in the progress bar
  110. * to set the position of the progress bar and time in the
  111. * video.
  112. */
  113. proto.seek = function(e) {
  114. var info = this.getNewLocation(e);
  115. this.$media.currentTime = info.actualTime; // Set the time
  116. this.updateTime(info.newTime);
  117. };
  118. /**
  119. * Play
  120. *
  121. * Plays or pauses the video
  122. */
  123. proto.playPause = function() {
  124. if (this.$media.paused) {
  125. this.play();
  126. } else {
  127. this.pause();
  128. }
  129. };
  130. proto.play = function() {
  131. this.$media.play();
  132. this.$playBtn.removeClass('fa-play fa-undo')
  133. .addClass('fa-pause');
  134. };
  135. proto.pause = function() {
  136. this.$media.pause();
  137. this.$playBtn.removeClass('fa-pause fa-undo')
  138. .addClass('fa-play');
  139. };
  140. /**
  141. * Mute
  142. *
  143. * Mutes the video
  144. */
  145. proto.mute = function() {
  146. if (this.$media.muted) {
  147. this.$media.muted = false;
  148. } else {
  149. this.$media.muted = true;
  150. }
  151. this.muteIconSwap();
  152. };
  153. proto.muteIconSwap = function() {
  154. if (this.$media.muted) {
  155. this.$muteBtn.removeClass('fa-volume-up')
  156. .addClass('fa-volume-off');
  157. } else {
  158. this.$muteBtn.removeClass('fa-volume-off')
  159. .addClass('fa-volume-up');
  160. }
  161. };
  162. /**
  163. * Volume
  164. *
  165. * Volume of the video
  166. */
  167. proto.adjustVolume = function() {
  168. var toVolume = this.$volume.data('volume') / 100;
  169. this.$media.volume = toVolume; // from 0 - 1
  170. if(toVolume === 0) {
  171. this.$media.muted = true;
  172. } else {
  173. this.$media.muted = false;
  174. }
  175. this.muteIconSwap();
  176. }
  177. /**
  178. * Progress
  179. *
  180. *
  181. */
  182. proto.progress = function() {
  183. var currentTime = Math.round(this.$media.currentTime);
  184. var duration = this.$media.duration;
  185. var locationPercent = (currentTime/duration) * 100;
  186. var buffered = this.$media.buffered.end(0);
  187. var bufferPercent = Math.floor((buffered/duration) * 100);
  188. this.updateTime(locationPercent);
  189. this.updateBuffer(bufferPercent);
  190. this.updateTimeDisplay(Math.floor(this.$media.currentTime), duration);
  191. };
  192. /**
  193. * Update Buffer
  194. *
  195. * Updates the width of the buffer bar.
  196. */
  197. proto.updateBuffer = function(percent) {
  198. this.$bufferBar.css('width', percent + '%');
  199. };
  200. /**
  201. * Update Time
  202. *
  203. * Updates the width of the seek bar.
  204. */
  205. proto.updateTime = function(percent) {
  206. this.$timeBar.css('width', percent + '%');
  207. };
  208. proto.updateTimeDisplay = function(currentTime, duration) {
  209. this.$currentTime.text(formatTime(currentTime));
  210. this.$duration.text(formatTime(duration));
  211. }
  212. function formatTime(s, m) {
  213. s = Math.floor( s );
  214. m = Math.floor( s / 60 );
  215. m = m >= 10 ? m : '0' + m;
  216. s = Math.floor( s % 60 );
  217. s = s >= 10 ? s : '0' + s;
  218. return m + ':' + s;
  219. }
  220. /**
  221. * Full screen
  222. *
  223. * Display video in fullscreen mode
  224. */
  225. proto.fullscreenMode = function() {
  226. var elem = this.$media;
  227. if (elem.requestFullscreen) {
  228. elem.requestFullscreen();
  229. } else if (elem.mozRequestFullScreen) {
  230. elem.mozRequestFullScreen();
  231. } else if (elem.webkitRequestFullscreen) {
  232. elem.webkitRequestFullscreen();
  233. }
  234. }
  235. /**
  236. * Update src
  237. *
  238. * Update src of the video and reload
  239. */
  240. proto.updateSrc = function(newSource, poster) {
  241. var source = this.$video.find('source');
  242. $(source).attr('src', newSource);
  243. if(poster) {
  244. this.$video.attr('poster', poster);
  245. }
  246. this.$media.load();
  247. }
  248. // making it a jQuery plugin
  249. $.fn.video = function() {
  250. return this.each(function() {
  251. $(this).data('Video', new Video($(this)));
  252. });
  253. }
  254. })(jQuery);
  255. // embedabled movies https://www.davestrailerpage.co.uk/
  256. // use jQuery UI slider for volume control
  257. if($.fn.slider) {
  258. $('.volumeControl').slider({
  259. min: 0,
  260. max: 100,
  261. value: 100,
  262. slide: function( event, ui ) {
  263. $(this).data('volume', ui.value).trigger('volumeChange');
  264. }
  265. });
  266. }
  267. // Initialize the Video instance
  268. $('.js-video').video();