mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Dynamic Audio UI: more controls (#1127)
* Added control to audio ui to select bgm/ambient and lock selection to overide dynamic audio update. Load both assets and char specific audio assets * correct ambient label and default value when no assets available. * add padding in audio select * Correct audio change of background ambient when locked. Updated CSS of audio ui for mobile friendly. * add space between mixer * Add checkbox to enable dynamic bgm/ambient switch * correct background ambient fadout * continue debuging ambient audio update * finish debuging * Fix BGM console error on first run. Reformat plugin code * Changed audio bgm lock into loop on/off. Added random pick button for bgm. Moved ambient lock button to right. * Add mouse wheel event handler on volume controls * Change bgm select to only contain current chat character bgm (solo/group). When enable expression bgm is off, any of the char+asset bgm can play next if not looping. * Corrected bgm looping at start. Force random to play another song if there is any. * Format code --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
Ideas:
|
Ideas:
|
||||||
|
- Clean design of new ui
|
||||||
|
- change select text versus options for playing: audio
|
||||||
- cross fading between bgm / start a different time
|
- cross fading between bgm / start a different time
|
||||||
|
- fading should appear before end when switching randomly
|
||||||
- Background based ambient sounds
|
- Background based ambient sounds
|
||||||
- import option on background UI ?
|
- import option on background UI ?
|
||||||
- Allow background music edition using background menu
|
- Allow background music edition using background menu
|
||||||
@@ -59,6 +62,8 @@ const DEFAULT_EXPRESSIONS = [
|
|||||||
];
|
];
|
||||||
const SPRITE_DOM_ID = "#expression-image";
|
const SPRITE_DOM_ID = "#expression-image";
|
||||||
|
|
||||||
|
let current_chat_id = null
|
||||||
|
|
||||||
let fallback_BGMS = null; // Initialized only once with module workers
|
let fallback_BGMS = null; // Initialized only once with module workers
|
||||||
let ambients = null; // Initialized only once with module workers
|
let ambients = null; // Initialized only once with module workers
|
||||||
let characterMusics = {}; // Updated with module workers
|
let characterMusics = {}; // Updated with module workers
|
||||||
@@ -69,16 +74,27 @@ let currentBackground = null;
|
|||||||
|
|
||||||
let cooldownBGM = 0;
|
let cooldownBGM = 0;
|
||||||
|
|
||||||
|
let bgmEnded = true;
|
||||||
|
|
||||||
//#############################//
|
//#############################//
|
||||||
// Extension UI and Settings //
|
// Extension UI and Settings //
|
||||||
//#############################//
|
//#############################//
|
||||||
|
|
||||||
const defaultSettings = {
|
const defaultSettings = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
dynamic_bgm_enabled: false,
|
||||||
|
//dynamic_ambient_enabled: false,
|
||||||
|
|
||||||
|
bgm_locked: true,
|
||||||
bgm_muted: true,
|
bgm_muted: true,
|
||||||
ambient_muted: true,
|
|
||||||
bgm_volume: 50,
|
bgm_volume: 50,
|
||||||
|
bgm_selected: null,
|
||||||
|
|
||||||
|
ambient_locked: true,
|
||||||
|
ambient_muted: true,
|
||||||
ambient_volume: 50,
|
ambient_volume: 50,
|
||||||
|
ambient_selected: null,
|
||||||
|
|
||||||
bgm_cooldown: 30
|
bgm_cooldown: 30
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +106,8 @@ function loadSettings() {
|
|||||||
Object.assign(extension_settings.audio, defaultSettings)
|
Object.assign(extension_settings.audio, defaultSettings)
|
||||||
}
|
}
|
||||||
$("#audio_enabled").prop('checked', extension_settings.audio.enabled);
|
$("#audio_enabled").prop('checked', extension_settings.audio.enabled);
|
||||||
|
$("#audio_dynamic_bgm_enabled").prop('checked', extension_settings.audio.dynamic_bgm_enabled);
|
||||||
|
//$("#audio_dynamic_ambient_enabled").prop('checked', extension_settings.audio.dynamic_ambient_enabled);
|
||||||
|
|
||||||
$("#audio_bgm_volume").text(extension_settings.audio.bgm_volume);
|
$("#audio_bgm_volume").text(extension_settings.audio.bgm_volume);
|
||||||
$("#audio_ambient_volume").text(extension_settings.audio.ambient_volume);
|
$("#audio_ambient_volume").text(extension_settings.audio.ambient_volume);
|
||||||
@@ -110,6 +128,41 @@ function loadSettings() {
|
|||||||
$("#audio_bgm").prop("muted", false);
|
$("#audio_bgm").prop("muted", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (extension_settings.audio.bgm_locked) {
|
||||||
|
//$("#audio_bgm_lock_icon").removeClass("fa-lock-open");
|
||||||
|
//$("#audio_bgm_lock_icon").addClass("fa-lock");
|
||||||
|
$("#audio_bgm").attr("loop", true);
|
||||||
|
$("#audio_bgm_lock").addClass("redOverlayGlow");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//$("#audio_bgm_lock_icon").removeClass("fa-lock");
|
||||||
|
//$("#audio_bgm_lock_icon").addClass("fa-lock-open");
|
||||||
|
$("#audio_bgm").attr("loop", false);
|
||||||
|
$("#audio_bgm_lock").removeClass("redOverlayGlow");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (extension_settings.audio.bgm_selected !== null) {
|
||||||
|
$("#audio_bgm_select").append(new Option(extension_settings.audio.bgm_selected, extension_settings.audio.bgm_selected));
|
||||||
|
$("#audio_bgm_select").val(extension_settings.audio.bgm_selected);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (extension_settings.audio.ambient_locked) {
|
||||||
|
$("#audio_ambient_lock_icon").removeClass("fa-lock-open");
|
||||||
|
$("#audio_ambient_lock_icon").addClass("fa-lock");
|
||||||
|
$("#audio_ambient_lock").addClass("redOverlayGlow");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#audio_ambient_lock_icon").removeClass("fa-lock");
|
||||||
|
$("#audio_ambient_lock_icon").addClass("fa-lock-open");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (extension_settings.audio.ambient_selected !== null) {
|
||||||
|
$("#audio_ambient_select").append(new Option(extension_settings.audio.ambient_selected, extension_settings.audio.ambient_selected));
|
||||||
|
$("#audio_ambient_select").val(extension_settings.audio.ambient_selected);
|
||||||
|
}*/
|
||||||
|
|
||||||
if (extension_settings.audio.ambient_muted) {
|
if (extension_settings.audio.ambient_muted) {
|
||||||
$("#audio_ambient_mute_icon").removeClass("fa-volume-high");
|
$("#audio_ambient_mute_icon").removeClass("fa-volume-high");
|
||||||
$("#audio_ambient_mute_icon").addClass("fa-volume-mute");
|
$("#audio_ambient_mute_icon").addClass("fa-volume-mute");
|
||||||
@@ -125,7 +178,7 @@ function loadSettings() {
|
|||||||
|
|
||||||
$("#audio_bgm_cooldown").val(extension_settings.audio.bgm_cooldown);
|
$("#audio_bgm_cooldown").val(extension_settings.audio.bgm_cooldown);
|
||||||
|
|
||||||
$("#audio_debug_div").hide(); // DBG
|
$("#audio_debug_div").hide(); // DBG: comment to see debug mode
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onEnabledClick() {
|
async function onEnabledClick() {
|
||||||
@@ -142,6 +195,51 @@ async function onEnabledClick() {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onDynamicBGMEnabledClick() {
|
||||||
|
extension_settings.audio.dynamic_bgm_enabled = $('#audio_dynamic_bgm_enabled').is(':checked');
|
||||||
|
currentCharacterBGM = null;
|
||||||
|
currentExpressionBGM = null;
|
||||||
|
cooldownBGM = 0;
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
async function onDynamicAmbientEnabledClick() {
|
||||||
|
extension_settings.audio.dynamic_ambient_enabled = $('#audio_dynamic_ambient_enabled').is(':checked');
|
||||||
|
currentBackground = null;
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
async function onBGMLockClick() {
|
||||||
|
extension_settings.audio.bgm_locked = !extension_settings.audio.bgm_locked;
|
||||||
|
if (extension_settings.audio.bgm_locked) {
|
||||||
|
extension_settings.audio.bgm_selected = $("#audio_bgm_select").val();
|
||||||
|
$("#audio_bgm").attr("loop", true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$("#audio_bgm").attr("loop", false);
|
||||||
|
}
|
||||||
|
//$("#audio_bgm_lock_icon").toggleClass("fa-lock");
|
||||||
|
//$("#audio_bgm_lock_icon").toggleClass("fa-lock-open");
|
||||||
|
$("#audio_bgm_lock").toggleClass("redOverlayGlow");
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onBGMRandomClick() {
|
||||||
|
var select = document.getElementById('audio_bgm_select');
|
||||||
|
var items = select.getElementsByTagName('option');
|
||||||
|
|
||||||
|
if (items.length < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var index;
|
||||||
|
do {
|
||||||
|
index = Math.floor(Math.random() * items.length);
|
||||||
|
} while (index == select.selectedIndex);
|
||||||
|
|
||||||
|
select.selectedIndex = index;
|
||||||
|
onBGMSelectChange();
|
||||||
|
}
|
||||||
|
|
||||||
async function onBGMMuteClick() {
|
async function onBGMMuteClick() {
|
||||||
extension_settings.audio.bgm_muted = !extension_settings.audio.bgm_muted;
|
extension_settings.audio.bgm_muted = !extension_settings.audio.bgm_muted;
|
||||||
$("#audio_bgm_mute_icon").toggleClass("fa-volume-high");
|
$("#audio_bgm_mute_icon").toggleClass("fa-volume-high");
|
||||||
@@ -151,6 +249,20 @@ async function onBGMMuteClick() {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onAmbientLockClick() {
|
||||||
|
extension_settings.audio.ambient_locked = !extension_settings.audio.ambient_locked;
|
||||||
|
if (extension_settings.audio.ambient_locked)
|
||||||
|
extension_settings.audio.ambient_selected = $("#audio_ambient_select").val();
|
||||||
|
else {
|
||||||
|
extension_settings.audio.ambient_selected = null;
|
||||||
|
currentBackground = null;
|
||||||
|
}
|
||||||
|
$("#audio_ambient_lock_icon").toggleClass("fa-lock");
|
||||||
|
$("#audio_ambient_lock_icon").toggleClass("fa-lock-open");
|
||||||
|
$("#audio_ambient_lock").toggleClass("redOverlayGlow");
|
||||||
|
saveSettingsDebounced();
|
||||||
|
}
|
||||||
|
|
||||||
async function onAmbientMuteClick() {
|
async function onAmbientMuteClick() {
|
||||||
extension_settings.audio.ambient_muted = !extension_settings.audio.ambient_muted;
|
extension_settings.audio.ambient_muted = !extension_settings.audio.ambient_muted;
|
||||||
$("#audio_ambient_mute_icon").toggleClass("fa-volume-high");
|
$("#audio_ambient_mute_icon").toggleClass("fa-volume-high");
|
||||||
@@ -176,6 +288,20 @@ async function onAmbientVolumeChange() {
|
|||||||
//console.debug(DEBUG_PREFIX,"UPDATED Ambient MAX TO",extension_settings.audio.ambient_volume);
|
//console.debug(DEBUG_PREFIX,"UPDATED Ambient MAX TO",extension_settings.audio.ambient_volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function onBGMSelectChange() {
|
||||||
|
extension_settings.audio.bgm_selected = $("#audio_bgm_select").val();
|
||||||
|
updateBGM(true);
|
||||||
|
saveSettingsDebounced();
|
||||||
|
//console.debug(DEBUG_PREFIX,"UPDATED BGM MAX TO",extension_settings.audio.bgm_volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function onAmbientSelectChange() {
|
||||||
|
extension_settings.audio.ambient_selected = $("#audio_ambient_select").val();
|
||||||
|
updateAmbient(true);
|
||||||
|
saveSettingsDebounced();
|
||||||
|
//console.debug(DEBUG_PREFIX,"UPDATED BGM MAX TO",extension_settings.audio.bgm_volume);
|
||||||
|
}
|
||||||
|
|
||||||
async function onBGMCooldownInput() {
|
async function onBGMCooldownInput() {
|
||||||
extension_settings.audio.bgm_cooldown = ~~($("#audio_bgm_cooldown").val());
|
extension_settings.audio.bgm_cooldown = ~~($("#audio_bgm_cooldown").val());
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
||||||
@@ -222,11 +348,42 @@ async function getCharacterBgmList(name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//#############################//
|
//#############################//
|
||||||
// Module Worker //
|
// Module Worker //
|
||||||
//#############################//
|
//#############################//
|
||||||
|
|
||||||
|
function fillBGMSelect() {
|
||||||
|
let found_last_selected_bgm = false;
|
||||||
|
// Update bgm list in UI
|
||||||
|
$("#audio_bgm_select")
|
||||||
|
.find('option')
|
||||||
|
.remove();
|
||||||
|
|
||||||
|
for (const file of fallback_BGMS) {
|
||||||
|
$('#audio_bgm_select').append(new Option("asset: " + file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""), file));
|
||||||
|
if (file === extension_settings.audio.bgm_selected) {
|
||||||
|
$('#audio_bgm_select').val(extension_settings.audio.bgm_selected);
|
||||||
|
found_last_selected_bgm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update bgm list in UI
|
||||||
|
for (const char in characterMusics)
|
||||||
|
for (const e in characterMusics[char])
|
||||||
|
for (const file of characterMusics[char][e]) {
|
||||||
|
$('#audio_bgm_select').append(new Option(char + ": " + file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""), file));
|
||||||
|
if (file === extension_settings.audio.bgm_selected) {
|
||||||
|
$('#audio_bgm_select').val(extension_settings.audio.bgm_selected);
|
||||||
|
found_last_selected_bgm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found_last_selected_bgm) {
|
||||||
|
$('#audio_bgm_select').val($("#audio_bgm_select option:first").val());
|
||||||
|
extension_settings.audio.bgm_selected = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
- Update ambient sound
|
- Update ambient sound
|
||||||
- Update character BGM
|
- Update character BGM
|
||||||
@@ -246,6 +403,8 @@ async function moduleWorker() {
|
|||||||
fallback_BGMS = await getAssetsList(ASSETS_BGM_FOLDER);
|
fallback_BGMS = await getAssetsList(ASSETS_BGM_FOLDER);
|
||||||
fallback_BGMS = fallback_BGMS.filter((filename) => filename != ".placeholder")
|
fallback_BGMS = fallback_BGMS.filter((filename) => filename != ".placeholder")
|
||||||
console.debug(DEBUG_PREFIX, "Detected assets:", fallback_BGMS);
|
console.debug(DEBUG_PREFIX, "Detected assets:", fallback_BGMS);
|
||||||
|
|
||||||
|
fillBGMSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ambients == null) {
|
if (ambients == null) {
|
||||||
@@ -253,10 +412,33 @@ async function moduleWorker() {
|
|||||||
ambients = await getAssetsList(ASSETS_AMBIENT_FOLDER);
|
ambients = await getAssetsList(ASSETS_AMBIENT_FOLDER);
|
||||||
ambients = ambients.filter((filename) => filename != ".placeholder")
|
ambients = ambients.filter((filename) => filename != ".placeholder")
|
||||||
console.debug(DEBUG_PREFIX, "Detected assets:", ambients);
|
console.debug(DEBUG_PREFIX, "Detected assets:", ambients);
|
||||||
|
|
||||||
|
// Update bgm list in UI
|
||||||
|
$("#audio_ambient_select")
|
||||||
|
.find('option')
|
||||||
|
.remove();
|
||||||
|
|
||||||
|
if (extension_settings.audio.ambient_selected !== null) {
|
||||||
|
let ambient_label = extension_settings.audio.ambient_selected;
|
||||||
|
if (ambient_label.includes("assets"))
|
||||||
|
ambient_label = "asset: " + ambient_label.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, "");
|
||||||
|
else {
|
||||||
|
ambient_label = ambient_label.substring("/characters/".length);
|
||||||
|
ambient_label = ambient_label.substring(0, ambient_label.indexOf("/")) + ": " + ambient_label.substring(ambient_label.indexOf("/") + "/bgm/".length);
|
||||||
|
ambient_label = ambient_label.replace(/\.[^/.]+$/, "");
|
||||||
|
}
|
||||||
|
$('#audio_ambient_select').append(new Option(ambient_label, extension_settings.audio.ambient_selected));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const file of ambients) {
|
||||||
|
if (file !== extension_settings.audio.ambient_selected)
|
||||||
|
$("#audio_ambient_select").append(new Option("asset: " + file.replace(/^.*[\\\/]/, '').replace(/\.[^/.]+$/, ""), file));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1) Update ambient audio
|
// 1) Update ambient audio
|
||||||
// ---------------------------
|
// ---------------------------
|
||||||
|
//if (extension_settings.audio.dynamic_ambient_enabled) {
|
||||||
let newBackground = $("#bg1").css("background-image");
|
let newBackground = $("#bg1").css("background-image");
|
||||||
const custom_background = getContext()["chatMetadata"]["custom_background"];
|
const custom_background = getContext()["chatMetadata"]["custom_background"];
|
||||||
|
|
||||||
@@ -275,6 +457,7 @@ async function moduleWorker() {
|
|||||||
updateAmbient();
|
updateAmbient();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
const context = getContext();
|
const context = getContext();
|
||||||
//console.debug(DEBUG_PREFIX,context);
|
//console.debug(DEBUG_PREFIX,context);
|
||||||
@@ -288,6 +471,14 @@ async function moduleWorker() {
|
|||||||
// 1) Update BGM (single chat)
|
// 1) Update BGM (single chat)
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
if (!chatIsGroup) {
|
if (!chatIsGroup) {
|
||||||
|
|
||||||
|
// Reset bgm list on new chat
|
||||||
|
if (context.chatId != current_chat_id) {
|
||||||
|
current_chat_id = context.chatId;
|
||||||
|
characterMusics = {};
|
||||||
|
cooldownBGM = 0;
|
||||||
|
}
|
||||||
|
|
||||||
newCharacter = context.name2;
|
newCharacter = context.name2;
|
||||||
|
|
||||||
//console.log(DEBUG_PREFIX,"SOLO CHAT MODE"); // DBG
|
//console.log(DEBUG_PREFIX,"SOLO CHAT MODE"); // DBG
|
||||||
@@ -307,7 +498,7 @@ async function moduleWorker() {
|
|||||||
if (currentCharacterBGM !== newCharacter) {
|
if (currentCharacterBGM !== newCharacter) {
|
||||||
currentCharacterBGM = newCharacter;
|
currentCharacterBGM = newCharacter;
|
||||||
try {
|
try {
|
||||||
await updateBGM();
|
await updateBGM(false, true);
|
||||||
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
@@ -346,6 +537,34 @@ async function moduleWorker() {
|
|||||||
|
|
||||||
// 2) Update BGM (group chat)
|
// 2) Update BGM (group chat)
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
|
|
||||||
|
// Load current chat character bgms
|
||||||
|
// Reset bgm list on new chat
|
||||||
|
if (context.chatId != current_chat_id) {
|
||||||
|
current_chat_id = context.chatId;
|
||||||
|
characterMusics = {};
|
||||||
|
cooldownBGM = 0;
|
||||||
|
for (const message of context.chat) {
|
||||||
|
if (characterMusics[message.name] === undefined)
|
||||||
|
await loadCharacterBGM(message.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
newCharacter = context.chat[context.chat.length - 1].name;
|
||||||
|
currentCharacterBGM = newCharacter;
|
||||||
|
await updateBGM(false, true);
|
||||||
|
cooldownBGM = extension_settings.audio.bgm_cooldown * 1000;
|
||||||
|
currentCharacterBGM = newCharacter;
|
||||||
|
currentExpressionBGM = FALLBACK_EXPRESSION;
|
||||||
|
console.debug(DEBUG_PREFIX, "(GROUP) Updated current character BGM to", currentExpressionBGM, "cooldown", cooldownBGM);
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.debug(DEBUG_PREFIX, "Error while trying to update BGM group, will try again");
|
||||||
|
currentCharacterBGM = null
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
newCharacter = context.chat[context.chat.length - 1].name;
|
newCharacter = context.chat[context.chat.length - 1].name;
|
||||||
const userName = context.name1;
|
const userName = context.name1;
|
||||||
|
|
||||||
@@ -353,17 +572,17 @@ async function moduleWorker() {
|
|||||||
|
|
||||||
//console.log(DEBUG_PREFIX,"GROUP CHAT MODE"); // DBG
|
//console.log(DEBUG_PREFIX,"GROUP CHAT MODE"); // DBG
|
||||||
|
|
||||||
// 2.1) First time character appear
|
// 2.1) New character appear
|
||||||
if (characterMusics[newCharacter] === undefined) {
|
if (characterMusics[newCharacter] === undefined) {
|
||||||
await loadCharacterBGM(newCharacter);
|
await loadCharacterBGM(newCharacter);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2) Switched chat
|
// 2.2) Switched char
|
||||||
if (currentCharacterBGM !== newCharacter) {
|
if (currentCharacterBGM !== newCharacter) {
|
||||||
// Check cooldown
|
// Check cooldown
|
||||||
if (cooldownBGM > 0) {
|
if (cooldownBGM > 0) {
|
||||||
//console.debug(DEBUG_PREFIX,"(GROUP) BGM switch on cooldown:",cooldownBGM);
|
console.debug(DEBUG_PREFIX, "(GROUP) BGM switch on cooldown:", cooldownBGM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,6 +648,8 @@ async function loadCharacterBGM(newCharacter) {
|
|||||||
characterMusics[newCharacter][e].push(i);
|
characterMusics[newCharacter][e].push(i);
|
||||||
}
|
}
|
||||||
console.debug(DEBUG_PREFIX, "Updated BGM map of", newCharacter, "to", characterMusics[newCharacter]);
|
console.debug(DEBUG_PREFIX, "Updated BGM map of", newCharacter, "to", characterMusics[newCharacter]);
|
||||||
|
|
||||||
|
fillBGMSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNewExpression() {
|
function getNewExpression() {
|
||||||
@@ -458,8 +679,29 @@ function getNewExpression() {
|
|||||||
return newExpression;
|
return newExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateBGM() {
|
async function updateBGM(isUserInput = false, newChat = false) {
|
||||||
let audio_files = characterMusics[currentCharacterBGM][currentExpressionBGM];// Try char expression BGM
|
if (!isUserInput && !extension_settings.audio.dynamic_bgm_enabled && $("#audio_bgm").attr("src") != "" && !bgmEnded && !newChat) {
|
||||||
|
console.debug(DEBUG_PREFIX, "BGM already playing and dynamic switch disabled, no update done");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let audio_file_path = ""
|
||||||
|
if (isUserInput || (extension_settings.audio.bgm_locked && extension_settings.audio.bgm_selected !== null)) {
|
||||||
|
audio_file_path = extension_settings.audio.bgm_selected;
|
||||||
|
|
||||||
|
if (isUserInput)
|
||||||
|
console.debug(DEBUG_PREFIX, "User selected BGM", audio_file_path);
|
||||||
|
if (extension_settings.audio.bgm_locked)
|
||||||
|
console.debug(DEBUG_PREFIX, "BGM locked keeping current audio", audio_file_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
let audio_files = null;
|
||||||
|
|
||||||
|
if (extension_settings.audio.dynamic_bgm_enabled) {
|
||||||
|
extension_settings.audio.bgm_selected = null;
|
||||||
|
saveSettingsDebounced();
|
||||||
|
audio_files = characterMusics[currentCharacterBGM][currentExpressionBGM];// Try char expression BGM
|
||||||
|
|
||||||
if (audio_files === undefined || audio_files.length == 0) {
|
if (audio_files === undefined || audio_files.length == 0) {
|
||||||
console.debug(DEBUG_PREFIX, "No BGM for", currentCharacterBGM, currentExpressionBGM);
|
console.debug(DEBUG_PREFIX, "No BGM for", currentCharacterBGM, currentExpressionBGM);
|
||||||
@@ -474,8 +716,15 @@ async function updateBGM() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
audio_files = [];
|
||||||
|
$("#audio_bgm_select option").each(function () { audio_files.push($(this).val()); });
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_file_path = audio_files[Math.floor(Math.random() * audio_files.length)];
|
||||||
|
}
|
||||||
|
|
||||||
const audio_file_path = audio_files[Math.floor(Math.random() * audio_files.length)];
|
|
||||||
console.log(DEBUG_PREFIX, "Updating BGM");
|
console.log(DEBUG_PREFIX, "Updating BGM");
|
||||||
console.log(DEBUG_PREFIX, "Checking file", audio_file_path);
|
console.log(DEBUG_PREFIX, "Checking file", audio_file_path);
|
||||||
try {
|
try {
|
||||||
@@ -485,20 +734,30 @@ async function updateBGM() {
|
|||||||
console.log(DEBUG_PREFIX, "File not found!")
|
console.log(DEBUG_PREFIX, "File not found!")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.log(DEBUG_PREFIX, "Switching BGM to", currentExpressionBGM)
|
console.log(DEBUG_PREFIX, "Switching BGM to", currentExpressionBGM);
|
||||||
|
$("#audio_bgm_select").val(audio_file_path);
|
||||||
const audio = $("#audio_bgm");
|
const audio = $("#audio_bgm");
|
||||||
|
|
||||||
if (audio.attr("src") == audio_file_path) {
|
if (audio.attr("src") == audio_file_path && !bgmEnded) {
|
||||||
console.log(DEBUG_PREFIX, "Already playing, ignored");
|
console.log(DEBUG_PREFIX, "Already playing, ignored");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
audio.animate({ volume: 0.0 }, 2000, function () {
|
let fade_time = 2000;
|
||||||
|
bgmEnded = false;
|
||||||
|
|
||||||
|
if (isUserInput || extension_settings.audio.bgm_locked) {
|
||||||
|
audio.attr("src", audio_file_path);
|
||||||
|
audio[0].play();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
audio.animate({ volume: 0.0 }, fade_time, function () {
|
||||||
audio.attr("src", audio_file_path);
|
audio.attr("src", audio_file_path);
|
||||||
audio[0].play();
|
audio[0].play();
|
||||||
audio.volume = extension_settings.audio.bgm_volume * 0.01;
|
audio.volume = extension_settings.audio.bgm_volume * 0.01;
|
||||||
audio.animate({ volume: extension_settings.audio.bgm_volume * 0.01 }, 2000);
|
audio.animate({ volume: extension_settings.audio.bgm_volume * 0.01 }, fade_time);
|
||||||
})
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -506,8 +765,19 @@ async function updateBGM() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateAmbient() {
|
async function updateAmbient(isUserInput = false) {
|
||||||
let audio_file_path = null;
|
let audio_file_path = null;
|
||||||
|
|
||||||
|
if (isUserInput || extension_settings.audio.ambient_locked) {
|
||||||
|
audio_file_path = extension_settings.audio.ambient_selected;
|
||||||
|
|
||||||
|
if (isUserInput)
|
||||||
|
console.debug(DEBUG_PREFIX, "User selected Ambient", audio_file_path);
|
||||||
|
if (extension_settings.audio.bgm_locked)
|
||||||
|
console.debug(DEBUG_PREFIX, "Ambient locked keeping current audio", audio_file_path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
extension_settings.audio.ambient_selected = null;
|
||||||
for (const i of ambients) {
|
for (const i of ambients) {
|
||||||
console.debug(i)
|
console.debug(i)
|
||||||
if (i.includes(currentBackground)) {
|
if (i.includes(currentBackground)) {
|
||||||
@@ -515,9 +785,10 @@ async function updateAmbient() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (audio_file_path === null) {
|
if (audio_file_path === null) {
|
||||||
console.debug(DEBUG_PREFIX, "No ambient file found for background", currentBackground);
|
console.debug(DEBUG_PREFIX, "No bgm file found for background", currentBackground);
|
||||||
const audio = $("#audio_ambient");
|
const audio = $("#audio_ambient");
|
||||||
audio.attr("src", "");
|
audio.attr("src", "");
|
||||||
audio[0].pause();
|
audio[0].pause();
|
||||||
@@ -527,45 +798,87 @@ async function updateAmbient() {
|
|||||||
//const audio_file_path = AMBIENT_FOLDER+currentBackground+".mp3";
|
//const audio_file_path = AMBIENT_FOLDER+currentBackground+".mp3";
|
||||||
console.log(DEBUG_PREFIX, "Updating ambient");
|
console.log(DEBUG_PREFIX, "Updating ambient");
|
||||||
console.log(DEBUG_PREFIX, "Checking file", audio_file_path);
|
console.log(DEBUG_PREFIX, "Checking file", audio_file_path);
|
||||||
|
$("#audio_ambient_select").val(audio_file_path);
|
||||||
|
|
||||||
|
let fade_time = 2000;
|
||||||
|
if (isUserInput)
|
||||||
|
fade_time = 0;
|
||||||
|
|
||||||
const audio = $("#audio_ambient");
|
const audio = $("#audio_ambient");
|
||||||
audio.animate({ volume: 0.0 }, 2000, function () {
|
|
||||||
|
if (audio.attr("src") == audio_file_path) {
|
||||||
|
console.log(DEBUG_PREFIX, "Already playing, ignored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio.animate({ volume: 0.0 }, fade_time, function () {
|
||||||
audio.attr("src", audio_file_path);
|
audio.attr("src", audio_file_path);
|
||||||
audio[0].play();
|
audio[0].play();
|
||||||
audio.volume = extension_settings.audio.ambient_volume * 0.01;
|
audio.volume = extension_settings.audio.ambient_volume * 0.01;
|
||||||
audio.animate({ volume: extension_settings.audio.ambient_volume * 0.01 }, 2000);
|
audio.animate({ volume: extension_settings.audio.ambient_volume * 0.01 }, fade_time);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles wheel events on volume sliders.
|
||||||
|
* @param {WheelEvent} e Event
|
||||||
|
*/
|
||||||
|
function onVolumeSliderWheelEvent(e) {
|
||||||
|
const slider = $(this);
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const delta = e.deltaY / 20;
|
||||||
|
const sliderVal = Number(slider.val());
|
||||||
|
|
||||||
|
let newVal = sliderVal - delta;
|
||||||
|
if (newVal < 0) {
|
||||||
|
newVal = 0;
|
||||||
|
} else if (newVal > 100) {
|
||||||
|
newVal = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
slider.val(newVal).trigger('input');
|
||||||
|
}
|
||||||
|
|
||||||
//#############################//
|
//#############################//
|
||||||
// Extension load //
|
// Extension load //
|
||||||
//#############################//
|
//#############################//
|
||||||
|
|
||||||
// This function is called when the extension is loaded
|
// This function is called when the extension is loaded
|
||||||
jQuery(async () => {
|
jQuery(async () => {
|
||||||
// This is an example of loading HTML from a file
|
|
||||||
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
|
const windowHtml = $(await $.get(`${extensionFolderPath}/window.html`));
|
||||||
|
|
||||||
$('#extensions_settings').append(windowHtml);
|
$('#extensions_settings').append(windowHtml);
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
|
||||||
$("#audio_bgm").attr("loop", true);
|
$("#audio_enabled").on("click", onEnabledClick);
|
||||||
|
$("#audio_dynamic_bgm_enabled").on("click", onDynamicBGMEnabledClick);
|
||||||
|
//$("#audio_dynamic_ambient_enabled").on("click", onDynamicAmbientEnabledClick);
|
||||||
|
|
||||||
|
//$("#audio_bgm").attr("loop", false);
|
||||||
$("#audio_ambient").attr("loop", true);
|
$("#audio_ambient").attr("loop", true);
|
||||||
|
|
||||||
$("#audio_bgm").hide();
|
$("#audio_bgm").hide();
|
||||||
$("#audio_ambient").hide();
|
$("#audio_bgm_lock").on("click", onBGMLockClick);
|
||||||
$("#audio_bgm_mute").on("click", onBGMMuteClick);
|
$("#audio_bgm_mute").on("click", onBGMMuteClick);
|
||||||
$("#audio_ambient_mute").on("click", onAmbientMuteClick);
|
|
||||||
|
|
||||||
$("#audio_enabled").on("click", onEnabledClick);
|
|
||||||
$("#audio_bgm_volume_slider").on("input", onBGMVolumeChange);
|
$("#audio_bgm_volume_slider").on("input", onBGMVolumeChange);
|
||||||
|
$("#audio_bgm_random").on("click", onBGMRandomClick);
|
||||||
|
|
||||||
|
$("#audio_ambient").hide();
|
||||||
|
$("#audio_ambient_lock").on("click", onAmbientLockClick);
|
||||||
|
$("#audio_ambient_mute").on("click", onAmbientMuteClick);
|
||||||
$("#audio_ambient_volume_slider").on("input", onAmbientVolumeChange);
|
$("#audio_ambient_volume_slider").on("input", onAmbientVolumeChange);
|
||||||
|
|
||||||
|
document.getElementById('audio_ambient_volume_slider').addEventListener('wheel', onVolumeSliderWheelEvent, { passive: false });
|
||||||
|
document.getElementById('audio_bgm_volume_slider').addEventListener('wheel', onVolumeSliderWheelEvent, { passive: false });
|
||||||
|
|
||||||
$("#audio_bgm_cooldown").on("input", onBGMCooldownInput);
|
$("#audio_bgm_cooldown").on("input", onBGMCooldownInput);
|
||||||
|
|
||||||
// Reset assets container, will be redected like if ST restarted
|
// Reset assets container, will be redected like if ST restarted
|
||||||
$("#audio_refresh_assets").on("click", function () {
|
$("#audio_refresh_assets").on("click", function () {
|
||||||
console.debug(DEBUG_PREFIX, "Refreshing audio assets");
|
console.debug(DEBUG_PREFIX, "Refreshing audio assets");
|
||||||
|
current_chat_id = null
|
||||||
fallback_BGMS = null;
|
fallback_BGMS = null;
|
||||||
ambients = null;
|
ambients = null;
|
||||||
characterMusics = {};
|
characterMusics = {};
|
||||||
@@ -574,6 +887,9 @@ jQuery(async () => {
|
|||||||
currentBackground = null;
|
currentBackground = null;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$("#audio_bgm_select").on("change", onBGMSelectChange);
|
||||||
|
$("#audio_ambient_select").on("change", onAmbientSelectChange);
|
||||||
|
|
||||||
// DBG
|
// DBG
|
||||||
$("#audio_debug").on("click", function () {
|
$("#audio_debug").on("click", function () {
|
||||||
if ($("#audio_debug").is(':checked')) {
|
if ($("#audio_debug").is(':checked')) {
|
||||||
@@ -587,6 +903,14 @@ jQuery(async () => {
|
|||||||
});
|
});
|
||||||
//
|
//
|
||||||
|
|
||||||
|
$("#audio_bgm").on("ended", function () {
|
||||||
|
console.debug(DEBUG_PREFIX, "END OF BGM")
|
||||||
|
if (!extension_settings.audio.bgm_locked) {
|
||||||
|
bgmEnded = true;
|
||||||
|
updateBGM();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
const wrapper = new ModuleWorkerWrapper(moduleWorker);
|
||||||
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL);
|
setInterval(wrapper.update.bind(wrapper), UPDATE_INTERVAL);
|
||||||
moduleWorker();
|
moduleWorker();
|
||||||
|
@@ -1,15 +1,68 @@
|
|||||||
.mixer-div {
|
.audio-ui-block {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-mixer-div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
background-color: rgba(38, 38, 38, 0.5);
|
||||||
|
border: 1px rgb(75, 75, 75) solid;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-mixer-element {
|
||||||
|
height: 60px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 10px;
|
||||||
|
label {
|
||||||
|
text-align: top;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-label {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-volume-div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-lock-button {
|
||||||
|
padding: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-random-button {
|
||||||
|
padding: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
height: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.audio-mute-button {
|
.audio-mute-button {
|
||||||
padding: 5px;
|
padding: 1rem;
|
||||||
width: 50px;
|
width: 100%;
|
||||||
height: 30px;
|
height: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-slider {
|
||||||
|
width: 100% !important;
|
||||||
|
vertical-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.audio-mute-button-muted {
|
.audio-mute-button-muted {
|
||||||
@@ -20,3 +73,23 @@
|
|||||||
width: 50px;
|
width: 50px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.audio-mixer-mute {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-mixer-volume {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-mixer-playlist {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-mixer-lock {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.audio-mixer-random {
|
||||||
|
width: 10%;
|
||||||
|
}
|
@@ -10,6 +10,20 @@
|
|||||||
<input type="checkbox" id="audio_enabled" name="audio_enabled">
|
<input type="checkbox" id="audio_enabled" name="audio_enabled">
|
||||||
<small>Enabled</small>
|
<small>Enabled</small>
|
||||||
</label>
|
</label>
|
||||||
|
<div id="audio_bgm_dynamic_enable_div">
|
||||||
|
<label class="checkbox_label" for="audio_dynamic_bgm_enabled">
|
||||||
|
<input type="checkbox" id="audio_dynamic_bgm_enabled" name="audio_dynamic_bgm_enabled">
|
||||||
|
<small>Enable expression BGM switch (req. character expression)</small>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<!--
|
||||||
|
<div id="audio_ambient_dynamic_enable_div">
|
||||||
|
<label class="checkbox_label" for="audio_dynamic_ambient_enabled">
|
||||||
|
<input type="checkbox" id="audio_dynamic_ambient_enabled" name="audio_dynamic_ambient_enabled">
|
||||||
|
<small>Enable ambient background switch (req. chat background)</small>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
<div id="audio_debug_div">
|
<div id="audio_debug_div">
|
||||||
<label class="checkbox_label" for="audio_debug">
|
<label class="checkbox_label" for="audio_debug">
|
||||||
<input type="checkbox" id="audio_debug" name="audio_debug">
|
<input type="checkbox" id="audio_debug" name="audio_debug">
|
||||||
@@ -24,23 +38,63 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div class="audio-ui-block">
|
||||||
<label for="audio_bgm_volume_slider">Music <span id="audio_bgm_volume"></span></label>
|
<label for="audio_bgm_volume_slider">Music</label>
|
||||||
<div class="mixer-div">
|
<div class="audio-mixer-div">
|
||||||
|
<div class="audio-mixer-element audio-mixer-mute">
|
||||||
|
<label for="audio_bgm_lock" class="audio-label">Mute</label>
|
||||||
<div id="audio_bgm_mute" class="menu_button audio-mute-button">
|
<div id="audio_bgm_mute" class="menu_button audio-mute-button">
|
||||||
<i class="fa-solid fa-volume-high fa-lg" id="audio_bgm_mute_icon"></i>
|
<i class="fa-solid fa-volume-high fa-lg" id="audio_bgm_mute_icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<input type="range" class ="slider" id ="audio_bgm_volume_slider" value = "0" maxlength ="100">
|
</div>
|
||||||
|
<div class="audio-mixer-element audio-mixer-volume">
|
||||||
|
<label for="audio_bgm_lock" class="audio-label">Vol <span id="audio_bgm_volume"></span></label>
|
||||||
|
<input type="range" class ="audio-slider" id ="audio_bgm_volume_slider" value = "0" maxlength ="100">
|
||||||
|
</div>
|
||||||
|
<div class="audio-mixer-element audio-mixer-playlist">
|
||||||
|
<label for="audio_bgm_lock" class="audio-label">Playlist</label>
|
||||||
|
<select id="audio_bgm_select">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="audio-mixer-element audio-mixer-lock">
|
||||||
|
<label for="audio_bgm_lock" class="audio-label">Loop</label>
|
||||||
|
<div id="audio_bgm_lock" class="menu_button audio-lock-button">
|
||||||
|
<i class="fa-solid fa-repeat fa-lg" id="audio_bgm_lock_icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="audio-mixer-element audio-mixer-random">
|
||||||
|
<label for="audio_bgm_random" class="audio-label">Roll</label>
|
||||||
|
<div id="audio_bgm_random" class="menu_button audio-random-button">
|
||||||
|
<i class="fa-solid fa-random fa-lg" id="audio_bgm_random_icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<audio id="audio_bgm" controls src="">
|
<audio id="audio_bgm" controls src="">
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label for="audio_ambient_volume_slider">Ambient <span id="audio_ambient_volume"></span></label>
|
<label for="audio_ambient_volume_slider">Ambient</label>
|
||||||
<div class="mixer-div">
|
<div class="audio-mixer-div">
|
||||||
|
<div class="audio-mixer-element audio-mixer-mute">
|
||||||
|
<label for="audio_ambient_lock" class="audio-label">Mute</label>
|
||||||
<div id="audio_ambient_mute" class="menu_button audio-mute-button">
|
<div id="audio_ambient_mute" class="menu_button audio-mute-button">
|
||||||
<i class="fa-solid fa-volume-high fa-lg" id="audio_ambient_mute_icon"></i>
|
<i class="fa-solid fa-volume-high fa-lg" id="audio_ambient_mute_icon"></i>
|
||||||
</div>
|
</div>
|
||||||
<input type="range" class ="slider" id ="audio_ambient_volume_slider" value = "0" maxlength ="100">
|
</div>
|
||||||
|
<div class="audio-mixer-element audio-mixer-volume">
|
||||||
|
<label for="audio_ambient_lock" class="audio-label">Vol <span id="audio_ambient_volume"></span></label>
|
||||||
|
<input type="range" class ="audio-slider" id ="audio_ambient_volume_slider" value = "0" maxlength ="100">
|
||||||
|
</div>
|
||||||
|
<div class="audio-mixer-element audio-mixer-playlist">
|
||||||
|
<label for="audio_ambient_lock" class="audio-label">Playlist</label>
|
||||||
|
<select id="audio_ambient_select">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="audio-mixer-element">
|
||||||
|
<label for="audio_ambient_lock audio-mixer-lock" class="audio-label">Lock</label>
|
||||||
|
<div id="audio_ambient_lock" class="menu_button audio-lock-button">
|
||||||
|
<i class="fa-solid fa-lock-open fa-lg" id="audio_ambient_lock_icon"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<audio id="audio_ambient" controls src="">
|
<audio id="audio_ambient" controls src="">
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user