'globalization/cordova_globalization.gyp:*',
'networkinformation/cordova_networkinformation.gyp:*',
'filetransfer/cordova_filetransfer.gyp:*',
+ 'media/cordova_media.gyp:*',
],
},
], # end targets
"clobbers": [
"navigator.globalization"
]
+ },
+ {
+ "file": "plugins/cordova-plugin-media/www/MediaError.js",
+ "id": "cordova-plugin-media.MediaError",
+ "clobbers": [
+ "window.MediaError"
+ ]
+ },
+ {
+ "file": "plugins/cordova-plugin-media/www/Media.js",
+ "id": "cordova-plugin-media.Media",
+ "clobbers": [
+ "window.Media"
+ ]
}
];
module.exports.metadata =
"cordova-plugin-file-transfer": "1.3.0",
"cordova-plugin-network-information": "1.0.1",
"cordova-plugin-globalization": "1.0.1",
+ "cordova-plugin-media": "1.0.1",
}
// BOTTOM OF METADATA
});
--- /dev/null
+cordova.define("cordova-plugin-media.Media", function(require, exports, module) { /*
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+var argscheck = require('cordova/argscheck'),
+ utils = require('cordova/utils'),
+ exec = require('cordova/exec');
+
+var mediaObjects = {};
+
+/**
+ * This class provides access to the device media, interfaces to both sound and video
+ *
+ * @constructor
+ * @param src The file name or url to play
+ * @param successCallback The callback to be called when the file is done playing or recording.
+ * successCallback()
+ * @param errorCallback The callback to be called if there is an error.
+ * errorCallback(int errorCode) - OPTIONAL
+ * @param statusCallback The callback to be called when media status has changed.
+ * statusCallback(int statusCode) - OPTIONAL
+ */
+var Media = function(src, successCallback, errorCallback, statusCallback) {
+ argscheck.checkArgs('sFFF', 'Media', arguments);
+ this.id = utils.createUUID();
+ mediaObjects[this.id] = this;
+ this.src = src;
+ this.successCallback = successCallback;
+ this.errorCallback = errorCallback;
+ this.statusCallback = statusCallback;
+ this._duration = -1;
+ this._position = -1;
+ exec(null, this.errorCallback, "Media", "create", [this.id, this.src]);
+};
+
+// Media messages
+Media.MEDIA_STATE = 1;
+Media.MEDIA_DURATION = 2;
+Media.MEDIA_POSITION = 3;
+Media.MEDIA_ERROR = 9;
+
+// Media states
+Media.MEDIA_NONE = 0;
+Media.MEDIA_STARTING = 1;
+Media.MEDIA_RUNNING = 2;
+Media.MEDIA_PAUSED = 3;
+Media.MEDIA_STOPPED = 4;
+Media.MEDIA_MSG = ["None", "Starting", "Running", "Paused", "Stopped"];
+
+// "static" function to return existing objs.
+Media.get = function(id) {
+ return mediaObjects[id];
+};
+
+/**
+ * Start or resume playing audio file.
+ */
+Media.prototype.play = function(options) {
+ exec(null, null, "Media", "startPlayingAudio", [this.id, this.src, options]);
+};
+
+/**
+ * Stop playing audio file.
+ */
+Media.prototype.stop = function() {
+ var me = this;
+ exec(function() {
+ me._position = 0;
+ }, this.errorCallback, "Media", "stopPlayingAudio", [this.id]);
+};
+
+/**
+ * Seek or jump to a new time in the track..
+ */
+Media.prototype.seekTo = function(milliseconds) {
+ var me = this;
+ exec(function(p) {
+ me._position = p;
+ }, this.errorCallback, "Media", "seekToAudio", [this.id, milliseconds]);
+};
+
+/**
+ * Pause playing audio file.
+ */
+Media.prototype.pause = function() {
+ exec(null, this.errorCallback, "Media", "pausePlayingAudio", [this.id]);
+};
+
+/**
+ * Get duration of an audio file.
+ * The duration is only set for audio that is playing, paused or stopped.
+ *
+ * @return duration or -1 if not known.
+ */
+Media.prototype.getDuration = function() {
+ return this._duration;
+};
+
+/**
+ * Get position of audio.
+ */
+Media.prototype.getCurrentPosition = function(success, fail) {
+ var me = this;
+ exec(function(p) {
+ me._position = p;
+ success(p);
+ }, fail, "Media", "getCurrentPositionAudio", [this.id]);
+};
+
+/**
+ * Start recording audio file.
+ */
+Media.prototype.startRecord = function() {
+ exec(null, this.errorCallback, "Media", "startRecordingAudio", [this.id, this.src]);
+};
+
+/**
+ * Stop recording audio file.
+ */
+Media.prototype.stopRecord = function() {
+ exec(null, this.errorCallback, "Media", "stopRecordingAudio", [this.id]);
+};
+
+/**
+ * Release the resources.
+ */
+Media.prototype.release = function() {
+ exec(null, this.errorCallback, "Media", "release", [this.id]);
+};
+
+/**
+ * Adjust the volume.
+ */
+Media.prototype.setVolume = function(volume) {
+ exec(null, null, "Media", "setVolume", [this.id, volume]);
+};
+
+/**
+ * Adjust the playback rate.
+ */
+Media.prototype.setRate = function(rate) {
+ if (cordova.platformId === 'ios'){
+ exec(null, null, "Media", "setRate", [this.id, rate]);
+ } else {
+ console.warn('media.setRate method is currently not supported for', cordova.platformId, 'platform.')
+ }
+};
+
+
+/**
+ * Audio has status update.
+ * PRIVATE
+ *
+ * @param id The media object id (string)
+ * @param msgType The 'type' of update this is
+ * @param value Use of value is determined by the msgType
+ */
+Media.onStatus = function(id, msgType, value) {
+
+ var media = mediaObjects[id];
+
+ if(media) {
+ switch(msgType) {
+ case Media.MEDIA_STATE :
+ media.statusCallback && media.statusCallback(value);
+ if(value == Media.MEDIA_STOPPED) {
+ media.successCallback && media.successCallback();
+ }
+ break;
+ case Media.MEDIA_DURATION :
+ media._duration = value;
+ break;
+ case Media.MEDIA_ERROR :
+ media.errorCallback && media.errorCallback(value);
+ break;
+ case Media.MEDIA_POSITION :
+ media._position = Number(value);
+ break;
+ default :
+ console.error && console.error("Unhandled Media.onStatus :: " + msgType);
+ break;
+ }
+ }
+ else {
+ console.error && console.error("Received Media.onStatus callback for unknown media :: " + id);
+ }
+
+};
+
+module.exports = Media;
+
+function onMessageFromNative(msg) {
+ if (msg.action == 'status') {
+ Media.onStatus(msg.status.id, msg.status.msgType, msg.status.value);
+ } else {
+ throw new Error('Unknown media action' + msg.action);
+ }
+}
+
+if (cordova.platformId === 'android' || cordova.platformId === 'amazon-fireos' || cordova.platformId === 'windowsphone') {
+
+ var channel = require('cordova/channel');
+
+ channel.createSticky('onMediaPluginReady');
+ channel.waitForInitialization('onMediaPluginReady');
+
+ channel.onCordovaReady.subscribe(function() {
+ exec(onMessageFromNative, undefined, 'Media', 'messageChannel', []);
+ channel.initializationComplete('onMediaPluginReady');
+ });
+}
+
+});
--- /dev/null
+cordova.define("cordova-plugin-media.MediaError", function(require, exports, module) { /*
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+*/
+
+/**
+ * This class contains information about any Media errors.
+*/
+/*
+ According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror
+ We should never be creating these objects, we should just implement the interface
+ which has 1 property for an instance, 'code'
+
+ instead of doing :
+ errorCallbackFunction( new MediaError(3,'msg') );
+we should simply use a literal :
+ errorCallbackFunction( {'code':3} );
+ */
+
+
+ var _MediaError = window.MediaError;
+
+
+if(!_MediaError) {
+ window.MediaError = _MediaError = function(code, msg) {
+ this.code = (typeof code != 'undefined') ? code : null;
+ this.message = msg || ""; // message is NON-standard! do not use!
+ };
+}
+
+_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0;
+_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1;
+_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2;
+_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3;
+_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;
+// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.
+// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes
+_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;
+
+module.exports = _MediaError;
+});
* limitations under the License.
*/
-var _global = window || global || {};
-var _document = document || {};
-
-/**
- * This class contains information about any Media errors
-*/
-/*
- According to :: http://dev.w3.org/html5/spec-author-view/video.html#mediaerror
- We should never be creating these objects, we should just implement the interface
- which has 1 property for an instance, 'code'
-
- instead of doing :
- errorCallbackFunction( new MediaError(3,'msg') );
-we should simply use a literal :
- errorCallbackFunction( {'code':3} );
- */
-
- var _MediaError = window.MediaError;
-
-
-if(!_MediaError) {
- window.MediaError = _MediaError = function(code, msg) {
- this.code = (typeof code != 'undefined') ? code : null;
- this.message = msg || ""; // message is NON-standard! do not use!
- };
-}
-
-_MediaError.MEDIA_ERR_NONE_ACTIVE = _MediaError.MEDIA_ERR_NONE_ACTIVE || 0;
-_MediaError.MEDIA_ERR_ABORTED = _MediaError.MEDIA_ERR_ABORTED || 1;
-_MediaError.MEDIA_ERR_NETWORK = _MediaError.MEDIA_ERR_NETWORK || 2;
-_MediaError.MEDIA_ERR_DECODE = _MediaError.MEDIA_ERR_DECODE || 3;
-_MediaError.MEDIA_ERR_NONE_SUPPORTED = _MediaError.MEDIA_ERR_NONE_SUPPORTED || 4;
-// TODO: MediaError.MEDIA_ERR_NONE_SUPPORTED is legacy, the W3 spec now defines it as below.
-// as defined by http://dev.w3.org/html5/spec-author-view/video.html#error-codes
-_MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = _MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED || 4;
-
-MediaError = _MediaError;
-
-var audioObjects = {};
-var mediaObjects = {};
-
-
-
-function create(args) {
- var id = args[0], src = args[1];
-
- console.log("media::create() - id =" + id + ", src =" + src);
-
- audioObjects[id] = new Audio(src);
-
- audioObjects[id].onStalledCB = function () {
- console.log("media::onStalled()");
-
- audioObjects[id].timer = window.setTimeout(
- function () {
- audioObjects[id].pause();
-
- if (audioObjects[id].currentTime !== 0)
- audioObjects[id].currentTime = 0;
-
- console.log("media::onStalled() - MEDIA_ERROR -> " + MediaError.MEDIA_ERR_ABORTED);
-
- var err = new MediaError(MediaError.MEDIA_ERR_ABORTED, "Stalled");
-
- Media.onStatus(id, Media.MEDIA_ERROR, err);
- }, 2000);
- };
-
- audioObjects[id].onEndedCB = function () {
- console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED);
- };
-
- audioObjects[id].onErrorCB = function () {
- console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error);
-
- Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error);
- };
-
- audioObjects[id].onPlayCB = function () {
- console.log("media::onPlayCB() - MEDIA_STATE -> MEDIA_STARTING");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING);
- };
-
- audioObjects[id].onPlayingCB = function () {
- console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING");
-
- Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING);
- };
-
- audioObjects[id].onDurationChangeCB = function () {
- console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " + audioObjects[id].duration);
-
- Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration);
- };
-
- audioObjects[id].onTimeUpdateCB = function () {
- console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " + audioObjects[id].currentTime);
-
- Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime);
- };
-
- audioObjects[id].onCanPlayCB = function () {
- console.log("media::onCanPlayCB()");
-
- window.clearTimeout(audioObjects[id].timer);
-
- audioObjects[id].play();
- };
-}
-
-function Media(src, mediaSuccess, mediaError, mediaStatus) {
- this.src = src;
- this.id = utils.createUUID();
- this.mediaSuccess = mediaSuccess;
- this.mediaError = mediaError;
- this.mediaStatus = mediaStatus;
- this._duration = -1;
- this._position = -1;
- mediaObjects[this.id] = this;
- create([this.id, this.src])
-}
-
-/**
- * Audio has status update.
- * PRIVATE
- *
- * @param id The media object id (string)
- * @param msgType The 'type' of update this is
- * @param value Use of value is determined by the msgType
- */
-Media.onStatus = function(id, msgType, value) {
-
- var media = mediaObjects[id];
-
- if(media) {
- switch(msgType) {
- case Media.MEDIA_STATE :
- media.statusCallback && media.statusCallback(value);
- if(value == Media.MEDIA_STOPPED) {
- media.successCallback && media.successCallback();
- }
- break;
- case Media.MEDIA_DURATION :
- media._duration = value;
- break;
- case Media.MEDIA_ERROR :
- media.errorCallback && media.errorCallback(value);
- break;
- case Media.MEDIA_POSITION :
- media._position = Number(value);
- break;
- default :
- console.error && console.error("Unhandled Media.onStatus :: " + msgType);
- break;
- }
- }
- else {
- console.error && console.error("Received Media.onStatus callback for unknown media :: " + id);
- }
-
+// TODO: remove when added to public cordova repository -> begin
+var plugin_name = 'cordova-plugin-media.tizen.Media';
+
+cordova.define(plugin_name, function(require, exports, module) {
+// TODO: remove -> end
+
+ exports = {
+ create: function(successCallback, errorCallback, args) {
+ console.log("Media create stub");
+ },
+ startPlayingAudio: function(successCallback, errorCallback, args) {},
+ stopPlayingAudio: function(successCallback, errorCallback, args) {},
+ seekToAudio: function(successCallback, errorCallback, args) {},
+ pausePlayingAudio: function(successCallback, errorCallback, args) {},
+ getCurrentPositionAudio: function(successCallback, errorCallback, args) {},
+ startRecordingAudio: function(successCallback, errorCallback, args) {},
+ stopRecordingAudio: function(successCallback, errorCallback, args) {},
+ release: function(successCallback, errorCallback, args) {},
+ setVolume: function(successCallback, errorCallback, args) {},
+ setRate: function(successCallback, errorCallback, args) {},
+ messageChannel: function(successCallback, errorCallback, args) {}
};
+require("cordova/exec/proxy").add("Media", exports);
-Media.prototype.getCurrentPosition = function(mediaSuccess, mediaError){}
-
-Media.prototype.getDuration = function(){};
-
-Media.prototype.pause = function(){};
-
-Media.prototype.play = function(){
- var id = this.id, src = this.src;
-
- console.log("media::startPlayingAudio() - id =" + id + ", src =" + src);
-
- audioObjects[id].addEventListener('canplay', audioObjects[id].onCanPlayCB);
- audioObjects[id].addEventListener('ended', audioObjects[id].onEndedCB);
- audioObjects[id].addEventListener('timeupdate', audioObjects[id].onTimeUpdateCB);
- audioObjects[id].addEventListener('durationchange', audioObjects[id].onDurationChangeCB);
- audioObjects[id].addEventListener('playing', audioObjects[id].onPlayingCB);
- audioObjects[id].addEventListener('play', audioObjects[id].onPlayCB);
- audioObjects[id].addEventListener('error', audioObjects[id].onErrorCB);
- audioObjects[id].addEventListener('stalled', audioObjects[id].onStalledCB);
-
- audioObjects[id].play();
-
-};
-
-Media.prototype.release = function(){};
-
-Media.prototype.seekTo = function(miliseconds){};
-
-Media.prototype.setVolume = function(volume){};
-
-Media.prototype.startRecord = function(){};
-
-Media.prototype.stop = function(){};
-
-Media.prototype.stopRecord = function(){};
-
-_global.Media = Media;
+console.log('Loaded cordova.media API');
-console.log('Loaded cordova.device API');
+//TODO: remove when added to public cordova repository -> begin
+});
exports = function(require) {
+ // this plugin is not loaded via cordova_plugins.js, we need to manually add
+ // it to module mapper
+ var mm = require('cordova/modulemapper');
+ mm.runs(plugin_name);
};
* limitations under the License.
*/
-#include "cordova/media/cordova_media_extension.h"
+#include "media/cordova_media_extension.h"
// This will be generated from cordova_media_api.js
extern const char kSource_cordova_media_api[];