not really known
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
5.4 KiB

  1. // Sugarizer audio stuff
  2. // Basic HTML 5 Audio Element encapsulation
  3. enyo.kind({
  4. name: "HTML5.Audio",
  5. kind: enyo.Control,
  6. tag: "audio",
  7. published: {
  8. src: "", crossorigin: "", preload: "auto",
  9. mediagroup: "", loop: false, muted: "", controlsbar: false
  10. },
  11. events: {
  12. onSoundEnded: "",
  13. onSoundTimeupdate: ""
  14. },
  15. // Constructor
  16. create: function() {
  17. this.inherited(arguments);
  18. this.isCordova = (enyo.platform.android || enyo.platform.androidChrome || enyo.platform.ios) && document.location.protocol.substr(0,4) != "http";
  19. this.startPlay = false;
  20. this.srcChanged();
  21. this.crossoriginChanged();
  22. this.preloadChanged();
  23. this.loopChanged();
  24. this.mutedChanged();
  25. this.controlsbarChanged();
  26. this.handleVolumeButtons();
  27. },
  28. // Handle volume buttons on Android
  29. handleVolumeButtons: function() {
  30. if (this.isCordova && !enyo.platform.iOS) {
  31. // HACK: Need only on Android because Cordova intercept volume buttons
  32. var emptyf = function() {};
  33. document.addEventListener("volumeupbutton", function() {
  34. cordova.plugins.VolumeControl.getVolume(function(value) {
  35. var volume = parseInt(value);
  36. if (volume < 100) {
  37. cordova.plugins.VolumeControl.setVolume((volume+10), emptyf, emptyf);
  38. }
  39. }, emptyf);
  40. }, false);
  41. document.addEventListener("volumedownbutton", function() {
  42. cordova.plugins.VolumeControl.getVolume(function(value) {
  43. var volume = parseInt(value);
  44. if (volume > 0) {
  45. cordova.plugins.VolumeControl.setVolume((volume-1), emptyf, emptyf);
  46. }
  47. }, emptyf);
  48. }, false);
  49. }
  50. },
  51. // Render
  52. rendered: function() {
  53. this.inherited(arguments);
  54. // Handle init
  55. if (this.hasNode()) {
  56. // Handle sound ended event
  57. var audio = this;
  58. enyo.dispatcher.listen(audio.hasNode(), "ended", function() {
  59. audio.doSoundEnded();
  60. });
  61. enyo.dispatcher.listen(audio.hasNode(), "timeupdate", function(s) {
  62. audio.doSoundTimeupdate({timeStamp: s.timeStamp});
  63. });
  64. }
  65. },
  66. // Property changed
  67. srcChanged: function() {
  68. this.setAttribute("src", this.src);
  69. },
  70. crossoriginChanged: function() {
  71. this.setAttribute("crossorigin", this.crossorigin);
  72. },
  73. preloadChanged: function() {
  74. this.setAttribute("preload", this.preload);
  75. },
  76. loopChanged: function() {
  77. this.setAttribute("loop", this.loop);
  78. },
  79. mutedChanged: function() {
  80. if (this.muted.length != 0)
  81. this.setAttribute("muted", this.muted);
  82. },
  83. controlsbarChanged: function() {
  84. this.setAttribute("controls", this.controlsbar);
  85. },
  86. // Test if component could play a file type
  87. canPlayType: function(typename) {
  88. var node = this.hasNode();
  89. if (!node)
  90. return false;
  91. return node.canPlayType(typename);
  92. },
  93. // Play audio
  94. play: function() {
  95. // HACK: HTML5 Audio don't work in PhoneGap on Android and iOS, use Media PhoneGap component instead
  96. if (this.isCordova) {
  97. // Compute full path
  98. var src = location.pathname.substring(0,1+location.pathname.lastIndexOf('/'))+this.src;
  99. var that = this;
  100. if (this.media) {
  101. this.media.src = "";
  102. this.media.pause();
  103. this.media.release();
  104. }
  105. // Create the Media object
  106. this.media = new Media(src, function() { }, function() { },
  107. function(status) {
  108. if (status == 4 && this.src != "") {
  109. that.doSoundEnded();
  110. }
  111. }
  112. );
  113. // Play
  114. this.media.play();
  115. return;
  116. }
  117. var node = this.hasNode();
  118. if (!node)
  119. return;
  120. this.started = false;
  121. var promise = node.play();
  122. if (promise) {
  123. var that = this;
  124. promise.then(function() {
  125. that.started = true;
  126. }).catch(function() {});
  127. } else {
  128. this.started = true;
  129. }
  130. },
  131. // Pause audio
  132. pause: function() {
  133. // HACK: HTML5 Audio don't work in PhoneGap on Android and iOS, use Media PhoneGap component instead
  134. if (this.isCordova) {
  135. if (!this.media)
  136. return;
  137. this.media.src = "";
  138. this.media.pause();
  139. this.media.release();
  140. return;
  141. }
  142. var node = this.hasNode();
  143. if (!node)
  144. return;
  145. if (this.started) {
  146. node.pause();
  147. }
  148. },
  149. // Test if audio is paused
  150. paused: function() {
  151. var node = this.hasNode();
  152. if (!node)
  153. return false;
  154. return node.paused;
  155. },
  156. // Test if audio is ended
  157. ended: function() {
  158. var node = this.hasNode();
  159. if (!node)
  160. return false;
  161. return node.ended;
  162. }
  163. });
  164. // TankOp Audio engine
  165. enyo.kind({
  166. name: "Sugar.Audio",
  167. kind: enyo.Control,
  168. components: [
  169. { name: "sound", kind: "HTML5.Audio", preload: "auto", autobuffer: true, controlsbar: false,
  170. onSoundEnded: "broadcastEnd", onSoundTimeupdate: "broadcastUpdate" }
  171. ],
  172. // Constructor
  173. create: function() {
  174. this.inherited(arguments);
  175. this.format = null;
  176. },
  177. // First render, test sound format supported
  178. rendered: function() {
  179. this.inherited(arguments);
  180. if (this.$.sound.canPlayType("audio/ogg"))
  181. this.format = ".ogg";
  182. else if (this.$.sound.canPlayType("audio/mpeg"))
  183. this.format = ".mp3";
  184. },
  185. // Play a sound
  186. play: function(sound, loop) {
  187. if (this.format == null)
  188. return;
  189. this.$.sound.setSrc(sound+this.format);
  190. this.$.sound.setLoop(loop === true);
  191. this.timeStamp = new Date().getTime();
  192. this.render();
  193. this.$.sound.play();
  194. },
  195. // Pause
  196. pause: function() {
  197. if (this.format == null)
  198. return;
  199. this.$.sound.pause();
  200. },
  201. // End of sound detected, broadcast the signal
  202. broadcastEnd: function() {
  203. enyo.Signals.send("onEndOfSound", {sound: this.$.sound.src.substring(0,this.$.sound.src.length-4)});
  204. },
  205. broadcastUpdate: function(s, e) {
  206. enyo.Signals.send("onSoundTimeupdate", {timestamp: e.timeStamp-this.timeStamp});
  207. }
  208. });