_Media.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. define("dojox/av/_Media", ['dojo'],function(dojo){
  2. dojo.experimental("dojox.av.FLVideo");
  3. return dojo.declare("dojox.av._Media", null, {
  4. // summary:
  5. // Used as a mixin for dojox and AIR media
  6. // description:
  7. // Calculates the current status of the playing media and fires
  8. // the appropriate events.
  9. //
  10. mediaUrl:"",
  11. //
  12. // initialVolume: Float?
  13. // The initial volume setting of the player. Acccepts between 0 and 1.
  14. initialVolume:1,
  15. //
  16. // autoPlay:Boolean?
  17. // Whether the video automatically plays on load or not.
  18. autoPlay: false,
  19. //
  20. // bufferTime: Number?
  21. // Time in milliseconds that the video should be loaded before it will
  22. // play. May pause and resume to build up buffer. Prevents stuttering.
  23. // Note:
  24. // Older FLVs, without a duration, cannot be buffered.
  25. bufferTime: 2000,
  26. //
  27. // minBufferTime: Number
  28. // Time in milliseconds bwteen the playhead time and loaded time that
  29. // will trigger the buffer. When buffer is triggered, video will pause
  30. // until the bufferTime amount is buffered.
  31. // Note: Should be a small number, greater than zero.
  32. minBufferTime:300,
  33. //
  34. // updateTime: Number
  35. // How often, in milliseconds to get an update of the video position.
  36. updateTime: 100,
  37. //
  38. // id: String?
  39. // The id of this widget and the id of the SWF movie.
  40. id:"",
  41. //
  42. // isDebug: Boolean?
  43. // Setting to true tells the SWF to output log messages to Firebug.
  44. isDebug: false,
  45. //
  46. // percentDownloaded: read-only-Number
  47. // The percentage the media has downloaded; from 0-100
  48. percentDownloaded:0,
  49. //
  50. // _flashObject: read-only-Object
  51. // The dojox.embed object
  52. _flashObject:null,
  53. //
  54. // flashMedia: read-only-SWF
  55. // The SWF object. Methods are passed to this.
  56. flashMedia:null,
  57. //
  58. // allowScriptAccess: String
  59. // Whether the SWF can access the container JS
  60. allowScriptAccess:"always",
  61. //
  62. // allowNetworking: String
  63. // Whether SWF is restricted to a domain
  64. allowNetworking: "all",
  65. //
  66. // wmode: String
  67. // The render type of the SWF
  68. wmode: "transparent",
  69. //
  70. // allowFullScreen: Boolean
  71. // Whether to allow the SWF to go to fullscreen
  72. allowFullScreen:true,
  73. _initStatus: function(){
  74. // summary:
  75. // Connect mediaStatus to the media.
  76. //
  77. this.status = "ready";
  78. this._positionHandle = dojo.connect(this, "onPosition", this, "_figureStatus");
  79. },
  80. // ============== //
  81. // Player Getters //
  82. // ============== //
  83. getTime: function(){
  84. // summary:
  85. // Returns the current time of the video
  86. // Note:
  87. // Consider the onPosition event, which returns
  88. // the time at a set interval. Too many trips to
  89. // the SWF could impact performance.
  90. return this.flashMedia.getTime(); // Float
  91. },
  92. // ============= //
  93. // Player Events //
  94. // ============= //
  95. onLoad: function(/* SWF */ mov){
  96. // summary:
  97. // Fired when the SWF player has loaded
  98. // NOT when the video has loaded
  99. //
  100. },
  101. onDownloaded: function(/* Number */percent){
  102. // summary:
  103. // Fires the amount of that the media has been
  104. // downloaded. Number, 0-100
  105. },
  106. onClick: function(/* Object */ evt){
  107. // summary:
  108. // TODO: Return x/y of click
  109. // Fires when the player is clicked
  110. // Could be used to toggle play/pause, or
  111. // do an external activity, like opening a new
  112. // window.
  113. },
  114. onSwfSized: function(/* Object */ data){
  115. // summary:
  116. // Fired on SWF resize, or when its
  117. // toggled between fullscreen.
  118. },
  119. onMetaData: function(/* Object */ data, /* Object */ evt){
  120. // summary:
  121. // The video properties. Width, height, duration, etc.
  122. // NOTE: if data is empty, this is an older FLV with no meta data.
  123. // Duration cannot be determined. In original FLVs, duration
  124. // could only be obtained with Flash Media Server.
  125. // NOTE: Older FLVs can still return width and height
  126. // and will do so on a second event call
  127. console.warn("onMeta", data)
  128. this.duration = data.duration;
  129. },
  130. onPosition: function(/* Float */ time){
  131. // summary:
  132. // The position of the playhead in seconds
  133. },
  134. onStart: function(/* Object */ data){
  135. // summary:
  136. // Fires when video starts
  137. // Good for setting the play button to pause
  138. // during an autoPlay for example
  139. },
  140. onPlay: function(/* Object */ data){
  141. // summary:
  142. // Fires when video starts and resumes
  143. },
  144. onPause: function(/* Object */ data){
  145. // summary:
  146. // Fires when the pause button is clicked
  147. },
  148. onEnd: function(/* Object */ data){
  149. // summary:
  150. // Fires when video ends
  151. // Could be used to change pause button to play
  152. // or show a post video graphic, like YouTube
  153. },
  154. onStop: function(){
  155. // summary:
  156. // Fire when the Stop button is clicked
  157. // TODO: This is not hooked up yet and shouldn't
  158. // fire.
  159. },
  160. onBuffer: function(/* Boolean */ isBuffering){
  161. // summary:
  162. // Fires a boolean to tell if media
  163. // is paused for buffering or if buffering
  164. // has finished
  165. this.isBuffering = isBuffering;
  166. },
  167. onError: function(/* Object */ data, /* String */ url){
  168. // summary:
  169. // Fired when the player encounters an error
  170. // example:
  171. // | console.warn("ERROR-"+data.type.toUpperCase()+":",
  172. // | data.info.code, " - URL:", url);
  173. console.warn("ERROR-"+data.type.toUpperCase()+":", data.info.code, " - URL:", url);
  174. },
  175. onStatus: function(/* Object */data){
  176. // summary:
  177. // Simple status
  178. },
  179. onPlayerStatus: function(/* Object */data){
  180. // summary:
  181. // The status of the video from the SWF
  182. // playing, stopped, bufering, etc.
  183. },
  184. onResize: function(){
  185. },
  186. _figureStatus: function(){
  187. // summary:
  188. // Calculate media status, based on playhead movement, and
  189. // onStop and onStart events
  190. // TODO:
  191. // Figure in real status from the media for more accurate results.
  192. //
  193. var pos = this.getTime();
  194. //console.log(pos, this.duration, (pos>this.duration-.5), (this.duration && pos>this.duration-.5))
  195. if(this.status=="stopping"){
  196. // stop was fired, need to fake pos==0
  197. this.status = "stopped";
  198. this.onStop(this._eventFactory());
  199. }else if(this.status=="ending" && pos==this._prevPos){
  200. this.status = "ended";
  201. this.onEnd(this._eventFactory());
  202. }else if(this.duration && pos>this.duration-.5){
  203. this.status="ending"
  204. }else if(pos===0 ){//|| this.status == "stopped"
  205. if(this.status == "ready"){
  206. //never played
  207. }else{
  208. //stopped
  209. this.status = "stopped";
  210. if(this._prevStatus != "stopped"){
  211. this.onStop(this._eventFactory());
  212. }
  213. }
  214. }else{
  215. // pos > 0
  216. if(this.status == "ready"){
  217. //started
  218. this.status = "started";
  219. this.onStart(this._eventFactory());
  220. this.onPlay(this._eventFactory());
  221. }else if(this.isBuffering){
  222. this.status = "buffering";
  223. }else if(this.status == "started" || (this.status == "playing" && pos != this._prevPos)){
  224. this.status = "playing";
  225. //this.onPosition(this._eventFactory());
  226. }else if(!this.isStopped && this.status == "playing" && pos == this._prevPos){
  227. this.status = "paused";
  228. console.warn("pause", pos, this._prevPos)
  229. if(this.status != this._prevStatus){
  230. this.onPause(this._eventFactory());
  231. }
  232. }else if((this.status == "paused" ||this.status == "stopped") && pos != this._prevPos){
  233. this.status = "started";
  234. this.onPlay(this._eventFactory());
  235. }
  236. }
  237. this._prevPos = pos;
  238. this._prevStatus = this.status;
  239. this.onStatus(this.status);
  240. },
  241. _eventFactory: function(){
  242. // summary:
  243. // Creates a generic event object.
  244. //
  245. var evt = {
  246. //position:this._channel.position,
  247. //seconds:this.toSeconds(this._channel.position*.001),
  248. //percentPlayed:this._getPercent(),
  249. status:this.status
  250. }
  251. return evt; // Object
  252. },
  253. _sub: function(topic, method){
  254. // summary:
  255. // helper for subscribing to topics
  256. dojo.subscribe(this.id+"/"+topic, this, method);
  257. },
  258. _normalizeVolume: function(vol){
  259. // summary:
  260. // Ensures volume is less than one
  261. //
  262. if(vol>1){
  263. while(vol>1){
  264. vol*=.1
  265. }
  266. }
  267. return vol;
  268. },
  269. _normalizeUrl: function(_url){
  270. // summary:
  271. // Checks that path is relative to HTML file or
  272. // convertes it to an absolute path.
  273. //
  274. console.log(" url:", _url);
  275. if(_url && (_url.toLowerCase().indexOf("http")<0 || _url.indexOf("/") == 0)){
  276. //
  277. // Appears to be a relative path. Attempt to convert it to absolute,
  278. // so it will better target the SWF.
  279. var loc = window.location.href.split("/");
  280. loc.pop();
  281. loc = loc.join("/")+"/";
  282. console.log(" loc:", loc);
  283. _url = loc+_url;
  284. }
  285. return _url;
  286. },
  287. destroy: function(){
  288. // summary:
  289. // destroys flash
  290. if(!this.flashMedia){
  291. this._cons.push(dojo.connect(this, "onLoad", this, "destroy"));
  292. return;
  293. }
  294. dojo.forEach(this._subs, function(s){
  295. dojo.unsubscribe(s);
  296. });
  297. dojo.forEach(this._cons, function(c){
  298. dojo.disconnect(c);
  299. });
  300. this._flashObject.destroy();
  301. //dojo._destroyElement(this.flashDiv);
  302. }
  303. });
  304. });