Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

JitsiTrack.js 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. var RTCBrowserType = require("./RTCBrowserType");
  2. var JitsiTrackEvents = require("../../JitsiTrackEvents");
  3. var EventEmitter = require("events");
  4. var RTC = require("./RTCUtils");
  5. /**
  6. * This implements 'onended' callback normally fired by WebRTC after the stream
  7. * is stopped. There is no such behaviour yet in FF, so we have to add it.
  8. * @param jitsiTrack our track object holding the original WebRTC stream object
  9. * to which 'onended' handling will be added.
  10. */
  11. function implementOnEndedHandling(jitsiTrack) {
  12. var stream = jitsiTrack.getOriginalStream();
  13. var originalStop = stream.stop;
  14. stream.stop = function () {
  15. originalStop.apply(stream);
  16. if (jitsiTrack.isActive()) {
  17. stream.onended();
  18. }
  19. };
  20. }
  21. /**
  22. * Adds onended/oninactive handler to a MediaStream.
  23. * @param mediaStream a MediaStream to attach onended/oninactive handler
  24. * @param handler the handler
  25. */
  26. function addMediaStreamInactiveHandler(mediaStream, handler) {
  27. if(RTCBrowserType.isTemasysPluginUsed()) {
  28. // themasys
  29. //FIXME: Seems that not working properly.
  30. if(mediaStream.onended) {
  31. mediaStream.onended = handler;
  32. } else if(mediaStream.addEventListener) {
  33. mediaStream.addEventListener('ended', function () {
  34. handler(mediaStream);
  35. });
  36. } else if(mediaStream.attachEvent) {
  37. mediaStream.attachEvent('ended', function () {
  38. handler(mediaStream);
  39. });
  40. }
  41. }
  42. else {
  43. if(typeof mediaStream.active !== "undefined")
  44. mediaStream.oninactive = handler;
  45. else
  46. mediaStream.onended = handler;
  47. }
  48. }
  49. /**
  50. * Represents a single media track (either audio or video).
  51. * @constructor
  52. * @param rtc the rtc instance
  53. * @param stream the stream
  54. * @param streamInactiveHandler the function that will handle
  55. * onended/oninactive events of the stream.
  56. */
  57. function JitsiTrack(rtc, stream, streamInactiveHandler)
  58. {
  59. /**
  60. * Array with the HTML elements that are displaying the streams.
  61. * @type {Array}
  62. */
  63. this.containers = [];
  64. this.rtc = rtc;
  65. this.stream = stream;
  66. this.eventEmitter = new EventEmitter();
  67. this.audioLevel = -1;
  68. this.type = (this.stream.getVideoTracks().length > 0)?
  69. JitsiTrack.VIDEO : JitsiTrack.AUDIO;
  70. if(this.type == "audio") {
  71. this._getTracks = function () {
  72. return this.stream.getAudioTracks();
  73. }.bind(this);
  74. } else {
  75. this._getTracks = function () {
  76. return this.stream.getVideoTracks();
  77. }.bind(this);
  78. }
  79. if (RTCBrowserType.isFirefox() && this.stream) {
  80. implementOnEndedHandling(this);
  81. }
  82. if(stream)
  83. addMediaStreamInactiveHandler(stream, streamInactiveHandler);
  84. }
  85. /**
  86. * JitsiTrack video type.
  87. * @type {string}
  88. */
  89. JitsiTrack.VIDEO = "video";
  90. /**
  91. * JitsiTrack audio type.
  92. * @type {string}
  93. */
  94. JitsiTrack.AUDIO = "audio";
  95. /**
  96. * Returns the type (audio or video) of this track.
  97. */
  98. JitsiTrack.prototype.getType = function() {
  99. return this.type;
  100. };
  101. /**
  102. * Check if this is audiotrack.
  103. */
  104. JitsiTrack.prototype.isAudioTrack = function () {
  105. return this.getType() === JitsiTrack.AUDIO;
  106. };
  107. /**
  108. * Check if this is videotrack.
  109. */
  110. JitsiTrack.prototype.isVideoTrack = function () {
  111. return this.getType() === JitsiTrack.VIDEO;
  112. };
  113. /**
  114. * Returns the RTCMediaStream from the browser (?).
  115. */
  116. JitsiTrack.prototype.getOriginalStream = function() {
  117. return this.stream;
  118. }
  119. /**
  120. * Mutes the track.
  121. */
  122. JitsiTrack.prototype.mute = function () {
  123. this._setMute(true);
  124. }
  125. /**
  126. * Unmutes the stream.
  127. */
  128. JitsiTrack.prototype.unmute = function () {
  129. this._setMute(false);
  130. }
  131. /**
  132. * Attaches the MediaStream of this track to an HTML container (?).
  133. * Adds the container to the list of containers that are displaying the track.
  134. * @param container the HTML container
  135. */
  136. JitsiTrack.prototype.attach = function (container) {
  137. if(this.stream)
  138. require("./RTCUtils").attachMediaStream(container, this.stream);
  139. this.containers.push(container);
  140. }
  141. /**
  142. * Removes the track from the passed HTML container.
  143. * @param container the HTML container. If <tt>null</tt> all containers are removed.
  144. */
  145. JitsiTrack.prototype.detach = function (container) {
  146. for(var i = 0; i < this.containers.length; i++)
  147. {
  148. if(this.containers[i].is(container))
  149. {
  150. this.containers.splice(i,1);
  151. }
  152. if(!container)
  153. {
  154. this.containers[i].find(">video").remove();
  155. }
  156. }
  157. if(container)
  158. $(container).find(">video").remove();
  159. }
  160. /**
  161. * Stops sending the media track. And removes it from the HTML.
  162. * NOTE: Works for local tracks only.
  163. */
  164. JitsiTrack.prototype.stop = function () {
  165. }
  166. /**
  167. * Returns true if this is a video track and the source of the video is a
  168. * screen capture as opposed to a camera.
  169. */
  170. JitsiTrack.prototype.isScreenSharing = function(){
  171. }
  172. /**
  173. * Returns id of the track.
  174. * @returns {string} id of the track or null if this is fake track.
  175. */
  176. JitsiTrack.prototype._getId = function () {
  177. var tracks = this.stream.getTracks();
  178. if(!tracks || tracks.length === 0)
  179. return null;
  180. return tracks[0].id;
  181. };
  182. /**
  183. * Returns id of the track.
  184. * @returns {string} id of the track or null if this is fake track.
  185. */
  186. JitsiTrack.prototype.getId = function () {
  187. return RTC.getStreamID(this.stream);
  188. };
  189. /**
  190. * Checks whether the MediaStream is avtive/not ended.
  191. * When there is no check for active we don't have information and so
  192. * will return that stream is active (in case of FF).
  193. * @returns {boolean} whether MediaStream is active.
  194. */
  195. JitsiTrack.prototype.isActive = function () {
  196. if((typeof this.stream.active !== "undefined"))
  197. return this.stream.active;
  198. else
  199. return true;
  200. };
  201. /**
  202. * Attaches a handler for events(For example - "audio level changed".).
  203. * All possible event are defined in JitsiTrackEvents.
  204. * @param eventId the event ID.
  205. * @param handler handler for the event.
  206. */
  207. JitsiTrack.prototype.on = function (eventId, handler) {
  208. if(this.eventEmitter)
  209. this.eventEmitter.on(eventId, handler);
  210. }
  211. /**
  212. * Removes event listener
  213. * @param eventId the event ID.
  214. * @param [handler] optional, the specific handler to unbind
  215. */
  216. JitsiTrack.prototype.off = function (eventId, handler) {
  217. if(this.eventEmitter)
  218. this.eventEmitter.removeListener(eventId, handler);
  219. }
  220. // Common aliases for event emitter
  221. JitsiTrack.prototype.addEventListener = JitsiTrack.prototype.on;
  222. JitsiTrack.prototype.removeEventListener = JitsiTrack.prototype.off;
  223. /**
  224. * Sets the audio level for the stream
  225. * @param audioLevel the new audio level
  226. */
  227. JitsiTrack.prototype.setAudioLevel = function (audioLevel) {
  228. if(this.audioLevel !== audioLevel) {
  229. this.eventEmitter.emit(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
  230. audioLevel);
  231. this.audioLevel = audioLevel;
  232. }
  233. }
  234. module.exports = JitsiTrack;