select wanted_frame_skip based on total video length
This commit is contained in:
parent
da0d0c2c91
commit
a24799e302
43
src/main.rs
43
src/main.rs
|
@ -1,23 +1,24 @@
|
||||||
use axum::body::Bytes;
|
|
||||||
use axum::extract::{Multipart, Query};
|
use axum::extract::{Multipart, Query};
|
||||||
use axum::http::StatusCode;
|
use axum::http::StatusCode;
|
||||||
use axum::response::{IntoResponse, Response};
|
use axum::response::{IntoResponse, Response};
|
||||||
use axum::routing::post;
|
use axum::routing::post;
|
||||||
use axum::{Json, Router};
|
use axum::{Json, Router};
|
||||||
use axum_macros::debug_handler;
|
use axum_macros::debug_handler;
|
||||||
use filepath::FilePath;
|
use ffmpeg_cli::Parameter;
|
||||||
use reqwest::header::WWW_AUTHENTICATE;
|
use futures_util::{future::ready, StreamExt};
|
||||||
use serde::__private::de::FlatInternallyTaggedAccess;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::process::Stdio;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
// build our application with a single route
|
// build our application with a single route
|
||||||
let app = Router::new().route("/", post(upload_file));
|
let app = Router::new()
|
||||||
|
.route("/", post(upload_file))
|
||||||
|
.layer(axum::extract::DefaultBodyLimit::max(100 * 1024 * 1024));
|
||||||
|
|
||||||
// run it with hyper on localhost:3000
|
// run it with hyper on localhost:3000
|
||||||
axum::Server::bind(&"0.0.0.0:6679".parse().unwrap())
|
axum::Server::bind(&"0.0.0.0:6679".parse().unwrap())
|
||||||
|
@ -44,7 +45,6 @@ struct AppError(anyhow::Error);
|
||||||
// Tell axum how to convert `AppError` into a response.
|
// Tell axum how to convert `AppError` into a response.
|
||||||
impl IntoResponse for AppError {
|
impl IntoResponse for AppError {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
println!("amogus");
|
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
format!("Something went wrong: {}", self.0),
|
format!("Something went wrong: {}", self.0),
|
||||||
|
@ -103,12 +103,6 @@ async fn send_image_to_dd(
|
||||||
Ok(json_response)
|
Ok(json_response)
|
||||||
}
|
}
|
||||||
|
|
||||||
use std::process::Stdio;
|
|
||||||
|
|
||||||
use ffmpeg_cli::Parameter;
|
|
||||||
|
|
||||||
use futures_util::{future::ready, StreamExt};
|
|
||||||
|
|
||||||
async fn fetch_frame_as_image(
|
async fn fetch_frame_as_image(
|
||||||
input_path: &str,
|
input_path: &str,
|
||||||
output_path: &str,
|
output_path: &str,
|
||||||
|
@ -129,11 +123,15 @@ async fn fetch_frame_as_image(
|
||||||
log::debug!("running {:?}", builder);
|
log::debug!("running {:?}", builder);
|
||||||
let ffmpeg = builder.run().await.unwrap();
|
let ffmpeg = builder.run().await.unwrap();
|
||||||
|
|
||||||
|
// TODO ffmpeg doesnt really provide a progress bar for this, its just
|
||||||
|
// a single frame being extracted. should ignoring x.unwrap() be the
|
||||||
|
// actual thing we gotta do?
|
||||||
|
|
||||||
log::debug!("run");
|
log::debug!("run");
|
||||||
ffmpeg
|
ffmpeg
|
||||||
.progress
|
.progress
|
||||||
.for_each(|x| {
|
.for_each(|x| {
|
||||||
dbg!(&x);
|
log::debug!("progress x value = {:?}", &x);
|
||||||
// lmao
|
// lmao
|
||||||
// x.unwrap();
|
// x.unwrap();
|
||||||
ready(())
|
ready(())
|
||||||
|
@ -144,7 +142,7 @@ async fn fetch_frame_as_image(
|
||||||
let output = ffmpeg.process.wait_with_output().unwrap();
|
let output = ffmpeg.process.wait_with_output().unwrap();
|
||||||
|
|
||||||
log::debug!("out");
|
log::debug!("out");
|
||||||
println!(
|
log::debug!(
|
||||||
"{}\nstderr:\n{}",
|
"{}\nstderr:\n{}",
|
||||||
output.status,
|
output.status,
|
||||||
std::str::from_utf8(&output.stderr).unwrap()
|
std::str::from_utf8(&output.stderr).unwrap()
|
||||||
|
@ -191,22 +189,29 @@ async fn upload_file(
|
||||||
let info = ffprobe::ffprobe(temp_file.path())?;
|
let info = ffprobe::ffprobe(temp_file.path())?;
|
||||||
let stream = info.streams.get(0).unwrap();
|
let stream = info.streams.get(0).unwrap();
|
||||||
|
|
||||||
let all_frames = stream.nb_frames.clone().unwrap().parse::<u32>()?;
|
let total_frame_count = stream.nb_frames.clone().unwrap().parse::<u32>()?;
|
||||||
let frame_rate_str = stream.r_frame_rate.clone();
|
let frame_rate_str = stream.r_frame_rate.clone();
|
||||||
|
|
||||||
let parts = frame_rate_str.split("/").into_iter().collect::<Vec<_>>();
|
let parts = frame_rate_str.split("/").into_iter().collect::<Vec<_>>();
|
||||||
let frame_rate =
|
let frame_rate =
|
||||||
parts.get(0).unwrap().parse::<u32>()? / parts.get(1).unwrap().parse::<u32>()?;
|
parts.get(0).unwrap().parse::<u32>()? / parts.get(1).unwrap().parse::<u32>()?;
|
||||||
|
|
||||||
let wanted_frame_skip = frame_rate.try_into().unwrap(); // every second
|
let total_length_in_seconds = total_frame_count / frame_rate;
|
||||||
|
let wanted_frame_skip_seconds = match total_length_in_seconds {
|
||||||
|
0..=10 => 2,
|
||||||
|
11..=60 => 10,
|
||||||
|
61..=120 => 15,
|
||||||
|
121.. => 20,
|
||||||
|
};
|
||||||
|
let wanted_frame_skip = (wanted_frame_skip_seconds * frame_rate).try_into().unwrap();
|
||||||
|
|
||||||
let temporary_frame_dir = tempfile::tempdir()?;
|
let temporary_frame_dir = tempfile::tempdir()?;
|
||||||
|
|
||||||
let temporary_frame_path =
|
let temporary_frame_path =
|
||||||
format!("{}/frame.png", temporary_frame_dir.path().to_string_lossy());
|
format!("{}/frame.png", temporary_frame_dir.path().to_string_lossy());
|
||||||
log::info!("path:{}", &temporary_frame_path);
|
log::info!("path: '{}'", &temporary_frame_path);
|
||||||
|
log::info!("wanted_frame_skip: {}", &wanted_frame_skip_seconds);
|
||||||
|
|
||||||
for frame_number in (0..all_frames).step_by(wanted_frame_skip) {
|
for frame_number in (0..total_frame_count).step_by(wanted_frame_skip) {
|
||||||
log::info!("extracting frame {:?}", frame_number);
|
log::info!("extracting frame {:?}", frame_number);
|
||||||
fetch_frame_as_image(
|
fetch_frame_as_image(
|
||||||
temp_file.path().to_str().unwrap(),
|
temp_file.path().to_str().unwrap(),
|
||||||
|
|
Loading…
Reference in New Issue