added audio and video messages
Continuous integration / Check (push) Successful in 39s
Continuous integration / Rustfmt (push) Successful in 34s
Continuous integration / build (push) Successful in 37s
Continuous integration / build-release (push) Successful in 1m3s

This commit is contained in:
wt committed 2026-02-15 17:40:32 +07:00
1 parent 9016889a78
commit 78ca22e1b7
6 files changed
+492 -7

No files matched your search

+56 -6
View File
@@ -6,6 +6,9 @@ use axum::response::Json;
use image::GenericImageView;
use std::path::Path;
use std::sync::Arc;
use symphonia::core::formats::FormatOptions;
use symphonia::core::meta::MetadataOptions;
use symphonia::core::probe::Hint;
use tokio::fs;
use tokio::io::AsyncWriteExt;
@@ -180,13 +183,14 @@ pub async fn upload_file_handler(
}))
}
FileType::Video => {
// For now, we'll just return basic info for videos
// In a real implementation, you might want to extract duration using ffmpeg
// Extract duration for video files
let duration = extract_duration(&filepath).await;
let video_info = VideoInfo {
filename: filename.clone(),
filepath: filepathweb.clone(),
size,
duration: None, // Duration extraction would require additional libraries
duration,
mime_type: content_type.clone(),
};
@@ -197,13 +201,14 @@ pub async fn upload_file_handler(
}))
}
FileType::Audio => {
// For now, we'll just return basic info for audio
// In a real implementation, you might want to extract duration using ffmpeg
// Extract duration for audio files
let duration = extract_duration(&filepath).await;
let audio_info = AudioInfo {
filename: filename.clone(),
filepath: filepathweb.clone(),
size,
duration: None, // Duration extraction would require additional libraries
duration,
mime_type: content_type.clone(),
};
@@ -242,6 +247,51 @@ enum FileType {
Generic,
}
// Function to extract duration from audio/video files
async fn extract_duration(filepath: &str) -> Option<f64> {
use symphonia::core::io::MediaSourceStream;
let file = match std::fs::File::open(filepath) {
Ok(file) => file,
Err(_) => return None,
};
let mss = MediaSourceStream::new(Box::new(file), Default::default());
let mut hint = Hint::new();
if let Some(ext) = Path::new(filepath).extension().and_then(|ext| ext.to_str()) {
hint.with_extension(ext);
}
let format_opts = FormatOptions::default();
let metadata_opts = MetadataOptions::default();
let probed =
match symphonia::default::get_probe().format(&hint, mss, &format_opts, &metadata_opts) {
Ok(probed) => probed,
Err(_) => return None,
};
let track = match probed
.format
.tracks()
.iter()
.find(|t| t.codec_params.codec != symphonia::core::codecs::CODEC_TYPE_NULL)
{
Some(track) => track,
None => return None,
};
let duration = track.codec_params.time_base.and_then(|tb| {
track
.codec_params
.n_frames
.and_then(|frames| Some(tb.calc_time(frames).seconds as f64))
});
duration
}
fn determine_file_type(content_type: &str, filename: &str) -> Option<FileType> {
let lower_ct = content_type.to_lowercase();
let lower_fn = filename.to_lowercase();