Address re-review: AAC re-encode, probe fallthrough, HDR detection

- Android non-AAC audio is now transcoded to AAC (matching iOS) via a
  source-decoder -> AAC-encoder pre-pass that captures the encoder's
  output format before the muxer starts, then writes buffered samples
  after the video pipeline finishes. Falls back to dropping audio if
  the transcode fails.
- compress.ts wraps probe() in try/catch and falls through to
  passthrough on failure instead of throwing.
- Probers expose isHDR (HLG/PQ via color transfer, plus Dolby Vision
  codecs/mimes); shouldCompress forces compression for HDR sources so
  the SDR BT.709 path always runs. Also sets
  KEY_COLOR_TRANSFER_REQUEST=SDR on the Android decoder (API 31+) so
  HDR sources tone-map to SDR pixels instead of being mislabeled.
This commit is contained in:
vineyardbovines
2026-06-20 14:43:57 -04:00
parent 34ee7bafda
commit fd387904d4
5 changed files with 270 additions and 8 deletions
+27 -2
View File
@@ -24,7 +24,19 @@ export async function compressVideo(
file.mimeType as SupportedMimeTypes,
)
const metadata = await probe(file.uri)
let metadata
try {
metadata = await probe(file.uri)
} catch (e) {
logger.debug('probe failed, falling through to passthrough', {
safeMessage: e,
})
return {
uri: file.uri,
size: file.fileSize ?? -1,
mimeType: file.mimeType ?? 'video/mp4',
}
}
if (!shouldCompress(metadata, isAcceptableFormat)) {
return {
@@ -55,7 +67,13 @@ export async function compressVideo(
}
function shouldCompress(
metadata: {bitrate: number; width: number; height: number; fileSize: number},
metadata: {
bitrate: number
width: number
height: number
fileSize: number
isHDR: boolean
},
isAcceptableFormat: boolean,
): boolean {
const maxDimension = Math.max(metadata.width, metadata.height)
@@ -67,6 +85,13 @@ function shouldCompress(
return true
}
// HDR sources need the SDR BT.709 tone-map in the compress path; otherwise we
// would upload HLG/PQ/Dolby Vision untouched.
if (metadata.isHDR) {
logger.debug('shouldCompress: yes (HDR source)')
return true
}
if (metadata.fileSize > MAX_UPLOAD_SIZE) {
logger.debug(`shouldCompress: yes (file too large: ${sizeMB}MB)`)
return true