pausePlayingAudio:function(win, lose, args) { var id = args[0]; var thisM = Media.get(id); try { thisM.node.pause(); Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED); } catch (err) { lose("Failed to pause: "+err); } },
stopPlayingAudio:function(win, lose, args) { var id = args[0]; try { var thisM = Media.get(id); thisM.node.pause(); thisM.node.currentTime = 0; Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); } catch (err) { lose("Failed to stop: "+err); } },
create:function(win, lose, args) { var id = args[0]; var srcUri = processUri(args[1]); var createAudioNode = !!args[2]; var thisM = Media.get(id); Media.prototype.node = null; var prefix = args[1].split(':').shift(); var extension = srcUri.extension; if (thisM.node === null) { if (SUPPORTED_EXTENSIONS.indexOf(extension) === -1 && SUPPORTED_PREFIXES.indexOf(prefix) === -1) { if (lose) { lose({ code: MediaError.MEDIA_ERR_ABORTED }); } return false; // unable to create } // Don't create Audio object in case of record mode if (createAudioNode === true) { thisM.node = new Audio(); thisM.node.msAudioCategory = "BackgroundCapableMedia"; thisM.node.src = srcUri.absoluteCanonicalUri; thisM.node.onloadstart = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING); }; thisM.node.ontimeupdate = function (e) { Media.onStatus(id, Media.MEDIA_POSITION, e.target.currentTime); }; thisM.node.onplaying = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); }; thisM.node.ondurationchange = function (e) { Media.onStatus(id, Media.MEDIA_DURATION, e.target.duration || -1); }; thisM.node.onerror = function (e) { // Due to media.spec.15 It should return MediaError for bad filename var err = e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ? { code: MediaError.MEDIA_ERR_ABORTED } : e.target.error; Media.onStatus(id, Media.MEDIA_ERROR, err); }; thisM.node.onended = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); }; } } return true; // successfully created },
thisM.node.onerror = function(e) { // Due to media.spec.15 It should return MediaError for bad filename var err = e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ? { code: MediaError.MEDIA_ERR_ABORTED } : e.target.error; Media.onStatus(id, Media.MEDIA_ERROR, err); };
pausePlayingAudio:function(successCallback, errorCallback, args) { var id = args[0]; console.log("media::pausePlayingAudio() - MEDIA_STATE -> MEDIA_PAUSED"); audioObjects[id].pause(); Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_PAUSED); },
getCurrentPositionAudio:function(win, lose, args) { var id = args[0]; try { var p = (Media.get(id)).node.currentTime; win(p); } catch (err) { lose(err); } },
seekToAudio:function(win, lose, args) { var id = args[0]; var milliseconds = args[1]; var thisM = Media.get(id); try { thisM.node.currentTime = milliseconds / 1000; win(thisM.node.currentTime); } catch (err) { lose("Failed to seek: "+err); } },
release:function(win, lose, args) { var id = args[0]; var thisM = Media.get(id); try { if (thisM.node) { thisM.node.onloadedmetadata = null; delete thisM.node; } } catch (err) { lose("Failed to release: "+err); } },
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); },
create:function(win, lose, args) { var id = args[0]; var src = args[1]; var thisM = Media.get(id); Media.prototype.node = null; var fn = src.split('.').pop(); // gets the file extension if (thisM.node === null) { if (fn === 'mp3' || fn === 'wma' || fn === 'wav' || fn === 'cda' || fn === 'adx' || fn === 'wm' || fn === 'm3u' || fn === 'wmx' || fn === 'm4a') { thisM.node = new Audio(src); thisM.node.onloadstart = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING); }; thisM.node.ontimeupdate = function (e) { Media.onStatus(id, Media.MEDIA_POSITION, e.target.currentTime); }; thisM.node.onplaying = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); }; thisM.node.ondurationchange = function (e) { Media.onStatus(id, Media.MEDIA_DURATION, e.target.duration || -1); }; thisM.node.onerror = function(e) { // Due to media.spec.15 It should return MediaError for bad filename var err = e.target.error.code === MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED ? { code: MediaError.MEDIA_ERR_ABORTED } : e.target.error; Media.onStatus(id, Media.MEDIA_ERROR, err); }; thisM.node.onended = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); }; } else { lose && lose({ code: MediaError.MEDIA_ERR_ABORTED }); return false; // unable to create } } return true; // successfully created },
startRecordingAudio:function(win, lose, args) { var id = args[0]; var srcUri = processUri(args[1]); var dest = parseUriToPathAndFilename(srcUri); var destFileName = dest.fileName; var success = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); }; var error = function (reason) { Media.onStatus(id, Media.MEDIA_ERROR, reason); }; // Initialize device Media.prototype.mediaCaptureMgr = null; var thisM = (Media.get(id)); var captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings(); captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio; thisM.mediaCaptureMgr = new Windows.Media.Capture.MediaCapture(); thisM.mediaCaptureMgr.addEventListener("failed", error); thisM.mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) { thisM.mediaCaptureMgr.addEventListener("recordlimitationexceeded", error); thisM.mediaCaptureMgr.addEventListener("failed", error); // Start recording Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync(destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(function (newFile) { recordedFile = newFile; var encodingProfile = null; switch (newFile.fileType) { case '.m4a': encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(Windows.Media.MediaProperties.AudioEncodingQuality.auto); break; case '.mp3': encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.auto); break; case '.wma': encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createWma(Windows.Media.MediaProperties.AudioEncodingQuality.auto); break; default: error("Invalid file type for record"); break; } thisM.mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, newFile).done(success, error); }, error); }, error); },
release:function(win, lose, args) { var id = args[0]; var thisM = Media.get(id); try { if (thisM.node) { thisM.node.onloadedmetadata = null; // Unsubscribing as the media object is being released thisM.node.onerror = null; // Needed to avoid "0x80070005 - JavaScript runtime error: Access is denied." on copyAsync thisM.node.src = null; delete thisM.node; } } catch (err) { lose("Failed to release: "+err); } },
stopRecordingAudio:function(win, lose, args) { var id = args[0]; var thisM = Media.get(id); var normalizedSrc = thisM.src.replace(/\//g, '\\'); var destPath = normalizedSrc.substr(0, normalizedSrc.lastIndexOf('\\')); var destFileName = normalizedSrc.replace(destPath + '\\', ''); thisM.mediaCaptureMgr.stopRecordAsync().done(function () { if (destPath) { Windows.Storage.StorageFolder.getFolderFromPathAsync(destPath).done(function(destFolder) { recordedFile.copyAsync(destFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(win, lose); }, lose); } else { // if path is not defined, we leave recorded file in temporary folder (similar to iOS) win(); } }, lose); },
startRecordingAudio:function(win, lose, args) { var id = args[0]; var src = args[1]; var normalizedSrc = src.replace(/\//g, '\\'); var destPath = normalizedSrc.substr(0, normalizedSrc.lastIndexOf('\\')); var destFileName = normalizedSrc.replace(destPath + '\\', ''); // Initialize device Media.prototype.mediaCaptureMgr = null; var thisM = (Media.get(id)); var captureInitSettings = new Windows.Media.Capture.MediaCaptureInitializationSettings(); captureInitSettings.streamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.audio; thisM.mediaCaptureMgr = new Windows.Media.Capture.MediaCapture(); thisM.mediaCaptureMgr.addEventListener("failed", lose); thisM.mediaCaptureMgr.initializeAsync(captureInitSettings).done(function (result) { thisM.mediaCaptureMgr.addEventListener("recordlimitationexceeded", lose); thisM.mediaCaptureMgr.addEventListener("failed", lose); // Start recording Windows.Storage.ApplicationData.current.temporaryFolder.createFileAsync(destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(function (newFile) { recordedFile = newFile; var encodingProfile = null; switch (newFile.fileType) { case '.m4a': encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createM4a(Windows.Media.MediaProperties.AudioEncodingQuality.auto); break; case '.mp3': encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createMp3(Windows.Media.MediaProperties.AudioEncodingQuality.auto); break; case '.wma': encodingProfile = Windows.Media.MediaProperties.MediaEncodingProfile.createWma(Windows.Media.MediaProperties.AudioEncodingQuality.auto); break; default: lose("Invalid file type for record"); break; } thisM.mediaCaptureMgr.startRecordToStorageFileAsync(encodingProfile, newFile).done(win, lose); }, lose); }, lose); },
startPlayingAudio:function(win, lose, args) { var id = args[0]; //var src = args[1]; //var options = args[2]; var thisM = Media.get(id); // if Media was released, then node will be null and we need to create it again if (!thisM.node) { if (!module.exports.create(win, lose, args)) { // there is no reason to continue if we can't create media // corresponding callback has been invoked in create so we don't need to call it here return; } } try { thisM.node.play(); } catch (err) { lose && lose({code:MediaError.MEDIA_ERR_ABORTED}); } },
stopRecordingAudio:function(win, lose, args) { var id = args[0]; var thisM = Media.get(id); var srcUri = processUri(thisM.src); var dest = parseUriToPathAndFilename(srcUri); var destPath = dest.path; var destFileName = dest.fileName; var fsType = dest.fsType; var success = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); }; var error = function (reason) { Media.onStatus(id, Media.MEDIA_ERROR, reason); }; thisM.mediaCaptureMgr.stopRecordAsync().done(function () { if (fsType === fsTypes.TEMPORARY) { if (!destPath) { // if path is not defined, we leave recorded file in temporary folder (similar to iOS) success(); } else { Windows.Storage.ApplicationData.current.temporaryFolder.getFolderAsync(destPath).done(function (destFolder) { recordedFile.copyAsync(destFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(success, error); }, error); } } else { // Copying file to persistent storage if (!destPath) { recordedFile.copyAsync(Windows.Storage.ApplicationData.current.localFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(success, error); } else { Windows.Storage.ApplicationData.current.localFolder.getFolderAsync(destPath).done(function (destFolder) { recordedFile.copyAsync(destFolder, destFileName, Windows.Storage.CreationCollisionOption.replaceExisting).done(success, error); }, error); } } }, error); },
stopPlayingAudio:function(successCallback, errorCallback, args) { var id = args[0]; window.clearTimeout(audioObjects[id].timer); audioObjects[id].pause(); if (audioObjects[id].currentTime !== 0) audioObjects[id].currentTime = 0; console.log("media::stopPlayingAudio() - MEDIA_STATE -> MEDIA_STOPPED"); Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); audioObjects[id].removeEventListener('canplay', audioObjects[id].onCanPlayCB); audioObjects[id].removeEventListener('ended', audioObjects[id].onEndedCB); audioObjects[id].removeEventListener('timeupdate', audioObjects[id].onTimeUpdateCB); audioObjects[id].removeEventListener('durationchange', audioObjects[id].onDurationChangeCB); audioObjects[id].removeEventListener('playing', audioObjects[id].onPlayingCB); audioObjects[id].removeEventListener('play', audioObjects[id].onPlayCB); audioObjects[id].removeEventListener('error', audioObjects[id].onErrorCB); audioObjects[id].removeEventListener('error', audioObjects[id].onStalledCB); },
audioObjects[id].onEndedCB = function () { console.log("media::onEndedCB() - MEDIA_STATE -> MEDIA_STOPPED"); Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); };
var success = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); };
thisM.node.onended = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STOPPED); };
thisM.node.ondurationchange = function (e) { Media.onStatus(id, Media.MEDIA_DURATION, e.target.duration || -1); };
thisM.node.onplaying = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); };
thisM.node.ontimeupdate = function (e) { Media.onStatus(id, Media.MEDIA_POSITION, e.target.currentTime); };
audioObjects[id].onDurationChangeCB = function () { console.log("media::onDurationChangeCB() - MEDIA_DURATION -> " + audioObjects[id].duration); Media.onStatus(id, Media.MEDIA_DURATION, audioObjects[id].duration); };
setVolume:function(win, lose, args) { var id = args[0]; var volume = args[1]; var thisM = Media.get(id); thisM.volume = volume; }
audioObjects[id].onErrorCB = function () { console.log("media::onErrorCB() - MEDIA_ERROR -> " + event.srcElement.error); Media.onStatus(id, Media.MEDIA_ERROR, event.srcElement.error); };
audioObjects[id].onPlayingCB = function () { console.log("media::onPlayingCB() - MEDIA_STATE -> MEDIA_RUNNING"); Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_RUNNING); };
var error = function (reason) { Media.onStatus(id, Media.MEDIA_ERROR, reason); };
audioObjects[id].onTimeUpdateCB = function () { console.log("media::onTimeUpdateCB() - MEDIA_POSITION -> " + audioObjects[id].currentTime); Media.onStatus(id, Media.MEDIA_POSITION, audioObjects[id].currentTime); };
thisM.node.onloadstart = function () { Media.onStatus(id, Media.MEDIA_STATE, Media.MEDIA_STARTING); };