Generating a HLS playlist through ffmpeg
I might be able to streamline the requests to cut down on the endpoints. This also will likely take some time if the file is large and could time out, that may be a concern for another day.
This commit is contained in:
48
src/main.rs
48
src/main.rs
@@ -13,10 +13,12 @@ use std::path::PathBuf;
|
|||||||
use crate::data::{Claims, CreateAccountRequest, Token};
|
use crate::data::{Claims, CreateAccountRequest, Token};
|
||||||
use crate::database::{create_user, get_user, user_exists};
|
use crate::database::{create_user, get_user, user_exists};
|
||||||
use crate::files::list_files;
|
use crate::files::list_files;
|
||||||
|
use crate::video::create_playlist;
|
||||||
|
|
||||||
mod data;
|
mod data;
|
||||||
mod database;
|
mod database;
|
||||||
mod files;
|
mod files;
|
||||||
|
mod video;
|
||||||
|
|
||||||
#[post("/register")]
|
#[post("/register")]
|
||||||
async fn register(user: Json<CreateAccountRequest>) -> impl Responder {
|
async fn register(user: Json<CreateAccountRequest>) -> impl Responder {
|
||||||
@@ -119,16 +121,58 @@ async fn image(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/video/generate")]
|
||||||
|
async fn generate_video(_claims: Claims, body: web::Json<ThumbnailRequest>) -> impl Responder {
|
||||||
|
let filename = PathBuf::from(&body.path);
|
||||||
|
|
||||||
|
if let Some(name) = filename.file_stem() {
|
||||||
|
let filename = name.to_str().expect("Filename should conver to string");
|
||||||
|
create_playlist(&body.path, &format!("tmp/{}.m3u8", filename));
|
||||||
|
|
||||||
|
HttpResponse::Ok()
|
||||||
|
} else {
|
||||||
|
HttpResponse::BadRequest()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/video/stream")]
|
||||||
|
async fn stream_video(request: HttpRequest, path: web::Query<ThumbnailRequest>) -> impl Responder {
|
||||||
|
let playlist = &path.path;
|
||||||
|
println!("Playlist: {}", playlist);
|
||||||
|
|
||||||
|
if let Ok(file) = NamedFile::open(playlist) {
|
||||||
|
file.into_response(&request).unwrap()
|
||||||
|
} else {
|
||||||
|
HttpResponse::NotFound().finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/video/{path}")]
|
||||||
|
async fn get_video_part(request: HttpRequest, path: web::Path<ThumbnailRequest>) -> impl Responder {
|
||||||
|
let playlist = &path.path;
|
||||||
|
println!("Video part: {}", playlist);
|
||||||
|
|
||||||
|
if let Ok(file) = NamedFile::open(String::from("tmp/") + playlist) {
|
||||||
|
file.into_response(&request).unwrap()
|
||||||
|
} else {
|
||||||
|
HttpResponse::NotFound().finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[actix_rt::main]
|
#[actix_rt::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
HttpServer::new(|| {
|
HttpServer::new(|| {
|
||||||
App::new()
|
App::new()
|
||||||
|
.service(register)
|
||||||
.service(login)
|
.service(login)
|
||||||
.service(list_photos)
|
.service(list_photos)
|
||||||
.service(register)
|
|
||||||
.service(image)
|
.service(image)
|
||||||
|
.service(generate_video)
|
||||||
|
.service(stream_video)
|
||||||
|
.service(get_video_part)
|
||||||
})
|
})
|
||||||
.bind("127.0.0.1:8088")?
|
.bind("192.168.10.23:8088")?
|
||||||
|
.bind("localhost:8088")?
|
||||||
.run()
|
.run()
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|||||||
24
src/video.rs
Normal file
24
src/video.rs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
// ffmpeg -i test.mp4 -c:v h264 -flags +cgop -g 30 -hls_time 3 out.m3u8
|
||||||
|
|
||||||
|
pub fn create_playlist(video_path: &str, playlist_file: &str) {
|
||||||
|
let result = Command::new("ffmpeg")
|
||||||
|
.arg("-i")
|
||||||
|
.arg(video_path)
|
||||||
|
.arg("-c:v")
|
||||||
|
.arg("h264")
|
||||||
|
.arg("-flags")
|
||||||
|
.arg("+cgop")
|
||||||
|
.arg("-g")
|
||||||
|
.arg("30")
|
||||||
|
.arg("-hls_time")
|
||||||
|
.arg("5")
|
||||||
|
.arg(playlist_file)
|
||||||
|
.output()
|
||||||
|
.expect("Expected this to work..");
|
||||||
|
|
||||||
|
println!("{:?}", result);
|
||||||
|
println!("Status: {}", String::from_utf8(result.stdout).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user