videos.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  3. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. define(["jquery", "util", "session", "elementFinder"],
  5. function ($, util, session, elementFinder) {
  6. var listeners = [];
  7. var TIME_UPDATE = 'timeupdate';
  8. var MIRRORED_EVENTS = ['play', 'pause'];
  9. var TOO_FAR_APART = 3000;
  10. session.on("reinitialize", function () {
  11. unsetListeners();
  12. setupListeners();
  13. });
  14. session.on("ui-ready", setupListeners);
  15. function setupListeners() {
  16. var videos = $('video');
  17. setupMirroredEvents(videos);
  18. setupTimeSync(videos);
  19. }
  20. function setupMirroredEvents(videos) {
  21. var currentListener;
  22. MIRRORED_EVENTS.forEach(function (eventName) {
  23. currentListener = makeEventSender(eventName);
  24. videos.on(eventName, currentListener);
  25. listeners.push({
  26. name: eventName,
  27. listener: currentListener
  28. });
  29. });
  30. }
  31. function makeEventSender(eventName) {
  32. return function (event, options) {
  33. var element = event.target;
  34. options = options || {};
  35. if (!options.silent) {
  36. session.send({
  37. type: ('video-'+eventName),
  38. location: elementFinder.elementLocation(element),
  39. position: element.currentTime
  40. });
  41. }
  42. };
  43. }
  44. function setupTimeSync(videos) {
  45. videos.each(function(i, video) {
  46. var onTimeUpdate = makeTimeUpdater();
  47. $(video).on(TIME_UPDATE, onTimeUpdate);
  48. listeners.push({
  49. name: TIME_UPDATE,
  50. listener: onTimeUpdate
  51. });
  52. });
  53. }
  54. function makeTimeUpdater() {
  55. var last = 0;
  56. return function (event) {
  57. var currentTime = event.target.currentTime;
  58. if(areTooFarApart(currentTime, last)){
  59. makeEventSender(TIME_UPDATE)(event);
  60. }
  61. last = currentTime;
  62. };
  63. }
  64. function areTooFarApart(currentTime, lastTime) {
  65. var secDiff = Math.abs(currentTime - lastTime);
  66. var milliDiff = secDiff * 1000;
  67. return milliDiff > TOO_FAR_APART;
  68. }
  69. session.on("close", unsetListeners);
  70. function unsetListeners() {
  71. var videos = $('video');
  72. listeners.forEach(function (event) {
  73. videos.off(event.name, event.listener);
  74. });
  75. listeners = [];
  76. }
  77. session.hub.on('video-timeupdate', function (msg) {
  78. var element = $findElement(msg.location);
  79. var oldTime = element.prop('currentTime');
  80. var newTime = msg.position;
  81. //to help throttle uneccesary position changes
  82. if(areTooFarApart(oldTime, newTime)){
  83. setTime(element, msg.position);
  84. }
  85. });
  86. MIRRORED_EVENTS.forEach( function (eventName) {
  87. session.hub.on("video-"+eventName, function (msg) {
  88. var element = $findElement(msg.location);
  89. setTime(element, msg.position);
  90. element.trigger(eventName, {silent: true});
  91. });
  92. });
  93. //Currently does not discriminate between visible and invisible videos
  94. function $findElement(location) {
  95. return $(elementFinder.findElement(location));
  96. }
  97. function setTime(video, time) {
  98. video.prop('currentTime', time);
  99. }
  100. });