code: adding mp3 duration to lock buttons client side
This commit is contained in:
parent
a7da277977
commit
69ec048bc9
14
Cargo.lock
generated
14
Cargo.lock
generated
@ -560,9 +560,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.147"
|
||||
version = "0.2.152"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@ -689,6 +689,15 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mp3-duration"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "348bdc7300502f0801e5b57c448815713cd843b744ef9bda252a2698fdf90a0f"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.7.0"
|
||||
@ -1145,6 +1154,7 @@ dependencies = [
|
||||
"log",
|
||||
"minijinja",
|
||||
"minimp3",
|
||||
"mp3-duration",
|
||||
"regex",
|
||||
"rodio",
|
||||
"serde",
|
||||
|
@ -11,8 +11,10 @@ axum = "0.6.18"
|
||||
axum-template = { version = "0.19.0", features = ["minijinja"] }
|
||||
cpal = "0.15.2"
|
||||
log = "0.4.20"
|
||||
# metadata = "0.1.8"
|
||||
minijinja = { version = "1.0.3", features = ["loader"] }
|
||||
minimp3 = "0.5.1"
|
||||
mp3-duration = "0.1.10"
|
||||
regex = "1.9.0"
|
||||
rodio = "0.17.1"
|
||||
serde = { version = "1.0.171", features = ["derive"] }
|
||||
|
@ -6,9 +6,11 @@ use std::fs;
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct SoundClip {
|
||||
title: String,
|
||||
hash: String,
|
||||
file_name: String,
|
||||
directory: String,
|
||||
length: Option<u64>,
|
||||
}
|
||||
|
||||
impl fmt::Display for SoundClip {
|
||||
@ -23,8 +25,11 @@ impl fmt::Display for SoundClip {
|
||||
|
||||
impl SoundClip {
|
||||
pub fn new(file_name: String, directory: String) -> Self {
|
||||
let full_file_name = format!("{}/{}", directory, file_name);
|
||||
Self {
|
||||
title: normalize_filename(&file_name),
|
||||
hash: encode_filename(&file_name),
|
||||
length: get_sound_clip_length(&full_file_name),
|
||||
file_name: file_name,
|
||||
directory: directory,
|
||||
}
|
||||
@ -49,6 +54,44 @@ fn encode_filename(file_name: &str) -> String {
|
||||
hash_hex
|
||||
}
|
||||
|
||||
/* // needs metadata to install ffmpeg.
|
||||
fn get_sound_clip_length(file_path: &str) -> Option<u64> {
|
||||
if let Ok(meta) = metadata::media_file::MediaFileMetadata::new(&std::path::Path::new(file_path))
|
||||
{
|
||||
return Some(meta._duration);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
*/
|
||||
|
||||
fn get_sound_clip_length(file_path: &str) -> Option<u64> {
|
||||
let path = std::path::Path::new(file_path);
|
||||
if let Ok(duration) = mp3_duration::from_path(&path) {
|
||||
if let Ok(millis) = duration.as_millis().try_into() {
|
||||
return Some(millis);
|
||||
}
|
||||
return Some(duration.as_secs() * 1000 + 1);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
fn normalize_filename(input: &str) -> String {
|
||||
// List of extensions to be removed
|
||||
let extensions = [".mp3", ".wav", ".flac", ".ogg"];
|
||||
|
||||
// Remove the extension if it matches any in the list
|
||||
let without_extension = extensions.iter().fold(input.to_string(), |acc, &ext| {
|
||||
if acc.ends_with(ext) {
|
||||
acc.trim_end_matches(ext).to_string()
|
||||
} else {
|
||||
acc
|
||||
}
|
||||
});
|
||||
|
||||
// Replace all underscores with spaces
|
||||
without_extension.replace("_", " ")
|
||||
}
|
||||
|
||||
pub fn scan_directory_for_clips(directory: &str, extensions: &[&str]) -> Option<Vec<SoundClip>> {
|
||||
let mut sound_clips = Vec::new();
|
||||
|
||||
|
@ -47,12 +47,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
function play(hash) {
|
||||
var disableTimeout;
|
||||
var none = null;
|
||||
|
||||
function play(hash, timeout) {
|
||||
|
||||
if (timeout && timeout != "none") {
|
||||
// Add the "disabled" class to all clip buttons
|
||||
$('.clip').addClass('disabled');
|
||||
|
||||
// Add "primary" and "loading" classes to the clicked button
|
||||
var clickedButton = $('#clip-' + hash);
|
||||
clickedButton.addClass('double loading positive');
|
||||
|
||||
// Clear any existing timeout to avoid conflicts
|
||||
clearTimeout(disableTimeout);
|
||||
|
||||
// Set a new timeout
|
||||
disableTimeout = setTimeout(function () {
|
||||
$('.clip').removeClass('disabled');
|
||||
clickedButton.removeClass('double loading positive');
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
fetch("/play/" + hash);
|
||||
}
|
||||
|
||||
function stop() {
|
||||
fetch("/stop");
|
||||
|
||||
// Clear the timeout
|
||||
clearTimeout(disableTimeout);
|
||||
|
||||
// Remove the "disabled" class from all clip buttons
|
||||
// and the "primary" and "loading" classes from any button that might have them
|
||||
$('.clip').removeClass('disabled');
|
||||
$('.clip').removeClass('double loading positive');
|
||||
}
|
||||
</script>
|
||||
<style type="text/css">
|
||||
@ -61,6 +91,10 @@
|
||||
/* Define a CSS variable for the width */
|
||||
}
|
||||
|
||||
.ui.ui.ui.ui.ui.ui.loading.button {
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
.left-column {
|
||||
width: var(--left-column-width) !important;
|
||||
height: 100%;
|
||||
@ -110,8 +144,9 @@
|
||||
|
||||
<div class="ui wrapped compact wrapping spaced /**buttons">
|
||||
{% for clip in clips %}
|
||||
<button class="ui {{ loop.cycle('red', 'blue', 'green', 'violet', 'orange') }} basic button"
|
||||
onclick="play('{{clip.hash}}')">{{clip.file_name}}</button>
|
||||
<button id="clip-{{clip.hash}}"
|
||||
class="ui {{ loop.cycle('red', 'blue', 'green', 'violet', 'orange') }} basic button clip"
|
||||
onclick="play('{{clip.hash}}', {{clip.length}})">{{clip.title}}</button>
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user