Media.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. *
  3. * Licensed to the Apache Software Foundation (ASF) under one
  4. * or more contributor license agreements. See the NOTICE file
  5. * distributed with this work for additional information
  6. * regarding copyright ownership. The ASF licenses this file
  7. * to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing,
  14. * software distributed under the License is distributed on an
  15. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16. * KIND, either express or implied. See the License for the
  17. * specific language governing permissions and limitations
  18. * under the License.
  19. *
  20. */
  21. var argscheck = require('cordova/argscheck'),
  22. utils = require('cordova/utils'),
  23. exec = require('cordova/exec');
  24. var mediaObjects = {};
  25. /**
  26. * This class provides access to the device media, interfaces to both sound and video
  27. *
  28. * @constructor
  29. * @param src The file name or url to play
  30. * @param successCallback The callback to be called when the file is done playing or recording.
  31. * successCallback()
  32. * @param errorCallback The callback to be called if there is an error.
  33. * errorCallback(int errorCode) - OPTIONAL
  34. * @param statusCallback The callback to be called when media status has changed.
  35. * statusCallback(int statusCode) - OPTIONAL
  36. */
  37. var Media = function(src, successCallback, errorCallback, statusCallback) {
  38. argscheck.checkArgs('sFFF', 'Media', arguments);
  39. this.id = utils.createUUID();
  40. mediaObjects[this.id] = this;
  41. this.src = src;
  42. this.successCallback = successCallback;
  43. this.errorCallback = errorCallback;
  44. this.statusCallback = statusCallback;
  45. this._duration = -1;
  46. this._position = -1;
  47. exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
  48. };
  49. // Media messages
  50. Media.MEDIA_STATE = 1;
  51. Media.MEDIA_DURATION = 2;
  52. Media.MEDIA_POSITION = 3;
  53. Media.MEDIA_ERROR = 9;
  54. // Media states
  55. Media.MEDIA_NONE = 0;
  56. Media.MEDIA_STARTING = 1;
  57. Media.MEDIA_RUNNING = 2;
  58. Media.MEDIA_PAUSED = 3;
  59. Media.MEDIA_STOPPED = 4;
  60. Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
  61. // "static" function to return existing objs.
  62. Media.get = function(id) {
  63. return mediaObjects[id];
  64. };
  65. /**
  66. * Start or resume playing audio file.
  67. */
  68. Media.prototype.play = function(options) {
  69. exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
  70. };
  71. /**
  72. * Stop playing audio file.
  73. */
  74. Media.prototype.stop = function() {
  75. var me = this;
  76. exec(function() {
  77. me._position = 0;
  78. }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
  79. };
  80. /**
  81. * Seek or jump to a new time in the track..
  82. */
  83. Media.prototype.seekTo = function(milliseconds) {
  84. var me = this;
  85. exec(function(p) {
  86. me._position = p;
  87. }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
  88. };
  89. /**
  90. * Pause playing audio file.
  91. */
  92. Media.prototype.pause = function() {
  93. exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
  94. };
  95. /**
  96. * Get duration of an audio file.
  97. * The duration is only set for audio that is playing, paused or stopped.
  98. *
  99. * @return duration or -1 if not known.
  100. */
  101. Media.prototype.getDuration = function() {
  102. return this._duration;
  103. };
  104. /**
  105. * Get position of audio.
  106. */
  107. Media.prototype.getCurrentPosition = function(success, fail) {
  108. var me = this;
  109. exec(function(p) {
  110. me._position = p;
  111. success(p);
  112. }, fail, "Media", "getCurrentPositionAudio", [this.id]);
  113. };
  114. /**
  115. * Start recording audio file.
  116. */
  117. Media.prototype.startRecord = function() {
  118. exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
  119. };
  120. /**
  121. * Stop recording audio file.
  122. */
  123. Media.prototype.stopRecord = function() {
  124. exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
  125. };
  126. /**
  127. * Release the resources.
  128. */
  129. Media.prototype.release = function() {
  130. exec(null, this.errorCallback, "Media", "release", [this.id]);
  131. };
  132. /**
  133. * Adjust the volume.
  134. */
  135. Media.prototype.setVolume = function(volume) {
  136. exec(null, null, "Media", "setVolume", [this.id, volume]);
  137. };
  138. /**
  139. * Adjust the playback rate.
  140. */
  141. Media.prototype.setRate = function(rate) {
  142. if (cordova.platformId === 'ios'){
  143. exec(null, null, "Media", "setRate", [this.id, rate]);
  144. } else {
  145. console.warn('media.setRate method is currently not supported for', cordova.platformId, 'platform.');
  146. }
  147. };
  148. /**
  149. * Get amplitude of audio.
  150. */
  151. Media.prototype.getCurrentAmplitude = function(success, fail) {
  152. exec(function(p) {
  153. success(p);
  154. }, fail, "Media", "getCurrentAmplitudeAudio", [this.id]);
  155. };
  156. /**
  157. * Audio has status update.
  158. * PRIVATE
  159. *
  160. * @param id The media object id (string)
  161. * @param msgType The 'type' of update this is
  162. * @param value Use of value is determined by the msgType
  163. */
  164. Media.onStatus = function(id, msgType, value) {
  165. var media = mediaObjects[id];
  166. if (media) {
  167. switch(msgType) {
  168. case Media.MEDIA_STATE :
  169. if (media.statusCallback) {
  170. media.statusCallback(value);
  171. }
  172. if (value == Media.MEDIA_STOPPED) {
  173. if (media.successCallback) {
  174. media.successCallback();
  175. }
  176. }
  177. break;
  178. case Media.MEDIA_DURATION :
  179. media._duration = value;
  180. break;
  181. case Media.MEDIA_ERROR :
  182. if (media.errorCallback) {
  183. media.errorCallback(value);
  184. }
  185. break;
  186. case Media.MEDIA_POSITION :
  187. media._position = Number(value);
  188. break;
  189. default :
  190. if (console.error) {
  191. console.error("Unhandled Media.onStatus :: " + msgType);
  192. }
  193. break;
  194. }
  195. } else if (console.error) {
  196. console.error("Received Media.onStatus callback for unknown media :: " + id);
  197. }
  198. };
  199. module.exports = Media;
  200. function onMessageFromNative(msg) {
  201. if (msg.action == 'status') {
  202. Media.onStatus(msg.status.id, msg.status.msgType, msg.status.value);
  203. } else {
  204. throw new Error('Unknown media action' + msg.action);
  205. }
  206. }
  207. if (cordova.platformId === 'android' || cordova.platformId === 'amazon-fireos' || cordova.platformId === 'windowsphone') {
  208. var channel = require('cordova/channel');
  209. channel.createSticky('onMediaPluginReady');
  210. channel.waitForInitialization('onMediaPluginReady');
  211. channel.onCordovaReady.subscribe(function() {
  212. exec(onMessageFromNative, undefined, 'Media', 'messageChannel', []);
  213. channel.initializationComplete('onMediaPluginReady');
  214. });
  215. }