Skip to content

Commit e696124

Browse files
committed
feat: update flag parsing and add HLS and Dash generation
1 parent a2e3f81 commit e696124

File tree

3 files changed

+152
-12
lines changed

3 files changed

+152
-12
lines changed

src/ffmpeg.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::{fs, process::Command};
2+
3+
fn run_command(command: &str) {
4+
let cmd = Command::new("sh")
5+
.arg("-c")
6+
.arg(command)
7+
.output()
8+
.expect("Error");
9+
10+
println!("status: {}", cmd.status);
11+
12+
println!("stdout: {}", String::from_utf8_lossy(&cmd.stdout));
13+
14+
println!("stderr: {}", String::from_utf8_lossy(&cmd.stderr));
15+
16+
let result = String::from_utf8_lossy(&cmd.stdout);
17+
let result = result.to_string();
18+
let result = result.as_str();
19+
20+
println!("{}", result);
21+
}
22+
23+
// fn create_preview_image() {}
24+
25+
// fn create_preview_gif() {}
26+
27+
pub fn create_thumbnails(input: String, output: String) {
28+
println!("\ncreate_thumbnails");
29+
30+
let thumbs_path = format!("{}/thumbs", output);
31+
32+
println!("Path: {}", thumbs_path);
33+
if !fs::metadata(&thumbs_path).is_ok() {
34+
fs::create_dir_all(&thumbs_path).unwrap();
35+
}
36+
37+
let command = format!(
38+
"ffmpeg -i {} -vf \"fps=1/4,scale=320:-1\" {}/img%03d.jpg",
39+
input, thumbs_path
40+
);
41+
42+
run_command(&command);
43+
}
44+
45+
pub fn create_hls_encoding(input: String, output: String) {
46+
println!("\npub create_hls_encoding");
47+
48+
if !fs::metadata(&output).is_ok() {
49+
fs::create_dir_all(&output).unwrap();
50+
}
51+
52+
// TODO: Sub add paths
53+
// let paths = ["hls", "dash"];
54+
// for path in paths {
55+
// let p = format!("{}/{}", path, output);
56+
// if !fs::metadata(&p).is_ok() {
57+
// fs::create_dir_all(&p).unwrap();
58+
// }
59+
// }
60+
61+
let command = format!("ffmpeg -stream_loop 0 -i {} \
62+
-map 0 -map 0 -map 0 -c:a aac -c:v h264_videotoolbox -allow_sw 1 \
63+
-b:v:0 800k -s:v:0 1280x720 -profile:v:0 main \
64+
-b:v:1 500k -s:v:1 640x340 -profile:v:1 main \
65+
-b:v:2 300k -s:v:2 320x170 -profile:v:2 baseline \
66+
-bf 1 \
67+
-keyint_min 120 -g 120 -sc_threshold 0 -b_strategy 0 -ar:a:1 22050 -use_timeline 1 -use_template 1 \
68+
-window_size 0 -adaptation_sets \"id=0,streams=v id=1,streams=a\" -hls_playlist 1 -seg_duration 4 \
69+
-streaming 0 -f dash \
70+
-hls_segment_filename \
71+
-hls_playlist_type {}/vod \
72+
{}/720p_%03d.m3u8 {}/720p.m3u8", input, output, output, output);
73+
run_command(&command);
74+
}

src/fileio.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ use std::fs;
33
use std::fs::File;
44
use std::io::Write;
55

6-
fn file_to_hyphen(name: &String) -> String {
6+
pub fn file_to_hyphen(name: &String) -> String {
77
return String::from(name.replace("_", "-").replace(" ", "-").replace(".", "-"));
88
}
99

10-
pub fn write_metadata(data: OutputMetadata) {
10+
pub fn write_metadata(data: &OutputMetadata) {
1111
let directory = file_to_hyphen(&data.title);
1212

1313
if !fs::metadata(&directory).is_ok() {

src/main.rs

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,50 @@
11
use clap::{App, Arg};
22
use std::process;
33

4+
enum Flags {
5+
_Gif,
6+
HLS,
7+
_Metadata,
8+
_PreviewImage,
9+
Thumbnails,
10+
}
11+
12+
// impl fmt::Display for Flags {
13+
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14+
// match self {
15+
// Flags::_Gif => write!(f, "gif"),
16+
// Flags::HLS => write!(f, "HLS"),
17+
// Flags::_Metadata => write!(f, "metadata"),
18+
// Flags::_PreviewImage => write!(f, "preview_image"),
19+
// Flags::Thumbnails => write!(f, "thumbs"),
20+
// }
21+
// }
22+
// }
23+
24+
impl ToString for Flags {
25+
fn to_string(&self) -> String {
26+
self.as_str().to_string()
27+
}
28+
}
29+
30+
impl Flags {
31+
fn as_str(&self) -> &'static str {
32+
match self {
33+
Flags::_Gif => "gif",
34+
Flags::HLS => "HLS",
35+
Flags::_Metadata => "metadata",
36+
Flags::_PreviewImage => "preview_image",
37+
Flags::Thumbnails => "thumbs",
38+
}
39+
}
40+
}
41+
42+
use crate::{
43+
ffmpeg::{create_hls_encoding, create_thumbnails},
44+
fileio::file_to_hyphen,
45+
};
46+
47+
mod ffmpeg;
448
mod fileio;
549
mod media_info;
650
mod metadata;
@@ -15,23 +59,45 @@ fn main() {
1559
.short('i')
1660
.long("input")
1761
.value_name("FILE")
18-
.help("Sets the input file to use")
19-
.takes_value(true),
62+
.help("Sets the input file to use"),
63+
)
64+
.arg(
65+
Arg::with_name(Flags::Thumbnails.as_str())
66+
.short('t')
67+
.long(Flags::Thumbnails.as_str())
68+
.help("Generate thumbnails")
69+
.takes_value(false),
70+
)
71+
.arg(
72+
Arg::with_name(Flags::HLS.as_str())
73+
.short('h')
74+
.long(Flags::HLS.as_str())
75+
.help("Generate hls chunks")
76+
.takes_value(false),
2077
)
2178
.get_matches();
2279

2380
let input = matches.value_of("input").unwrap_or("help");
24-
// println!("Input file: {}", input);
25-
2681
if input == "help" {
2782
println!("Usage: <TODO>");
28-
2983
process::exit(1);
3084
}
3185

3286
let out = media_info::get_media_info(&input);
33-
println!("{:#?}", out);
34-
fileio::write_metadata(out);
87+
println!("{:#?}", &out);
88+
fileio::write_metadata(&out);
89+
90+
let path = format!("./{}", file_to_hyphen(&out.title));
91+
92+
let gen_thumbs = matches.is_present(Flags::Thumbnails.as_str());
93+
if gen_thumbs {
94+
create_thumbnails(out.file_name.clone(), path.clone());
95+
}
96+
97+
let gen_hls = matches.is_present(Flags::HLS.as_str());
98+
if gen_hls {
99+
create_hls_encoding(out.file_name.clone(), path.clone());
100+
}
35101

36102
/*
37103
TODO:
@@ -42,11 +108,11 @@ fn main() {
42108
[x] Store Metadata in JSON
43109
44110
[ ] FFMPEG to generate media
45-
[ ] thumbnails
111+
[x] thumbnails
46112
[ ] gif
47113
[ ] preview image
48-
[ ] HLS
49-
[ ] DASH
114+
[x] HLS
115+
[x] DASH
50116
[ ] Metadata
51117
[ ] Upload metadata to database
52118

0 commit comments

Comments
 (0)