2022-01-28 19:32:52 +00:00
|
|
|
//! Minimal CLI tool to generate a m3u8 playlist from a MPS file.
|
|
|
|
//! This does not support playback, so it can run on any platform with a filesystem.
|
|
|
|
//! Use `mps-m3u8 --help` for usage instructions.
|
|
|
|
//!
|
|
|
|
|
|
|
|
mod cli;
|
|
|
|
|
|
|
|
use std::fs::File;
|
|
|
|
use std::io::{BufReader, BufWriter, Cursor};
|
2022-01-31 14:22:36 +00:00
|
|
|
use std::path::Path;
|
2022-01-28 19:32:52 +00:00
|
|
|
|
|
|
|
use m3u8_rs::{MediaPlaylist, MediaSegment};
|
|
|
|
|
|
|
|
use mps_interpreter::MpsRunner;
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let args = cli::parse();
|
|
|
|
|
|
|
|
let out_path = Path::new(&args.playlist);
|
|
|
|
let mut out_file = BufWriter::new(File::create(out_path).expect("Invalid output file"));
|
|
|
|
|
|
|
|
let mut playlist = MediaPlaylist {
|
|
|
|
version: 6,
|
|
|
|
..Default::default()
|
|
|
|
};
|
|
|
|
let mut skipped_count = 0;
|
|
|
|
|
|
|
|
if args.raw {
|
|
|
|
println!("Executing: {}", &args.input);
|
|
|
|
let in_file = Cursor::new(&args.input);
|
|
|
|
|
|
|
|
let runner = MpsRunner::with_stream(in_file);
|
|
|
|
for item in runner {
|
|
|
|
match item {
|
|
|
|
Ok(music) => {
|
|
|
|
if let Some(filename) =
|
2022-01-31 14:22:36 +00:00
|
|
|
music.field("filename").and_then(|x| x.to_owned().to_str())
|
2022-01-28 19:32:52 +00:00
|
|
|
{
|
|
|
|
playlist.segments.push(MediaSegment {
|
|
|
|
uri: filename,
|
|
|
|
title: music.field("title").and_then(|x| x.to_owned().to_str()),
|
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
skipped_count += 1;
|
|
|
|
}
|
2022-01-31 14:22:36 +00:00
|
|
|
}
|
2022-01-28 19:32:52 +00:00
|
|
|
Err(e) => eprintln!("{}", e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let in_path = Path::new(&args.input);
|
|
|
|
let in_file = BufReader::new(File::open(in_path).expect("Invalid/missing input file"));
|
|
|
|
|
|
|
|
let runner = MpsRunner::with_stream(in_file);
|
|
|
|
for item in runner {
|
|
|
|
match item {
|
|
|
|
Ok(music) => {
|
|
|
|
if let Some(filename) =
|
2022-01-31 14:22:36 +00:00
|
|
|
music.field("filename").and_then(|x| x.to_owned().to_str())
|
2022-01-28 19:32:52 +00:00
|
|
|
{
|
|
|
|
playlist.segments.push(MediaSegment {
|
|
|
|
uri: filename,
|
|
|
|
title: music.field("title").and_then(|x| x.to_owned().to_str()),
|
|
|
|
..Default::default()
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
skipped_count += 1;
|
|
|
|
}
|
2022-01-31 14:22:36 +00:00
|
|
|
}
|
2022-01-28 19:32:52 +00:00
|
|
|
Err(e) => eprintln!("{}", e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if skipped_count != 0 {
|
2022-01-31 14:22:36 +00:00
|
|
|
eprintln!(
|
|
|
|
"Skipped {} items due to missing `filename` field",
|
|
|
|
skipped_count
|
|
|
|
);
|
2022-01-28 19:32:52 +00:00
|
|
|
}
|
|
|
|
if let Err(e) = playlist.write_to(&mut out_file) {
|
|
|
|
eprintln!("Playlist save error: {}", e);
|
|
|
|
}
|
|
|
|
}
|