amplitudejs
Version:
A JavaScript library that allows you to control the design of your media controls in your webpage -- not the browser. No dependencies (jQuery not required) https://521dimensions.com/open-source/amplitudejs
1,764 lines (1,497 loc) • 382 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("Amplitude", [], factory);
else if(typeof exports === 'object')
exports["Amplitude"] = factory();
else
root["Amplitude"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 47);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _package = __webpack_require__(59);
module.exports = {
version: _package.version,
audio: new Audio(),
active_metadata: {},
active_album: "",
active_index: 0,
active_playlist: null,
playback_speed: 1.0,
callbacks: {},
songs: [],
playlists: {},
start_song: "",
starting_playlist: "",
starting_playlist_song: "",
repeat: false,
repeat_song: false,
shuffle_list: {},
shuffle_on: false,
default_album_art: "",
default_playlist_art: "",
debug: false,
volume: 0.5,
pre_mute_volume: 0.5,
volume_increment: 5,
volume_decrement: 5,
soundcloud_client: "",
soundcloud_use_art: false,
soundcloud_song_count: 0,
soundcloud_songs_ready: 0,
is_touch_moving: false,
buffered: 0,
bindings: {},
continue_next: true,
delay: 0,
player_state: "stopped",
web_audio_api_available: false,
context: null,
source: null,
analyser: null,
visualizations: {
available: [],
active: [],
backup: ""
},
waveforms: {
sample_rate: 100,
built: []
}
}; /**
* These variables make Amplitude run. The config is the most important
* containing active settings and parameters.
*
* The config JSON is the global settings for ALL of Amplitude functions.
* This is global and contains all of the user preferences. The default
* settings are set, and the user overwrites them when they initialize
* Amplitude.
*
* @module config
* @type {object}
* @property {string} config.version - The current version of AmplitudeJS.
* @property {object} config.audio - Handles all of the audio.
* @property {object} config.active_metadata - Contains the active metadata for the song.
* @property {string} config.active_album - Holds the active album name. Used to check and see if the album changed and run the album changed callback.
* @property {number} config.active_index - Contains the index of the actively playing song.
* @property {string} config.active_playlist - Contains the key to the active playlist index.
* @property {number} config.playback_speed - Sets the initial playback speed of the song. The values for this can be 1.0, 1.5, 2.0
* @property {object} config.callbacks - The user can pass a JSON object with a key => value store of callbacks to be run at certain events.
* @property {array} config.songs - Contains all of the songs the user has passed to Amplitude to use.
* @property {object} config.playlists - Contains all of the playlists the user created.
* @property {object} config.start_song - The index of the song that AmplitudeJS should start with.
* @property {string} config.starting_playlist - The starting playlist the player will intiialize to.
* @property {string} config.starting_playlist_song - The index of the song in the playlist that should be started.
* @property {boolean} config.repeat - When repeat is on, when the song ends the song will replay itself.
* @property {object} config.shuffle_list - When shuffled, gets populated with the songs the user provided in a random order.
* @property {boolean} config.shuffle_on - When on, gets set to true so when traversing through songs, AmplitudeJS knows whether or not to use the songs object or the shuffle_list
* @property {string} config.default_album_art - The user can set default album art to be displayed if the song they set doesn't contain album art.
* @property {string} config.default_playlist_art - The user can set default playlist art to be displayed if the playlist they are setting meta data for doesn't contain an art picture.
* @property {boolean} config.debug - When set to true, AmplitudeJS will print to the console any errors providing helpful feedback to the user.
* @property {number} config.volume - The user can set the initial volume to a number between 0 and 1 over-riding the default of .5
* @property {number} config.pre_mute_volume - This is set on mute so that when a user un-mutes AmplitudeJS knows what to restore the volume to.
* @property {number} config.volume_increment - The default values are an integer between 1 and 100 for how much the volume should increase when the user presses the volume up button.
* @property {number} config.volume_decrement - The default values are an integer between 1 and 100 for how much the volume should decrease when the user presses the volume down button.
* @property {string} config.soundcloud_client - When using SoundCloud, the user will have to provide their API Client ID
* @property {boolean} config.soundcloud_use_art - The user can set this to true and AmplitudeJS will use the album art for the song returned from the Soundcloud API
* @property {number} config.soundcloud_song_count - Used on config to count how many songs are from Soundcloud and compare it to how many are ready for when to move to the rest of the configuration
* @property {number} config.soundcloud_songs_ready - Used on config to count how many songs are ready so when we get all of the data from the SoundCloud API that we need this should match the SoundCloud song count meaning we can move to the rest of the config.
* @property {integer} config.is_touch_moving - Flag for if the user is moving the screen.
* @property {boolean} config.buffered - How much of the song is buffered.
* @property {object} config.bindings - Array of bindings to certain key events.
* @property {boolean} config.continue_next - Determines when a song ends, we should continue to the next song.
* @property {number} config.delay - Sets the delay between songs in MS.
* @property {boolean} config.use_web_audio_api - Flag that determines if the user wants to use Web Audio API Components.
* @property {boolean} config.web_audio_api_available - Flag that determines if the Web Audio API is available.
* @property {object} config.context - Web Audio API Context
* @property {object} config.source - Web Audio API Source
* @property {object} config.analyser - Web Audio API Analyser
* @property {string} config.player_state - The current state of the player.
*/
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _config = __webpack_require__(0);
var _config2 = _interopRequireDefault(_config);
var _checks = __webpack_require__(5);
var _checks2 = _interopRequireDefault(_checks);
var _audioNavigation = __webpack_require__(3);
var _audioNavigation2 = _interopRequireDefault(_audioNavigation);
var _playPauseElements = __webpack_require__(2);
var _playPauseElements2 = _interopRequireDefault(_playPauseElements);
var _metaDataElements = __webpack_require__(7);
var _metaDataElements2 = _interopRequireDefault(_metaDataElements);
var _callbacks = __webpack_require__(9);
var _callbacks2 = _interopRequireDefault(_callbacks);
var _debug = __webpack_require__(4);
var _debug2 = _interopRequireDefault(_debug);
var _visualizations = __webpack_require__(16);
var _visualizations2 = _interopRequireDefault(_visualizations);
var _configState = __webpack_require__(6);
var _configState2 = _interopRequireDefault(_configState);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Interacts directly with native functions of the Audio element. Logic
* leading up to these methods are handled by click handlers which call
* helpers and visual synchronizers. These are the core functions of AmplitudeJS.
* Every other function that leads to these prepare the information to be
* acted upon by these functions.
*
* @module core/Core
*/
/**
* Import the Visualizations from the FX module.
* @module fx/visualizations
*/
/**
* Imports AmplitudeJS Callback Utility
* @module utilities/callbacks
*/
/**
* Imports the Play/Pause Visual Elements module.
* @module visual/playPauseElements
*/
/**
* Imports the Checks module.
* @module utilities/checks
*/
var Core = function () {
/**
* Plays the active song. If the current song is live, it reconnects
* the stream before playing.
*
* Public Accessor: Amplitude.play()
*
* @access public
*/
function play() {
_visualizations2.default.stop();
_visualizations2.default.run();
/*
If the audio is live we re-conenct the stream.
*/
if (_config2.default.active_metadata.live) {
reconnectStream();
}
/*
Mobile remote sources need to be reconnected on play. I think this is
because mobile browsers are optimized not to load all resources
for speed reasons. We only do this if mobile and the paused button
is not clicked. If the pause button was clicked then we don't reconnect
or the user will lose their place in the stream.
*/
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) && !_config2.default.paused) {
reconnectStream();
}
/*
Play the song and set the playback rate to the playback
speed.
*/
var playPromise = _config2.default.audio.play();
if (playPromise !== undefined) {
playPromise.then(function (_) {}).catch(function (error) {});
}
_config2.default.audio.play();
_config2.default.audio.playbackRate = _config2.default.playback_speed;
/*
Sets the state of the player.
*/
_configState2.default.setPlayerState();
}
/**
* Pauses the active song. If it's live, it disconnects the stream.
*
* Public Accessor: Amplitude.pause()
*
* @access public
*/
function pause() {
_visualizations2.default.stop();
/*
Pause the active song.
*/
_config2.default.audio.pause();
/*
Flag that pause button was clicked.
*/
_config2.default.paused = true;
/*
If the song is live, we disconnect the stream so we aren't
saving it to memory.
*/
if (_config2.default.active_metadata.live) {
disconnectStream();
}
/*
Sets the state of the player.
*/
_configState2.default.setPlayerState();
}
/**
* Stops the active song by setting the current song time to 0.
* When the user resumes, it will be from the beginning.
* If it's a live stream it disconnects.
*
* Public Accessor: Amplitude.stop()
*
* @access public
*/
function stop() {
_visualizations2.default.stop();
/*
Set the current time of the song to 0 which will reset the song.
*/
if (_config2.default.audio.currentTime != 0) {
_config2.default.audio.currentTime = 0;
}
/*
Run pause so the song will stop
*/
_config2.default.audio.pause();
/*
If the song is live, disconnect the stream.
*/
if (_config2.default.active_metadata.live) {
disconnectStream();
}
/*
Sets the state of the player.
*/
_configState2.default.setPlayerState();
/*
Run the stop callback
*/
_callbacks2.default.run("stop");
}
/**
* Sets the song volume.
*
* Public Accessor: Amplitude.setVolume( volumeLevel )
*
* @access public
* @param {number} volumeLevel - A number between 1 and 100 as a percentage of
* min to max for a volume level.
*/
function setVolume(volumeLevel) {
/*
If the volume is set to mute somewhere else, we sync the display.
*/
if (volumeLevel == 0) {
_config2.default.audio.muted = true;
} else {
_config2.default.audio.muted = false;
}
/*
Sets the volume in the config so we can reference it later on.
*/
_config2.default.volume = volumeLevel;
/*
Set the volume of the active song.
*/
_config2.default.audio.volume = volumeLevel / 100;
}
/**
* Sets the song percentage. If it's a live song, we ignore this because
* we can't skip ahead. This is an issue if you have a playlist with
* a live source.
*
* Public Accessor: Amplitude.setSongLocation( songPercentage )
*
* @access public
* @param {number} songPercentage - A number between 1 and 100 as a percentage of song completion.
*/
function setSongLocation(songPercentage) {
/*
As long as the song is not live, we can set the current time of the
song to the percentage the user passed in.
*/
if (!_config2.default.active_metadata.live) {
_config2.default.audio.currentTime = _config2.default.audio.duration * (songPercentage / 100);
}
}
/**
* Skips to a location in a song
*
* Public Accessor: Amplitude.skipToLocation( seconds )
*
* @access public
* @param {number} seconds - An integer containing the seconds to skip to
*/
function skipToLocation(seconds) {
/*
When the active song can be played through, we can check to
see if the seconds will work. We only bind the event handler
once and remove it once it's fired.
*/
_config2.default.audio.addEventListener("canplaythrough", function () {
/*
If the active song duration is greater than or equal to the
amount of seconds the user wants to skip to and the seconds
is greater than 0, we skip to the seconds defined.
*/
if (_config2.default.audio.duration >= seconds && seconds > 0) {
_config2.default.audio.currentTime = seconds;
} else {
_debug2.default.writeMessage("Amplitude can't skip to a location greater than the duration of the audio or less than 0");
}
}, { once: true });
}
/**
* Disconnects the live stream
*
* Public Accessor: Amplitude.disconnectStream()
*
* @access public
*/
function disconnectStream() {
_config2.default.audio.src = "";
_config2.default.audio.load();
}
/**
* Reconnects the live stream
*
* Public Accessor: Amplitude.reconnectStream()
*
* @access public\
*/
function reconnectStream() {
_config2.default.audio.src = _config2.default.active_metadata.url;
_config2.default.audio.load();
}
/**
* Sets the playback speed for the song.
*
* @param {number} playbackSpeed The speed we want the song to play back at.
*/
function setPlaybackSpeed(playbackSpeed) {
/*
Set the config playback speed.
*/
_config2.default.playback_speed = playbackSpeed;
/*
Set the active song playback rate.
*/
_config2.default.audio.playbackRate = _config2.default.playback_speed;
}
/*
Return publically facing functions
*/
return {
play: play,
pause: pause,
stop: stop,
setVolume: setVolume,
setSongLocation: setSongLocation,
skipToLocation: skipToLocation,
disconnectStream: disconnectStream,
reconnectStream: reconnectStream,
setPlaybackSpeed: setPlaybackSpeed
};
}();
/**
* Import the Config State module.
* @module utilities/configState
*/
/**
* Imports AmplitudeJS Debug Utility
* @module utilities/debug
*/
/**
* Imports the Meta Data Visual Elements module.
* @module visual/metaDataElements
*/
/**
* Imports the Audio Navigation module.
* @module utilities/audioNavigation
*/
/**
* Imports the config module
* @module config
*/
exports.default = Core;
module.exports = exports["default"];
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _config = __webpack_require__(0);
var _config2 = _interopRequireDefault(_config);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Defines the visual representation of AmplitudeJS play pause elements.
* @module visual/PlayPauseElements
*/
var PlayPauseElements = function () {
/**
* Syncs all play pause elements.
*
* @access public
*/
function sync() {
syncGlobal();
syncPlaylist();
syncSong();
syncSongInPlaylist();
}
/**
* Syncs the global play pause buttons to the state of the active song.
*
* @access public
*/
function syncGlobal() {
/*
Get the active song state.
*/
var state = _config2.default.audio.paused ? "paused" : "playing";
/*
Get all play pause buttons.
*/
var playPauseElements = document.querySelectorAll(".amplitude-play-pause");
/*
Iterate over all of the play pause elements syncing the
display visually.
*/
for (var i = 0; i < playPauseElements.length; i++) {
/*
Grab the playlist and song attributes from the element.
*/
var playlist = playPauseElements[i].getAttribute("data-amplitude-playlist");
var song = playPauseElements[i].getAttribute("data-amplitude-song-index");
/*
This method is responsible for only the global elements,
so we make sure there are no playlist or songs defined on
the element.
*/
if (playlist == null && song == null) {
/*
Determines what classes we should add and remove
from the elements.
*/
switch (state) {
case "playing":
setElementPlay(playPauseElements[i]);
break;
case "paused":
setElementPause(playPauseElements[i]);
break;
}
}
}
}
/**
* Syncs the main playlist play pause buttons to the state of the active song.
*
* @access public
*/
function syncPlaylist() {
var state = _config2.default.audio.paused ? "paused" : "playing";
/*
Get all of the main playlist play pause elements
*/
var playlistPlayPauseElements = document.querySelectorAll('.amplitude-play-pause[data-amplitude-playlist="' + _config2.default.active_playlist + '"]');
/*
Iterate over the play pause elements, syncing the state accordingly.
*/
for (var i = 0; i < playlistPlayPauseElements.length; i++) {
/*
Grab the song attributes from the element.
*/
var song = playlistPlayPauseElements[i].getAttribute("data-amplitude-song-index");
/*
We want only the play pause elements for the main on a
playlist nothing else. We have another method for the
song in playlist play pause method.
*/
if (song == null) {
/*
Determines what classes we should add and remove
from the elements.
*/
switch (state) {
case "playing":
setElementPlay(playlistPlayPauseElements[i]);
break;
case "paused":
setElementPause(playlistPlayPauseElements[i]);
break;
}
}
}
}
/**
* Syncs the song play pause buttons to the state of the active song.
*
* @access public
*/
function syncSong() {
var state = _config2.default.audio.paused ? "paused" : "playing";
/*
Get all of the individual song play pause buttons. These have an
amplitude-song-index that matches the active index attribute.
*/
var songPlayPauseElements = document.querySelectorAll('.amplitude-play-pause[data-amplitude-song-index="' + _config2.default.active_index + '"]');
/*
Iterate over all of the song play pause elements
*/
for (var i = 0; i < songPlayPauseElements.length; i++) {
/*
Grab the playlist attributes from the element.
*/
var playlist = songPlayPauseElements[i].getAttribute("data-amplitude-playlist");
/*
We want only the song play pause buttons, not ones scoped in a playlist.
*/
if (playlist == null) {
/*
Determines what classes we should add and remove
from the elements.
*/
switch (state) {
case "playing":
setElementPlay(songPlayPauseElements[i]);
break;
case "paused":
setElementPause(songPlayPauseElements[i]);
break;
}
}
}
}
/**
* Syncs the song in playlist play pause buttons to the state of
* the active song.
*
* @access public
*/
function syncSongInPlaylist() {
var state = _config2.default.audio.paused ? "paused" : "playing";
var activePlaylistIndex = _config2.default.active_playlist != "" && _config2.default.active_playlist != null ? _config2.default.playlists[_config2.default.active_playlist].active_index : null;
/*
Get all of the individual song play pause buttons. These have an
amplitude-song-index attribute. Some have amplitude-playlist which
means they are individual songs within a playlist.
*/
var songInPlaylistPlayPauseElements = document.querySelectorAll('.amplitude-play-pause[data-amplitude-song-index="' + activePlaylistIndex + '"][data-amplitude-playlist="' + _config2.default.active_playlist + '"]');
/*
Iterate over all of the individual play pause elements for songs inspect
a playlist.
*/
for (var i = 0; i < songInPlaylistPlayPauseElements.length; i++) {
/*
Determines what classes we should add and remove
from the elements.
*/
switch (state) {
case "playing":
setElementPlay(songInPlaylistPlayPauseElements[i]);
break;
case "paused":
setElementPause(songInPlaylistPlayPauseElements[i]);
break;
}
}
}
/**
* Sets all of the play pause buttons to paused.
*
* @access public
*/
function syncToPause() {
/*
Gets all of the play pause elements
*/
var playPauseElements = document.querySelectorAll(".amplitude-play-pause");
/*
Sets all of the elements to pause
*/
for (var i = 0; i < playPauseElements.length; i++) {
setElementPause(playPauseElements[i]);
}
}
/**
* Sets an element to be playing by removing the 'amplitude-paused' class
* and adding the 'amplitude-playing' class
*
* @access public
* @param {element} element - The element getting the playing class added.
*/
function setElementPlay(element) {
element.classList.add("amplitude-playing");
element.classList.remove("amplitude-paused");
}
/**
* Sets an element to be paused by adding the 'amplitude-paused' class
* and removing the 'amplitude-playing' class
*
* @access public
* @param {element} element - The element getting the paused class added.
*/
function setElementPause(element) {
element.classList.remove("amplitude-playing");
element.classList.add("amplitude-paused");
}
/**
* Returns the public facing methods
*/
return {
sync: sync,
syncGlobal: syncGlobal,
syncPlaylist: syncPlaylist,
syncSong: syncSong,
syncSongInPlaylist: syncSongInPlaylist,
syncToPause: syncToPause
};
}(); /**
* Imports the config module
* @module config
*/
exports.default = PlayPauseElements;
module.exports = exports["default"];
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _config = __webpack_require__(0);
var _config2 = _interopRequireDefault(_config);
var _core = __webpack_require__(1);
var _core2 = _interopRequireDefault(_core);
var _callbacks = __webpack_require__(9);
var _callbacks2 = _interopRequireDefault(_callbacks);
var _checks = __webpack_require__(5);
var _checks2 = _interopRequireDefault(_checks);
var _playPauseElements = __webpack_require__(2);
var _playPauseElements2 = _interopRequireDefault(_playPauseElements);
var _songSliderElements = __webpack_require__(14);
var _songSliderElements2 = _interopRequireDefault(_songSliderElements);
var _songPlayedProgressElements = __webpack_require__(20);
var _songPlayedProgressElements2 = _interopRequireDefault(_songPlayedProgressElements);
var _timeElements = __webpack_require__(15);
var _timeElements2 = _interopRequireDefault(_timeElements);
var _metaDataElements = __webpack_require__(7);
var _metaDataElements2 = _interopRequireDefault(_metaDataElements);
var _containerElements = __webpack_require__(49);
var _containerElements2 = _interopRequireDefault(_containerElements);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* AmplitudeJS Audio Navigation Utility.
*
* @module utilities/AudioNavigation
*/
/**
* Meta Data Elements Module
*
* @module visual/MetaDataElements
*/
/**
* Imports the Song Played Progress Elements Module
*
* @module visual/SongPlayedProgressElements
*/
/**
* Imports the Play Pause Elements Module
*
* @module visual/PlayPauseElements
*/
/**
* Imports the Callbacks Module
*
* @module utilities/Callbacks
*/
/**
* Imports the config module
* @module config
*/
var AudioNavigation = function () {
/**
* Sets the next song
*
* @access public
* @param {boolean} [songEnded=false] If the song ended, this is set to true
* so we take into effect the repeat setting.
*/
function setNext() {
var songEnded = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
/*
Initializes the next index variable. This will be the
index of the song that is next.
*/
var nextIndex = null;
var nextSong = {};
/*
Ensure we don't loop in the playlist if config.repeat is not true
*/
var endOfList = false;
/*
Determines if we are repeating the song or not. If we are repeating,
the next song will be the same song index.
*/
if (_config2.default.repeat_song) {
/*
If the playlist is shuffled, get the now playing index.
*/
if (_config2.default.shuffle_on) {
nextIndex = _config2.default.shuffle_list[_config2.default.active_index].index;
nextSong = _config2.default.shuffle_list[nextIndex];
} else {
nextIndex = _config2.default.active_index;
nextSong = _config2.default.songs[nextIndex];
}
} else {
/*
If the shuffle is on, we use the shuffled list of
songs to determine our next song.
*/
if (_config2.default.shuffle_on) {
/*
If the active shuffle index + 1 is less than the length, then
we use the next shuffle otherwise we go to the beginning
of the shuffle list.
*/
if (parseInt(_config2.default.active_index) + 1 < _config2.default.shuffle_list.length) {
/*
Set the next index to be the index of the song in the shuffle list.
*/
nextIndex = parseInt(_config2.default.active_index) + 1;
} else {
nextIndex = 0;
endOfList = true;
}
nextSong = _config2.default.shuffle_list[nextIndex];
} else {
/*
If the active index + 1 is less than the length of the songs, then
we use the next song otherwise we go to the beginning of the
song list.
*/
if (parseInt(_config2.default.active_index) + 1 < _config2.default.songs.length) {
nextIndex = parseInt(_config2.default.active_index) + 1;
} else {
nextIndex = 0;
endOfList = true;
}
/*
Sets the next index.
*/
nextSong = _config2.default.songs[nextIndex];
}
}
/*
Change the song after the next button has been pressed.
*/
changeSong(nextSong, nextIndex);
/*
If it's the end of the list and repeat is not on, do nothing.
*/
if (endOfList && !_config2.default.repeat) {} else {
/*
If the song has ended and repeat is on, play the song.
*/
if (!(songEnded && !_config2.default.repeat && endOfList)) {
_core2.default.play();
}
}
/*
Sync the play pause elements and run the
after next callback.
*/
_playPauseElements2.default.sync();
_callbacks2.default.run("next");
/*
If we repeated the song, run the repeat song callback.
*/
if (_config2.default.repeat_song) {
_callbacks2.default.run("song_repeated");
}
}
/**
* Sets the next song in a playlist
*
* @param {string} playlist - The playlist being shuffled
* @param {boolean} [songEnded=false] - If the song ended, this is set to true
* so we take into effect the repeat setting.
*/
function setNextPlaylist(playlist) {
var songEnded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
/*
Initializes the next index
*/
var nextIndex = null;
var nextSong = {};
/*
Ensure we don't loop in the playlist if config.repeat is not true
*/
var endOfList = false;
/*
If we are repeating the song, then we just start the song over.
*/
if (_config2.default.repeat_song) {
/*
If the playlist is shuffled, get the now playing index.
*/
if (_config2.default.playlists[playlist].shuffle) {
nextIndex = _config2.default.playlists[playlist].active_index;
nextSong = _config2.default.playlists[playlist].shuffle_list[nextIndex];
} else {
nextIndex = _config2.default.playlists[playlist].active_index;
nextSong = _config2.default.playlists[playlist].songs[nextIndex];
}
} else {
/*
If the playlist is shuffled we get the next index of the playlist.
*/
if (_config2.default.playlists[playlist].shuffle) {
/*
If the active shuffle index + 1 is less than the length of the shuffle list,
then we use the next shuffle otherwise we go to the beginning of the shuffle list.
*/
if (parseInt(_config2.default.playlists[playlist].active_index) + 1 < _config2.default.playlists[playlist].shuffle_list.length) {
/*
Set the next index to be the index of the song in the shuffle list.
*/
nextIndex = _config2.default.playlists[playlist].active_index + 1;
} else {
nextIndex = 0;
endOfList = true;
}
nextSong = _config2.default.playlists[playlist].shuffle_list[nextIndex];
} else {
/*
If the active index +1 is less than the length of the songs in the playlist,
then we use the next song otherwise we go to the beginning of the playlist.
*/
if (parseInt(_config2.default.playlists[playlist].active_index) + 1 < _config2.default.playlists[playlist].songs.length) {
nextIndex = parseInt(_config2.default.playlists[playlist].active_index) + 1;
} else {
nextIndex = 0;
endOfList = true;
}
/*
Sets the next song.
*/
nextSong = _config2.default.playlists[playlist].songs[nextIndex];
}
}
/*
Sets the active playlist to the playlist we are on.
*/
setActivePlaylist(playlist);
/*
Change the song within the playlist.
*/
changeSongPlaylist(playlist, nextSong, nextIndex);
/*
If it's the end of the playlist and we aren't repeating, do nothing.
*/
if (endOfList && !_config2.default.repeat) {} else {
if (!(songEnded && !_config2.default.repeat && endOfList)) {
_core2.default.play();
}
}
/*
Sync the play pause buttons.
*/
_playPauseElements2.default.sync();
_callbacks2.default.run("next");
/*
Repeat the song.
*/
if (_config2.default.repeat_song) {
_callbacks2.default.run("song_repeated");
}
}
/**
* Sets the previous song on the global songs array.
*
* @access private
*/
function setPrevious() {
/*
Initializes the previous index
*/
var previousIndex = null;
var previousSong = {};
/*
If we are repeating the song, then we just start the song over.
*/
if (_config2.default.repeat_song) {
/*
If the config is shuffled, get the now playing index.
*/
if (_config2.default.shuffle_on) {
previousIndex = _config2.default.active_index;
previousSong = _config2.default.shuffle_list[previousIndex];
} else {
previousIndex = _config2.default.active_index;
previousSong = _config2.default.songs[previousIndex];
}
} else {
/*
Get the previous index. If the previous index will be less than 0, get the
last song of the array and continue.
*/
if (parseInt(_config2.default.active_index) - 1 >= 0) {
previousIndex = parseInt(_config2.default.active_index - 1);
} else {
previousIndex = parseInt(_config2.default.songs.length - 1);
}
/*
If the config is shuffled, we grab the song from the shuffle list
*/
if (_config2.default.shuffle_on) {
/*
Grab song from the shuffle list
*/
previousSong = _config2.default.shuffle_list[previousIndex];
} else {
/*
Grab song from the songs array
*/
previousSong = _config2.default.songs[previousIndex];
}
}
/*
Change the song after the next button has been pressed.
*/
changeSong(previousSong, previousIndex);
/*
Play the newest song.
*/
_core2.default.play();
/*
Sync the play pause elements and run the
after next callback.
*/
_playPauseElements2.default.sync();
_callbacks2.default.run("prev");
/*
If we repeated the song, run the repeat song callback.
*/
if (_config2.default.repeat_song) {
_callbacks2.default.run("song_repeated");
}
}
/**
* Sets the previous playlist song.
*
* @access private
*
* @prop {string} playlist - The playlist we are navigating in.
*/
function setPreviousPlaylist(playlist) {
/*
Initializes the previous index
*/
var previousIndex = null;
var previousSong = {};
/*
If we are repeating the song, then we just start the song over.
*/
if (_config2.default.repeat_song) {
/*
If the playlist is shuffled, get the now playing index.
*/
if (_config2.default.playlists[playlist].shuffle) {
previousIndex = _config2.default.playlists[playlist].active_index;
previousSong = _config2.default.playlists[playlist].shuffle_list[previousIndex];
} else {
previousIndex = _config2.default.playlists[playlist].active_index;
previousSong = _config2.default.playlists[playlist].songs[previousIndex];
}
} else {
/*
Get the previous index. If the previous index will be less than 0, get the
last song of the array and continue.
*/
if (parseInt(_config2.default.playlists[playlist].active_index) - 1 >= 0) {
previousIndex = parseInt(_config2.default.playlists[playlist].active_index - 1);
} else {
previousIndex = parseInt(_config2.default.playlists[playlist].songs.length - 1);
}
/*
If the playlist is shuffled, we grab the song from the shuffle list
*/
if (_config2.default.playlists[playlist].shuffle) {
/*
Grab song from the shuffle list
*/
previousSong = _config2.default.playlists[playlist].shuffle_list[previousIndex];
} else {
/*
Grab song from the songs array
*/
previousSong = _config2.default.playlists[playlist].songs[previousIndex];
}
}
/*
Sets the active playlist to the playlist we are on.
*/
setActivePlaylist(playlist);
/*
Change the song within the playlist.
*/
changeSongPlaylist(playlist, previousSong, previousIndex);
/*
Plays the song
*/
_core2.default.play();
/*
Sync the play pause buttons.
*/
_playPauseElements2.default.sync();
_callbacks2.default.run("prev");
/*
Repeat the song.
*/
if (_config2.default.repeat_song) {
_callbacks2.default.run("song_repeated");
}
}
/**
* Change song in the songs array.
*
* @access private
* @prop {object} song - The song we are changing to.
* @prop {number} index - The index we are changing to.
* @prop {boolean} direct - Determines if it was a direct click on the song.
* We then don't care if shuffle is on or not.
*/
function changeSong(song, index) {
var direct = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
/*
Prepare the song change.
*/
prepareSongChange(song);
/*
Change the song.
*/
_config2.default.audio.src = song.url;
_config2.default.active_metadata = song;
_config2.default.active_album = song.album;
_config2.default.active_index = parseInt(index);
/*
Set new information now that the song has changed.
*/
afterSongChange(direct);
}
/**
* Handles a song change in the playlist
*
* @access private
* @prop {string} playlist - The playlist we are changing the song on.
* @prop {object} song - The song we are changing to in the playlist.
* @prop {number} index - The inded of the song we are changing to in the playlist.
* @prop {boolean} direct - Determines if it was a direct click on the song. We
* then don't care if shuffle is on or not
*/
function changeSongPlaylist(playlist, song, index) {
var direct = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
/*
Prepare the song change.
*/
prepareSongChange(song);
/*
Change the song.
*/
_config2.default.audio.src = song.url;
_config2.default.active_metadata = song;
_config2.default.active_album = song.album;
_config2.default.active_index = null;
_config2.default.playlists[playlist].active_index = parseInt(index);
/*
Set new information now that the song has changed.
*/
afterSongChange(direct);
}
/**
* Prepares a song change
*
* @access private
* @prop {object} song - The song we change to.
*/
function prepareSongChange(song) {
/*
Stop the current song.
*/
_core2.default.stop();
/*
Sync all of the elements to a stopped song.
*/
_playPauseElements2.default.syncToPause();
_songSliderElements2.default.resetElements();
_songPlayedProgressElements2.default.resetElements();
_timeElements2.default.resetCurrentTimes();
/*
If an album changes, fire an album change.
*/
if (_checks2.default.newAlbum(song)) {
_callbacks2.default.run("album_change");
}
}
/**
* Updates data on the display after a song has changed.
*
* @prop {boolean} direct - Determines if it was a direct click on the song.
* We then don't care if shuffle is on or not.
*
* @access private
*/
function afterSongChange(direct) {
_metaDataElements2.default.displayMetaData();
_containerElements2.default.setActive(direct);
_timeElements2.default.resetDurationTimes();
/*
Run the song change callback.
*/
_callbacks2.default.run("song_change");
}
/**
* Sets the active playlist
*
* @access public
* @param {string} playlist - The string of the playlist being set to active.
*/
function setActivePlaylist(playlist) {
/*
If the active playlist is different than the playlist being set,
we run the `playlist_changed` callback.
*/
if (_config2.default.active_playlist != playlist) {
_callbacks2.default.run("playlist_changed");
/*
Set the active playlist to the playlist parameter. Only need to
set if it's different.
*/
_config2.default.active_playlist = playlist;
if (playlist != null) {
_config2.default.playlists[playlist].active_index = 0;
}
}
}
/*
Return the publically facing methods
*/
return {
setNext: setNext,
setNextPlaylist: setNextPlaylist,
setPrevious: setPrevious,
setPreviousPlaylist: setPreviousPlaylist,
changeSong: changeSong,
changeSongPlaylist: changeSongPlaylist,
setActivePlaylist: setActivePlaylist
};
}();
/**
* Container Elements Module
*
* @module visual/ContainerElements
*/
/**
* Imports the Time Elements Module
*
* @module visual/TimeElements
*/
/**
* Imports the Song Slider Elements Module
*
* @module visual/SongSliderElements
*/
/**
* Imports the Checks Module
*
* @module utilities/Checks
*/
/**
* Imports the Core Module
*
* @module core/Core
*/
exports.default = AudioNavigation;
module.exports = exports["default"];
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _config = __webpack_require__(0);
var _config2 = _interopRequireDefault(_config);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Handles the debugging of AmplitudeJS
* @module utilities/Debug
*/
var Debug = function () {
/**
* Writes out debug message to the console if enabled.
*
* Public Accessor: Debug.writeMessage( message )
*
* @access public
* @param {string} message - The string that gets printed to alert the user of a debugging error.
*/
function writeMessage(message) {
/*
If the user has flagged AmplitudeJS to debug, we print out a message
to the console.
*/
if (_config2.default.debug) {
console.log(message);
}
}
/*
Returns the public facing methods
*/
return {
writeMessage: writeMessage
};
}(); /**
* Imports the config module
* @module config
*/
exports.default = Debug;
module.exports = exports["default"];
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _config = __webpack_require__(0);
var _config2 = _interopRequireDefault(_config);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* AmplitudeJS Checks Module. Checks for new songs, albums, and playlists
*
* @module utilities/Checks
*/
var Checks = function () {
/**
* Checks to see if the new song to be played is different than the song
* that is currently playing. To be true, the user would have selected
* play on a new song with a new index. To be false, the user would have
* clicked play/pause on the song that was playing.
*
* Public Accessor: Checks.newSong( playlist, songIndex )
* @access public
* @param {string} playlist - The playlist we are checking the new song for. Could be null
* @param {number} songIndex - The index of the new song to be played.
* @returns {boolean} True if we are setting a new song, false if we are not setting a new song.
*/
function newSong(playlist, songIndex) {
/*
If the playlists don't match, then it's definitely a new song.
*/
if (_config2.default.active_playlist != playlist) {
return true;
} else {
/*
If we aren't in a playlist, we check the active index.
*/
if (_config2.default.active_playlist == null && playlist == null) {
/*
If the active indexes don't match, then it's a new song.
*/
if (_config2.default.active_index != songIndex) {
return true;
} else {
return false;
}
} else {
/*
If we are in a playlist, then we check to see if the
new song index matches the active index.
*/
if (_config2.default.active_playlist == playlist && _config2.default.playlists[playlist].active_index != songIndex) {
return true;
} else {
return false;
}
}
}
}
/**
* Checks to see if there is a new album
*
* Public Accessor: Checks.newAlbum( album )
*
* @access public
* @param {string} album - Checks to see if the new song will have a new album.
* @returns {boolean} True if there is a new album, false if there is not a new ablum.
*/
function newAlbum(album) {
if (_config2.default.active_album != album) {
return true;
} else {
return false;
}
}
/**
* Checks to see if there is a new playlist
*
* Public Accessor: Checks.newPlaylist( playlist )
*
* @access public
* @param {string} playlist - The playlist passed in to check against the active playlist.
* @returns {boolean} True if there is a new playlist, false if there is not a new playlist.
*/
function newPlaylist(playlist) {
if (_config2.default.active_playlist != playlist) {
return true;
} else {
return false;
}
}
/**
* Determines if the string passed in is a URL or not
*
* Public Accessor: AmplitudeHelpers.isURL( url )
*
* @access public
* @param {string} url - The string we are testing to see if it's a URL.
* @returns {boolean} True if the string is a url, false if it is not.
*/
function isURL(url) {
/*
Test the string against the URL pattern and return if it matches
*/
var pattern = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
return pattern.test(url);
}
/**
* Determines if what is passed in is an integer or not.
*
* Public Accessor: AmplitudeHelpers.isInt( int )
*
* @access public
* @param {string|number} int - The variable we are testing to see is an integer or not.
* @returns {boolean} If the variable is an integer or not.
*/
function isInt(int) {
return !isNaN(int) && parseInt(Number(int)) == int && !isNaN(parseInt(int, 10));
}
/**
* Returns public facing methods
*/
return {
newSong: newSong,
newAlbum: newAlbum,
newPlaylist: newPlaylist,
isURL: isURL,
isInt: isInt
};
}(); /**
* Imports the config module
* @module config
*/
exports.default = Checks;
module.exports = exports["default"];
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _config = __webpack_require__(0);
var _config2 = _interopRequireDefault(_config);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Handles the state of the config object.
*
* @module utilities/ConfigState
*/
var ConfigState = function () {
/**
* Resets the config to the default state. This is called on initialize
* to ensure the user's config is what matters.
*
* Public Accessor: AmplitudeHelpers.resetConfig()
*
* @access public
*/
function resetConfig() {
_config2.default.audio = new Audio();
_config2.default.active_metadata = {};