Fix subrip extraction

This commit is contained in:
Zoe Roux 2023-08-01 01:42:55 +09:00
parent 7b56924466
commit 0f59798e73
2 changed files with 26 additions and 15 deletions

View File

@ -34,7 +34,7 @@ import { AudiosMenu, QualitiesMenu } from "../video";
import i18next from "i18next"; import i18next from "i18next";
export const getDisplayName = (sub: Subtitle) => { export const getDisplayName = (sub: Subtitle) => {
const languageNames = new Intl.DisplayNames([i18next.language], { type: "language" }); const languageNames = new Intl.DisplayNames([i18next.language ?? "en"], { type: "language" });
const lng = sub.language ? languageNames.of(sub.language) : undefined; const lng = sub.language ? languageNames.of(sub.language) : undefined;
if (lng && sub.title) return `${lng} - ${sub.title}`; if (lng && sub.title) return `${lng} - ${sub.title}`;

View File

@ -2,7 +2,9 @@ use json::JsonValue;
use serde::Serialize; use serde::Serialize;
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
use std::{ use std::{
collections::HashMap,
fs, io, fs, io,
iter::Map,
path::PathBuf, path::PathBuf,
process::Stdio, process::Stdio,
str::{self, FromStr}, str::{self, FromStr},
@ -75,6 +77,8 @@ pub struct Subtitle {
pub language: Option<String>, pub language: Option<String>,
/// The codec of this stream. /// The codec of this stream.
pub codec: String, pub codec: String,
/// The extension for the codec.
pub extension: Option<String>,
/// Is this stream the default one of it's type? /// Is this stream the default one of it's type?
pub is_default: bool, pub is_default: bool,
/// Is this stream tagged as forced? (useful only for subtitles) /// Is this stream tagged as forced? (useful only for subtitles)
@ -100,19 +104,16 @@ async fn extract(path: String, sha: &String, subs: &Vec<Subtitle>) {
.args(&["-dump_attachment:t", ""]) .args(&["-dump_attachment:t", ""])
.args(&["-i", path.as_str()]); .args(&["-i", path.as_str()]);
for sub in subs { for sub in subs {
if let Some(ext) = sub.extension.clone() {
cmd.args(&[ cmd.args(&[
"-map", "-map",
format!("0:s:{idx}", idx = sub.index).as_str(), format!("0:s:{idx}", idx = sub.index).as_str(),
"-c:s", "-c:s",
"copy", "copy",
format!( format!("/metadata/{sha}/sub/{idx}.{ext}", idx = sub.index,).as_str(),
"/metadata/{sha}/sub/{idx}.{ext}",
idx = sub.index,
ext = sub.codec
)
.as_str(),
]); ]);
} }
}
println!("Starting extraction with the command: {:?}", cmd); println!("Starting extraction with the command: {:?}", cmd);
cmd.stdout(Stdio::null()) cmd.stdout(Stdio::null())
.spawn() .spawn()
@ -123,6 +124,8 @@ async fn extract(path: String, sha: &String, subs: &Vec<Subtitle>) {
} }
pub async fn identify(path: String) -> Result<MediaInfo, std::io::Error> { pub async fn identify(path: String) -> Result<MediaInfo, std::io::Error> {
let extension_table: HashMap<&str, &str> = HashMap::from([("subrip", "srt"), ("ass", "ass")]);
let mediainfo = Command::new("mediainfo") let mediainfo = Command::new("mediainfo")
.arg("--Output=JSON") .arg("--Output=JSON")
.arg("--Language=raw") .arg("--Language=raw")
@ -148,13 +151,21 @@ pub async fn identify(path: String) -> Result<MediaInfo, std::io::Error> {
.filter(|x| x["@type"] == "Text") .filter(|x| x["@type"] == "Text")
.map(|a| { .map(|a| {
let index = parse::<u32>(&a["@typeorder"]).unwrap() - 1; let index = parse::<u32>(&a["@typeorder"]).unwrap() - 1;
let codec = a["Format"].as_str().unwrap().to_string().to_lowercase(); let mut codec = a["Format"].as_str().unwrap().to_string().to_lowercase();
if codec == "utf-8" {
codec = "subrip".to_string();
}
let extension = extension_table.get(codec.as_str()).map(|x| x.to_string());
Subtitle { Subtitle {
link: format!("/video/{sha}/subtitle/{index}.{codec}"), link: format!(
"/video/{sha}/subtitle/{index}.{ext}",
ext = extension.clone().unwrap_or(codec.clone())
),
index, index,
title: a["Title"].as_str().map(|x| x.to_string()), title: a["Title"].as_str().map(|x| x.to_string()),
language: a["Language"].as_str().map(|x| x.to_string()), language: a["Language"].as_str().map(|x| x.to_string()),
codec, codec,
extension,
is_default: a["Default"] == "Yes", is_default: a["Default"] == "Yes",
is_forced: a["Forced"] == "No", is_forced: a["Forced"] == "No",
} }