mirror of
https://github.com/memen45/SubMusic.git
synced 2026-02-18 00:57:39 +01:00
363 lines
10 KiB
MonkeyC
363 lines
10 KiB
MonkeyC
module SubMusic {
|
|
class Playable extends Storable {
|
|
|
|
hidden var d_storage = {
|
|
|
|
// handled by loadIds()
|
|
"ids" => [], // array of ids
|
|
"types" => [], // array of types
|
|
"idcs" => [],
|
|
"idx" => 0, // suggested start index
|
|
"shuffle" => false,
|
|
|
|
"podcast_mode" => false, // determines playback storage
|
|
};
|
|
|
|
function initialize(storage) {
|
|
System.println("Playable::initialize( storage = " + storage + " )");
|
|
|
|
Storable.initialize(storage);
|
|
}
|
|
|
|
function podcast_mode() {
|
|
return get("podcast_mode");
|
|
}
|
|
|
|
function songidx() {
|
|
return get("idx");
|
|
}
|
|
|
|
function ids() {
|
|
return get("ids");
|
|
}
|
|
|
|
function types() {
|
|
return get("types");
|
|
}
|
|
|
|
function idcs() {
|
|
return get("idcs");
|
|
}
|
|
|
|
function size() {
|
|
return ids().size();
|
|
}
|
|
|
|
function getSongId(idx) {
|
|
return ids()[idcs()[idx]];
|
|
}
|
|
|
|
function shuffle() {
|
|
return get("shuffle");
|
|
}
|
|
|
|
function getSongIds() {
|
|
return ids();
|
|
}
|
|
|
|
function getAudio(idx) {
|
|
// return null if out of bounds
|
|
if ((idx >= idcs().size())
|
|
|| (idx >= ids().size())
|
|
|| (idx >= types().size())) {
|
|
return null;
|
|
}
|
|
idx = idcs()[idx]; // rewrite to apply shuffle
|
|
var id = ids()[idx];
|
|
var type = types()[idx];
|
|
return new Audio(id, type);
|
|
}
|
|
}
|
|
|
|
class IPlayable extends Playable {
|
|
|
|
function initialize() {
|
|
System.println("IPlayable::initialize()");
|
|
|
|
var storage = PlayableStore.get();
|
|
if (storage == null) {
|
|
storage = {};
|
|
}
|
|
Playable.initialize(storage);
|
|
}
|
|
|
|
function save() {
|
|
return PlayableStore.save(self);
|
|
}
|
|
|
|
function incSongIdx() {
|
|
setIdx(songidx() + 1);
|
|
return save();
|
|
}
|
|
|
|
function decSongIdx() {
|
|
setIdx(songidx() - 1);
|
|
return save();
|
|
}
|
|
|
|
function setAudio(audio) {
|
|
for (var idx = 0; idx != ids().size(); ++idx) {
|
|
var id = ids()[idx];
|
|
var type = types()[idx];
|
|
if ((id == audio["id"])
|
|
&& (type == audio["type"])) {
|
|
setIdx(idx);
|
|
return save();
|
|
}
|
|
}
|
|
// not found
|
|
return false;
|
|
}
|
|
|
|
function setSongId(songid) {
|
|
// find id
|
|
for (var idx = 0; idx != ids().size(); ++idx) {
|
|
var id = ids()[idx];
|
|
if (id == songid) {
|
|
setIdx(idx);
|
|
return save();
|
|
}
|
|
}
|
|
// not found
|
|
return false;
|
|
}
|
|
|
|
function setIdx(value) {
|
|
return set("idx", value);
|
|
}
|
|
|
|
function setIds(value) {
|
|
return set("ids", value);
|
|
}
|
|
|
|
function setIdcs(value) {
|
|
return set("idcs", value);
|
|
}
|
|
|
|
function setTypes(value) {
|
|
return set("types", value);
|
|
}
|
|
|
|
function setPodcastMode(value) {
|
|
return set("podcast_mode", value);
|
|
}
|
|
|
|
function setShuffle(value) {
|
|
return set("shuffle", value);
|
|
}
|
|
|
|
function removeAudioByIdx(idx) {
|
|
System.println("IPlayable::removeAudioByIdx(idx: " + idx + " )");
|
|
System.println(ids());
|
|
System.println(types());
|
|
System.println(idcs());
|
|
|
|
ids().remove(ids()[idx]); // remove the id from ids
|
|
types().remove(types()[idx]); // remove the type from types
|
|
idcs().remove(idx); // remove the idx from idcs
|
|
|
|
System.println(ids().toString());
|
|
System.println(types().toString());
|
|
System.println(idcs());
|
|
System.println("IPlayable::removeAudioByIdx() - done");
|
|
}
|
|
|
|
function removeRemoved() {
|
|
|
|
if (ids().size() == 0) {
|
|
return true;
|
|
}
|
|
|
|
// check for ids that are no longer available
|
|
var index = 0;
|
|
var realidx = idcs()[songidx()];
|
|
var changed = false;
|
|
do {
|
|
var id = ids()[index];
|
|
var type = types()[index];
|
|
var audio = new Audio(id, type);
|
|
|
|
if (audio.refId() != null) {
|
|
index += 1;
|
|
continue;
|
|
}
|
|
changed = true;
|
|
|
|
// this idx is removed, so no increment of idx
|
|
ids().remove(ids()[index]);
|
|
types().remove(types()[index]);
|
|
|
|
|
|
// reset or decrease songidx if needed
|
|
if (index == realidx) {
|
|
setIdx(0);
|
|
} else if (realidx > index) {
|
|
realidx -= 1;
|
|
}
|
|
} while (index != ids().size());
|
|
|
|
// nothing changed? nothing to do
|
|
if (!changed) { return true; }
|
|
|
|
// now reset idcs
|
|
setIdcs(new[ids().size()]);
|
|
for (var idx = 0; idx != idcs().size(); ++idx) {
|
|
idcs()[idx] = idx;
|
|
}
|
|
// realidx == songidx when !shuffle
|
|
setIdx(realidx);
|
|
|
|
// if not shuffle, nothing to do
|
|
if (!shuffle()) {
|
|
return save();
|
|
}
|
|
// now fix shuffle if needed
|
|
set("shuffle", false);
|
|
return shuffleIdcs(true);
|
|
}
|
|
|
|
function shuffleIdcs(shuffle) {
|
|
// nothing to do if same or no songs on list
|
|
if (shuffle() == shuffle) {
|
|
return false;
|
|
}
|
|
|
|
setShuffle(shuffle);
|
|
|
|
// empty list cannot be shuffled
|
|
if (size() == 0) {
|
|
return false;
|
|
}
|
|
|
|
System.println("Playable::shuffleIdcs() Before: " + idcs());
|
|
System.println("Playable::shuffleIdcs() songids: " + ids().toString());
|
|
System.println("Playable::shuffleIdcs() songids: " + types().toString());
|
|
System.println("Playable::shuffleIdcs() songidx: " + songidx());
|
|
|
|
// if not shuffle, generate 0:n array for idcs
|
|
if (!shuffle) {
|
|
// store the current real index
|
|
setIdx(idcs()[songidx()]);
|
|
|
|
setIdcs(new[ids().size()]);
|
|
for (var idx = 0; idx != idcs().size(); ++idx) {
|
|
idcs()[idx] = idx;
|
|
}
|
|
System.println("Playable::shuffleIdcs() After unshuffle:" + idcs());
|
|
return save();
|
|
}
|
|
|
|
// shuffle idcs around current
|
|
var current = idcs()[songidx()];
|
|
|
|
// shuffle the idcs
|
|
var tmp = idcs()[0];
|
|
idcs()[0] = idcs()[songidx()];
|
|
idcs()[songidx()] = tmp;
|
|
|
|
for (var idx = 1; idx != idcs().size(); ++idx) {
|
|
tmp = idcs()[idx];
|
|
var other = (Math.rand() % (idcs().size() - idx)) + idx;
|
|
idcs()[idx] = idcs()[other];
|
|
idcs()[other] = tmp;
|
|
}
|
|
|
|
System.println("Playable::shuffleIdcs() After shuffle:" + idcs());
|
|
|
|
// slice last songs and prepend to account for songidx
|
|
var splitidx = songidx();
|
|
var end = idcs().slice(0, -splitidx);
|
|
setIdcs(idcs().slice(-splitidx, null));
|
|
idcs().addAll(end);
|
|
|
|
System.println("Playable::shuffleIdcs() After shuffle:" + idcs());
|
|
|
|
return save();
|
|
}
|
|
|
|
function loadIds(ids, audioid, type) {
|
|
System.println("IPlayable::loadIds( ids: " + ids + " audioid: " + audioid + " type: " + type);
|
|
|
|
var audioidx = 0;
|
|
|
|
// reset ids, idcs and idx
|
|
setIdx(0);
|
|
setIdcs([]);
|
|
|
|
setIds([]);
|
|
setTypes([]);
|
|
|
|
setShuffle(false);
|
|
|
|
// only add the audios that are available for playing
|
|
for (var idx = 0; idx != ids.size(); ++idx) {
|
|
var audio = new Audio(ids[idx], type);
|
|
|
|
// check for audioid match
|
|
if ((audio.id() == audioid)
|
|
|| ((audioid instanceof Lang.String)
|
|
&& (audioid.equals(audio.id())))) {
|
|
// set index to this audio if matched
|
|
setIdx(audioidx);
|
|
|
|
// reset progress if this audio was chosen and completed
|
|
var time = audio.time().toNumber();
|
|
if (time == 0) { time = 1; }
|
|
var progress = 100 * audio.playback() / time;
|
|
var complete = (progress > 98);
|
|
if (complete) { audio.setPlayback(0); }
|
|
}
|
|
|
|
// not added if no refId
|
|
if (audio.refId() == null) {
|
|
continue;
|
|
}
|
|
|
|
// add to ids and indices
|
|
ids().add(audio.id());
|
|
types().add(type);
|
|
idcs().add(audioidx);
|
|
|
|
audioidx++;
|
|
}
|
|
return save();
|
|
}
|
|
|
|
function loadPodcast(id, episodeid) {
|
|
System.println("IPlayable::loadPodcast( id: " + id + " episodeid: " + episodeid + ")");
|
|
|
|
// return empty array if no id available
|
|
if (id == null) {
|
|
return false;
|
|
}
|
|
|
|
var ipodcast = new IPodcast(id);
|
|
setPodcastMode(ipodcast.podcast());
|
|
var ids = ipodcast.episodes();
|
|
|
|
return loadIds(ids, episodeid, Audio.PODCAST_EPISODE);
|
|
}
|
|
|
|
function loadPlaylist(id, songid) {
|
|
System.println("IPlayable::loadPlaylist( id: " + id + " songid: " + songid + ")");
|
|
|
|
// return empty array if no id available
|
|
if (id == null) {
|
|
return false;
|
|
}
|
|
|
|
var iplaylist = new IPlaylist(id);
|
|
setPodcastMode(iplaylist.podcast());
|
|
var ids = iplaylist.songs();
|
|
|
|
return loadIds(ids, songid, Audio.SONG);
|
|
}
|
|
|
|
function loadSongIds(ids) {
|
|
|
|
setPodcastMode(false);
|
|
|
|
return loadIds(ids, null, Audio.SONG);
|
|
}
|
|
}
|
|
} |