Create simple playlist generator
This commit is contained in:
parent
bde7ead3b6
commit
322d988c0a
6 changed files with 139 additions and 1 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -1139,6 +1139,15 @@ dependencies = [
|
||||||
"symphonia",
|
"symphonia",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mps-m3u8"
|
||||||
|
version = "0.4.0"
|
||||||
|
dependencies = [
|
||||||
|
"clap 3.0.12",
|
||||||
|
"m3u8-rs",
|
||||||
|
"mps-interpreter",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mps-player"
|
name = "mps-player"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -13,7 +13,8 @@ exclude = ["extras/"]
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"mps-interpreter",
|
"mps-interpreter",
|
||||||
"mps-player"
|
"mps-player",
|
||||||
|
"mps-m3u8"
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
19
mps-m3u8/Cargo.toml
Normal file
19
mps-m3u8/Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "mps-m3u8"
|
||||||
|
version = "0.4.0"
|
||||||
|
edition = "2021"
|
||||||
|
authors = ["NGnius <ngniusness@gmail.com>"]
|
||||||
|
description = "Minimal playlist generator for MPS files"
|
||||||
|
license = "LGPL-2.1-only OR GPL-2.0-or-later"
|
||||||
|
repository = "https://github.com/NGnius/mps"
|
||||||
|
keywords = ["audio", "playlist", "scripting", "language"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
# local
|
||||||
|
mps-interpreter = { version = "0.4.0", path = "../mps-interpreter" }
|
||||||
|
# external
|
||||||
|
clap = { version = "3.0", features = ["derive"] }
|
||||||
|
m3u8-rs = { version = "^3.0.0" }
|
8
mps-m3u8/README.md
Normal file
8
mps-m3u8/README.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# mps-m3u8
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
License: LGPL-2.1-only OR GPL-2.0-or-later
|
20
mps-m3u8/src/cli.rs
Normal file
20
mps-m3u8/src/cli.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
use clap::Parser;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[clap(author, version)]
|
||||||
|
#[clap(about = "MPS m3u8 generator")]
|
||||||
|
pub struct CliArgs {
|
||||||
|
/// Input MPS file
|
||||||
|
pub input: String,
|
||||||
|
|
||||||
|
/// Output m3u8 playlist
|
||||||
|
pub playlist: String,
|
||||||
|
|
||||||
|
/// Parse input as MPS instead of as filename
|
||||||
|
#[clap(long)]
|
||||||
|
pub raw: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse() -> CliArgs {
|
||||||
|
CliArgs::parse()
|
||||||
|
}
|
81
mps-m3u8/src/main.rs
Normal file
81
mps-m3u8/src/main.rs
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
//! 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::path::Path;
|
||||||
|
use std::io::{BufReader, BufWriter, Cursor};
|
||||||
|
|
||||||
|
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) =
|
||||||
|
music.field("filename").and_then(|x| x.to_owned().to_str())
|
||||||
|
{
|
||||||
|
playlist.segments.push(MediaSegment {
|
||||||
|
uri: filename,
|
||||||
|
title: music.field("title").and_then(|x| x.to_owned().to_str()),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
skipped_count += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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) =
|
||||||
|
music.field("filename").and_then(|x| x.to_owned().to_str())
|
||||||
|
{
|
||||||
|
playlist.segments.push(MediaSegment {
|
||||||
|
uri: filename,
|
||||||
|
title: music.field("title").and_then(|x| x.to_owned().to_str()),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
skipped_count += 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => eprintln!("{}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if skipped_count != 0 {
|
||||||
|
eprintln!("Skipped {} items due to missing `filename` field", skipped_count);
|
||||||
|
}
|
||||||
|
if let Err(e) = playlist.write_to(&mut out_file) {
|
||||||
|
eprintln!("Playlist save error: {}", e);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue