www/Media.js (176 lines of code) (raw):

/* * * 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. * */ /* global cordova */ var argscheck = require('cordova/argscheck'); var utils = require('cordova/utils'); var 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 * * @param durationUpdateCallback The callback to be called when the duration updates. * durationUpdateCallback(float duration) - OPTIONAL * */ var Media = function (src, successCallback, errorCallback, statusCallback, durationUpdateCallback) { 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.durationUpdateCallback = durationUpdateCallback; 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]); }; /** * Pause recording audio file. */ Media.prototype.pauseRecord = function () { exec(null, this.errorCallback, 'Media', 'pauseRecordingAudio', [this.id]); }; /** * Resume recording audio file. */ Media.prototype.resumeRecord = function () { exec(null, this.errorCallback, 'Media', 'resumeRecordingAudio', [this.id]); }; /** * Release the resources. */ Media.prototype.release = function () { var me = this; exec( function () { delete mediaObjects[me.id]; }, 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' || cordova.platformId === 'android') { exec(null, null, 'Media', 'setRate', [this.id, rate]); } else { console.warn('media.setRate method is currently not supported for', cordova.platformId, 'platform.'); } }; /** * Get amplitude of audio. */ Media.prototype.getCurrentAmplitude = function (success, fail) { exec( function (p) { success(p); }, fail, 'Media', 'getCurrentAmplitudeAudio', [this.id] ); }; /** * 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: if (media.statusCallback) { media.statusCallback(value); } if (value === Media.MEDIA_STOPPED) { if (media.successCallback) { media.successCallback(); } } break; case Media.MEDIA_DURATION: media._duration = value; if (media.durationUpdateCallback) { media.durationUpdateCallback(value); } break; case Media.MEDIA_ERROR: if (media.errorCallback) { media.errorCallback(value); } break; case Media.MEDIA_POSITION: media._position = Number(value); break; default: if (console.error) { console.error('Unhandled Media.onStatus :: ' + msgType); } break; } } else if (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') { var channel = require('cordova/channel'); channel.createSticky('onMediaPluginReady'); channel.waitForInitialization('onMediaPluginReady'); channel.onCordovaReady.subscribe(function () { exec(onMessageFromNative, undefined, 'Media', 'messageChannel', []); channel.initializationComplete('onMediaPluginReady'); }); }