Scan and generate Video HLS playlists on startup

Refactored and improved video path state. Bumped versions of some dependencies.
This commit is contained in:
Cameron
2024-12-05 20:19:03 -05:00
parent 2b2a811cae
commit 0419aa2323
6 changed files with 593 additions and 62 deletions

View File

@@ -212,9 +212,9 @@ async fn generate_video(
) -> impl Responder {
let filename = PathBuf::from(&body.path);
if let Some(name) = filename.file_stem() {
if let Some(name) = filename.file_name() {
let filename = name.to_str().expect("Filename should convert to string");
let playlist = format!("tmp/{}.m3u8", filename);
let playlist = format!("{}/{}.m3u8", app_state.video_path, filename);
if let Some(path) = is_valid_full_path(&app_state.base_path, &body.path, false) {
if let Ok(child) = create_playlist(path.to_str().unwrap(), &playlist).await {
app_state
@@ -243,7 +243,7 @@ async fn stream_video(
debug!("Playlist: {}", playlist);
// Extract video playlist dir to dotenv
if !playlist.starts_with("tmp")
if !playlist.starts_with(&app_state.video_path)
&& is_valid_full_path(&app_state.base_path, playlist, false).is_some()
{
HttpResponse::BadRequest().finish()
@@ -259,14 +259,19 @@ async fn get_video_part(
request: HttpRequest,
_: Claims,
path: web::Path<ThumbnailRequest>,
app_state: Data<AppState>,
) -> impl Responder {
let part = &path.path;
debug!("Video part: {}", part);
if let Ok(file) = NamedFile::open(String::from("tmp/") + part) {
let mut file_part = PathBuf::new();
file_part.push(app_state.video_path.clone());
file_part.push(part);
// TODO: Do we need to guard against directory attacks here?
if let Ok(file) = NamedFile::open(&file_part) {
file.into_response(&request)
} else {
error!("Video part not found: tmp/{}", part);
error!("Video part not found: {:?}", file_part);
HttpResponse::NotFound().finish()
}
}
@@ -450,6 +455,7 @@ fn is_image(entry: &DirEntry) -> bool {
.path()
.extension()
.and_then(|ext| ext.to_str())
.map(|ext| ext.to_lowercase())
.map(|ext| ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "nef")
.unwrap_or(false)
}
@@ -459,6 +465,7 @@ fn is_video(entry: &DirEntry) -> bool {
.path()
.extension()
.and_then(|ext| ext.to_str())
.map(|ext| ext.to_lowercase())
.map(|ext| ext == "mp4" || ext == "mov")
.unwrap_or(false)
}
@@ -493,6 +500,13 @@ fn main() -> std::io::Result<()> {
.register(Box::new(VIDEO_GAUGE.clone()))
.unwrap();
let app_state = app_data.clone();
app_state
.playlist_manager
.do_send(ScanDirectoryMessage {
directory: app_state.base_path.clone(),
});
HttpServer::new(move || {
let user_dao = SqliteUserDao::new();
let favorites_dao = SqliteFavoriteDao::new();