feat: enhance Jellyfin stream URL generation and improve NumberInput component

This commit is contained in:
2026-03-11 19:44:48 +01:00
parent 8d8d320a02
commit c9aa36bb5f
2 changed files with 15 additions and 8 deletions

View File

@@ -153,13 +153,15 @@ impl IMediaProvider for JellyfinMediaProvider {
Ok(body.items.into_iter().next().and_then(map_jellyfin_item)) Ok(body.items.into_iter().next().and_then(map_jellyfin_item))
} }
/// Build a direct-play stream URL for a Jellyfin item. /// Build a stream URL for a Jellyfin item.
/// ///
/// Uses `static=true` to request the original file without transcoding. /// Requests H.264 video + AAC audio in an MP4 container so that all
/// The API key is embedded in the URL so the player does not need separate auth. /// major browsers can play it natively. Jellyfin will direct-play if the
/// source already matches; otherwise it transcodes on the fly.
/// The API key is embedded in the URL so the player needs no separate auth.
async fn get_stream_url(&self, item_id: &MediaItemId) -> DomainResult<String> { async fn get_stream_url(&self, item_id: &MediaItemId) -> DomainResult<String> {
Ok(format!( Ok(format!(
"{}/Videos/{}/stream?static=true&api_key={}", "{}/Videos/{}/stream?videoCodec=h264&audioCodec=aac&container=mp4&api_key={}",
self.config.base_url, self.config.base_url,
item_id.as_ref(), item_id.as_ref(),
self.config.api_key, self.config.api_key,

View File

@@ -66,12 +66,14 @@ function NumberInput({
onChange, onChange,
min, min,
max, max,
step,
placeholder, placeholder,
}: { }: {
value: number | ""; value: number | "";
onChange: (v: number | "") => void; onChange: (v: number | "") => void;
min?: number; min?: number;
max?: number; max?: number;
step?: number | "any";
placeholder?: string; placeholder?: string;
}) { }) {
return ( return (
@@ -79,6 +81,7 @@ function NumberInput({
type="number" type="number"
min={min} min={min}
max={max} max={max}
step={step}
value={value} value={value}
placeholder={placeholder} placeholder={placeholder}
onChange={(e) => onChange={(e) =>
@@ -229,11 +232,12 @@ function BlockEditor({ block, onChange, onRemove }: BlockEditorProps) {
</div> </div>
<div className="grid grid-cols-2 gap-3"> <div className="grid grid-cols-2 gap-3">
<Field label="Start time" hint="24-hour format HH:MM"> <Field label="Start time">
<TextInput <input
type="time"
value={block.start_time.slice(0, 5)} value={block.start_time.slice(0, 5)}
onChange={(v) => setField("start_time", v + ":00")} onChange={(e) => setField("start_time", e.target.value + ":00")}
placeholder="20:00" className="w-full rounded-md border border-zinc-700 bg-zinc-800 px-3 py-2 text-sm text-zinc-100 focus:border-zinc-500 focus:outline-none"
/> />
</Field> </Field>
<Field label="Duration (minutes)"> <Field label="Duration (minutes)">
@@ -443,6 +447,7 @@ function RecyclePolicyEditor({ policy, onChange }: RecyclePolicyEditorProps) {
} }
min={0} min={0}
max={1} max={1}
step={0.01}
placeholder="0.1" placeholder="0.1"
/> />
</Field> </Field>