Manually burn-in subtitles only if no pre-burned video is available (#268)

This commit is contained in:
bytedream 2023-11-19 19:24:15 +01:00
parent 14e71c05b8
commit 2c37093959
5 changed files with 88 additions and 14 deletions

View file

@ -2,6 +2,8 @@ use lazy_static::lazy_static;
use regex::Regex;
use std::str::FromStr;
pub const SOFTSUB_CONTAINERS: [&str; 3] = ["mkv", "mov", "mp4"];
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum FFmpegPreset {
Predefined(FFmpegCodec, Option<FFmpegHwAccel>, FFmpegQuality),

View file

@ -172,6 +172,10 @@ impl SingleFormat {
pub fn is_episode(&self) -> bool {
matches!(self.source, MediaCollection::Episode(_))
}
pub fn is_special(&self) -> bool {
self.sequence_number == 0.0 || self.sequence_number.fract() != 0.0
}
}
struct SingleFormatCollectionEpisodeKey(f32);

View file

@ -1,32 +1,47 @@
use anyhow::Result;
use anyhow::{bail, Result};
use crunchyroll_rs::media::{Resolution, Stream, VariantData};
use crunchyroll_rs::Locale;
pub async fn variant_data_from_stream(
stream: &Stream,
resolution: &Resolution,
) -> Result<Option<(VariantData, VariantData)>> {
subtitle: Option<Locale>,
) -> Result<Option<(VariantData, VariantData, bool)>> {
// sometimes Crunchyroll marks episodes without real subtitles that they have subtitles and
// reports that only hardsub episode are existing. the following lines are trying to prevent
// potential errors which might get caused by this incorrect reporting
// (https://github.com/crunchy-labs/crunchy-cli/issues/231)
let mut hardsub_locales = stream.streaming_hardsub_locales();
let hardsub_locale = if !hardsub_locales.contains(&Locale::Custom("".to_string()))
let (hardsub_locale, mut contains_hardsub) = if !hardsub_locales
.contains(&Locale::Custom("".to_string()))
&& !hardsub_locales.contains(&Locale::Custom(":".to_string()))
{
// if only one hardsub locale exists, assume that this stream doesn't really contains hardsubs
if hardsub_locales.len() == 1 {
Some(hardsub_locales.remove(0))
(Some(hardsub_locales.remove(0)), false)
} else {
// fallback to `None`. this should trigger an error message in `stream.dash_streaming_data`
// that the requested stream is not available
None
(None, false)
}
} else {
None
let hardsubs_requested = subtitle.is_some();
(subtitle, hardsubs_requested)
};
let mut streaming_data = stream.dash_streaming_data(hardsub_locale).await?;
let mut streaming_data = match stream.dash_streaming_data(hardsub_locale).await {
Ok(data) => data,
Err(e) => {
// the error variant is only `crunchyroll_rs::error::Error::Input` when the requested
// hardsub is not available
if let crunchyroll_rs::error::Error::Input { .. } = e {
contains_hardsub = false;
stream.dash_streaming_data(None).await?
} else {
bail!(e)
}
}
};
streaming_data
.0
.sort_by(|a, b| a.bandwidth.cmp(&b.bandwidth).reverse());
@ -42,5 +57,11 @@ pub async fn variant_data_from_stream(
.into_iter()
.find(|v| resolution.height == v.resolution.height),
};
Ok(video_variant.map(|v| (v, streaming_data.1.first().unwrap().clone())))
Ok(video_variant.map(|v| {
(
v,
streaming_data.1.first().unwrap().clone(),
contains_hardsub,
)
}))
}