Instrument video probe with raw-value metrics for bitrate/HDR validation

This commit is contained in:
vineyardbovines
2026-06-25 18:10:11 -04:00
parent 3f2c106ecb
commit 127d0288b4
4 changed files with 56 additions and 4 deletions
+17
View File
@@ -252,6 +252,23 @@ export type Events = {
'composer:image:edit': {
platform: Platform['OS']
}
'composer:video:probe': {
mimeType: string
codec: string
width: number
height: number
duration: number
bitrate: number
fileSize: number
hasAudio: boolean
frameRate: number
rotation: number
isHDR: boolean
wouldCompress: boolean
}
'composer:video:probeFailed': {
safeMessage: string
}
'composerPrompt:press': {}
'composerPrompt:camera:press': {}
'composerPrompt:gallery:press': {}
+12 -2
View File
@@ -6,7 +6,11 @@ import {
VIDEO_MAX_SIZE,
} from '#/lib/constants'
import {logger} from '#/logger'
import {compress, probe} from '../../../../modules/expo-bluesky-video-compress'
import {
compress,
probe,
type VideoMetadata,
} from '../../../../modules/expo-bluesky-video-compress'
import {
COMPRESSION_MAX_DIMENSION,
COMPRESSION_PASSTHROUGH_BITRATE,
@@ -19,6 +23,8 @@ export async function compressVideo(
opts?: {
signal?: AbortSignal
onProgress?: (progress: number) => void
onProbe?: (metadata: VideoMetadata, wouldCompress: boolean) => void
onProbeFailed?: (error: unknown) => void
},
): Promise<CompressedVideo> {
if (file.mimeType === 'image/gif') {
@@ -36,6 +42,7 @@ export async function compressVideo(
logger.debug('probe failed, falling through to passthrough', {
safeMessage: e,
})
opts?.onProbeFailed?.(e)
return {
uri: file.uri,
size: file.fileSize ?? -1,
@@ -43,7 +50,10 @@ export async function compressVideo(
}
}
if (!shouldCompress(metadata, isAcceptableFormat)) {
const willCompress = shouldCompress(metadata, isAcceptableFormat)
opts?.onProbe?.(metadata, willCompress)
if (!willCompress) {
return {
uri: file.uri,
size: metadata.fileSize,
+4 -2
View File
@@ -412,9 +412,10 @@ export const ComposePost = ({
currentDid,
abortController.signal,
i18n,
ax.metric,
)
},
[i18n, agent, currentDid, composerDispatch],
[i18n, agent, currentDid, composerDispatch, ax.metric],
)
const onInitVideo = useNonReactiveCallback(() => {
@@ -559,6 +560,7 @@ export const ComposePost = ({
currentDid,
abortController.signal,
i18n,
ax.metric,
)
} catch (e) {
logger.error('Failed to restore video from draft', {
@@ -567,7 +569,7 @@ export const ComposePost = ({
})
}
},
[i18n, agent, currentDid, composerDispatch],
[i18n, agent, currentDid, composerDispatch, ax.metric],
)
const handleSelectDraft = useCallback(
+23
View File
@@ -16,6 +16,7 @@ import {uploadVideo} from '#/lib/media/video/upload'
import {createVideoAgent} from '#/lib/media/video/util'
import {isNetworkError} from '#/lib/strings/errors'
import {logger} from '#/logger'
import {type AnalyticsContextType} from '#/analytics'
type CaptionsTrack = {lang: string; file: File}
@@ -265,6 +266,7 @@ export async function processVideo(
did: string,
signal: AbortSignal,
i18n: I18n,
metric: AnalyticsContextType['metric'],
) {
let video: CompressedVideo | undefined
try {
@@ -273,6 +275,27 @@ export async function processVideo(
dispatch({type: 'update_progress', progress: trunc2dp(num), signal})
},
signal,
onProbe: (metadata, wouldCompress) => {
metric('composer:video:probe', {
mimeType: metadata.mimeType,
codec: metadata.codec,
width: metadata.width,
height: metadata.height,
duration: metadata.duration,
bitrate: metadata.bitrate,
fileSize: metadata.fileSize,
hasAudio: metadata.hasAudio,
frameRate: metadata.frameRate,
rotation: metadata.rotation,
isHDR: metadata.isHDR,
wouldCompress,
})
},
onProbeFailed: e => {
metric('composer:video:probeFailed', {
safeMessage: e instanceof Error ? e.message : String(e),
})
},
})
} catch (e) {
const message = getCompressErrorMessage(e, i18n)