feat(Media player widget): expands on Direct Play and Transcoding badges (#6489)
This commit is contained in:
1 parent
27ca058088
commit
49314533bf
6 files changed
+126
-21
No files matched your search
@@ -41,7 +41,11 @@ export interface StreamSession {
|
||||
audioCodec: string | null;
|
||||
videoCodec: string | null;
|
||||
};
|
||||
isVideoDirect: boolean;
|
||||
isAudioDirect: boolean;
|
||||
containerChanged: boolean;
|
||||
};
|
||||
bitrateKbps: number | null;
|
||||
} | null;
|
||||
} | null;
|
||||
}
|
||||
|
||||
@@ -56,6 +56,9 @@ export class JellyfinIntegration extends Integration implements IMediaServerInte
|
||||
if (sessionInfo.NowPlayingItem) {
|
||||
const positionMs = ticksToMs(sessionInfo.PlayState?.PositionTicks);
|
||||
const durationMs = ticksToMs(sessionInfo.NowPlayingItem.RunTimeTicks);
|
||||
const bitrateBps =
|
||||
sessionInfo.TranscodingInfo?.Bitrate ?? sessionInfo.NowPlayingItem.MediaSources?.[0]?.Bitrate ?? null;
|
||||
const bitrateKbps = bitrateBps !== null ? Math.round(bitrateBps / 1000) : null;
|
||||
|
||||
currentlyPlaying = {
|
||||
type: convertJellyfinType(sessionInfo.NowPlayingItem.Type),
|
||||
@@ -98,7 +101,11 @@ export class JellyfinIntegration extends Integration implements IMediaServerInte
|
||||
videoCodec: sessionInfo.TranscodingInfo?.VideoCodec ?? null,
|
||||
},
|
||||
container: sessionInfo.TranscodingInfo?.Container ?? null,
|
||||
isVideoDirect: sessionInfo.TranscodingInfo?.IsVideoDirect ?? true,
|
||||
isAudioDirect: sessionInfo.TranscodingInfo?.IsAudioDirect ?? true,
|
||||
containerChanged: sessionInfo.PlayState?.PlayMethod === "DirectStream",
|
||||
},
|
||||
bitrateKbps,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,6 +43,12 @@ function parseResolution(
|
||||
return parsedWidth !== null && parsedHeight !== null ? { width: parsedWidth, height: parsedHeight } : null;
|
||||
}
|
||||
|
||||
function isStreamDirect(decision: string | undefined): boolean {
|
||||
// Plex reports "transcode" when a stream is re-encoded. "copy" (remuxed
|
||||
// without re-encoding) and an absent decision both count as direct.
|
||||
return decision !== "transcode";
|
||||
}
|
||||
|
||||
export class PlexIntegration extends Integration implements IMediaServerIntegration, IMediaReleasesIntegration {
|
||||
public async getCurrentSessionsAsync(_options: CurrentSessionsInput): Promise<StreamSession[]> {
|
||||
const token = super.getSecretValue("apiKey");
|
||||
@@ -87,6 +93,16 @@ export class PlexIntegration extends Integration implements IMediaServerIntegrat
|
||||
const videoStream = streams.find((stream) => stream.$.streamType === "1");
|
||||
const audioStream = streams.find((stream) => stream.$.streamType === "2");
|
||||
|
||||
const isVideoDirect = isStreamDirect(transcodeElement?.$.videoDecision);
|
||||
const isAudioDirect = isStreamDirect(transcodeElement?.$.audioDecision);
|
||||
const containerChanged = Boolean(
|
||||
transcodeElement?.$.container &&
|
||||
mediaInfoElement?.$.container &&
|
||||
transcodeElement.$.container !== mediaInfoElement.$.container,
|
||||
);
|
||||
const bitrateKbps =
|
||||
parseOptionalNumber(sessionElement?.$.bandwidth) ?? parseOptionalNumber(mediaInfoElement?.$.bitrate);
|
||||
|
||||
return {
|
||||
sessionId: sessionElement?.$.id ?? "unknown",
|
||||
sessionName: `${playerElement.$.product} (${playerElement.$.title})`,
|
||||
@@ -124,7 +140,11 @@ export class PlexIntegration extends Integration implements IMediaServerIntegrat
|
||||
audioCodec: transcodeElement?.$.audioCodec ?? null,
|
||||
videoCodec: transcodeElement?.$.videoCodec ?? null,
|
||||
},
|
||||
isVideoDirect,
|
||||
isAudioDirect,
|
||||
containerChanged,
|
||||
},
|
||||
bitrateKbps,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user