From 3bed1b6131e4e3a4439ada1eba7983c9db60a8af Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 25 Feb 2026 15:58:53 -0600 Subject: [PATCH] fix: consider DAR when extracting video dimension (#25293) * feat: consider DAR when extracting video dimension * move to probe * comment --------- Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com> --- server/src/repositories/media.repository.ts | 48 +++++++++++++-------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/server/src/repositories/media.repository.ts b/server/src/repositories/media.repository.ts index e3e78b3238..7b0b30583d 100644 --- a/server/src/repositories/media.repository.ts +++ b/server/src/repositories/media.repository.ts @@ -243,23 +243,26 @@ export class MediaRepository { bitrate: this.parseInt(results.format.bit_rate), }, videoStreams: results.streams - .filter((stream) => stream.codec_type === 'video') - .filter((stream) => !stream.disposition?.attached_pic) - .map((stream) => ({ - index: stream.index, - height: this.parseInt(stream.height), - width: this.parseInt(stream.width), - codecName: stream.codec_name === 'h265' ? 'hevc' : stream.codec_name, - codecType: stream.codec_type, - frameCount: this.parseInt(options?.countFrames ? stream.nb_read_packets : stream.nb_frames), - rotation: this.parseInt(stream.rotation), - isHDR: stream.color_transfer === 'smpte2084' || stream.color_transfer === 'arib-std-b67', - bitrate: this.parseInt(stream.bit_rate), - pixelFormat: stream.pix_fmt || 'yuv420p', - colorPrimaries: stream.color_primaries, - colorSpace: stream.color_space, - colorTransfer: stream.color_transfer, - })), + .filter((stream) => stream.codec_type === 'video' && !stream.disposition?.attached_pic) + .map((stream) => { + const height = this.parseInt(stream.height); + const dar = this.getDar(stream.display_aspect_ratio); + return { + index: stream.index, + height, + width: dar ? Math.round(height * dar) : this.parseInt(stream.width), + codecName: stream.codec_name === 'h265' ? 'hevc' : stream.codec_name, + codecType: stream.codec_type, + frameCount: this.parseInt(options?.countFrames ? stream.nb_read_packets : stream.nb_frames), + rotation: this.parseInt(stream.rotation), + isHDR: stream.color_transfer === 'smpte2084' || stream.color_transfer === 'arib-std-b67', + bitrate: this.parseInt(stream.bit_rate), + pixelFormat: stream.pix_fmt || 'yuv420p', + colorPrimaries: stream.color_primaries, + colorSpace: stream.color_space, + colorTransfer: stream.color_transfer, + }; + }), audioStreams: results.streams .filter((stream) => stream.codec_type === 'audio') .map((stream) => ({ @@ -352,4 +355,15 @@ export class MediaRepository { private parseFloat(value: string | number | undefined): number { return Number.parseFloat(value as string) || 0; } + + private getDar(dar: string | undefined): number { + if (dar) { + const [darW, darH] = dar.split(':').map(Number); + if (darW && darH) { + return darW / darH; + } + } + + return 0; + } }