Plug native video probe into upload telemetry funnel

Adds video:upload:probed event (uploadId/engine + raw container metadata:
bitrate, codec, isHDR, frame rate, rotation, etc.) wired through a new
VideoTelemetry.probed method. compressVideo gains an onProbe opt and fires
it once after the probe call succeeds, before shouldCompress is evaluated.

Renames the native engine label from native:react-native-compressor@1.13.0
to native:expo-bluesky-video-compress@1 so probed events stay paired with
the engine that can actually surface this data; web/mediabunny is unchanged
and will simply never call telemetry.probed().
This commit is contained in:
vineyardbovines
2026-06-25 18:37:15 -04:00
parent c4f93fccd0
commit f4b8651708
4 changed files with 49 additions and 2 deletions
+19
View File
@@ -1352,6 +1352,25 @@ export type Events = {
engine: string
sourceBytes?: number
}
// Native-only. Raw container metadata returned by the new module's probe()
// (bitrate, codec, HDR, frame rate, rotation, etc.). Fires once per upload
// between compressStarted and the compressSkipped/compressCompleted decision.
// The web (mediabunny) and legacy rn-compressor engines do not surface this.
'video:upload:probed': {
uploadId: string
engine: string
mimeType: string
codec: string
width: number
height: number
duration: number
bitrate: number
fileSize: number
hasAudio: boolean
frameRate: number
rotation: number
isHDR: boolean
}
'video:upload:compressCompleted': {
uploadId: string
engine: string
+8 -1
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,7 @@ export async function compressVideo(
opts?: {
signal?: AbortSignal
onProgress?: (progress: number) => void
onProbe?: (metadata: VideoMetadata) => void
},
): Promise<CompressedVideo> {
if (file.mimeType === 'image/gif') {
@@ -49,6 +54,8 @@ export async function compressVideo(
}
}
opts?.onProbe?.(metadata)
if (!shouldCompress(metadata, isAcceptableFormat)) {
return {
uri: file.uri,
+21 -1
View File
@@ -5,6 +5,7 @@ import {nanoid} from 'nanoid/non-secure'
import {type VideoCompressSkipReason} from '#/lib/media/video/types'
import {Sentry} from '#/logger/sentry/lib'
import {type Metrics} from '#/analytics/metrics'
import {type VideoMetadata} from '../../../../modules/expo-bluesky-video-compress'
type MetricFn = <E extends keyof Metrics>(event: E, payload: Metrics[E]) => void
@@ -14,7 +15,7 @@ type MetricFn = <E extends keyof Metrics>(event: E, payload: Metrics[E]) => void
const COMPRESS_ENGINE =
Platform.OS === 'web'
? 'web:mediabunny@1.25.3'
: 'native:react-native-compressor@1.13.0'
: 'native:expo-bluesky-video-compress@1'
type Phase = 'compress' | 'upload' | 'processing'
@@ -28,6 +29,7 @@ export type VideoTelemetry = {
readonly engine: string
picked: () => void
compressStarted: () => void
probed: (metadata: VideoMetadata) => void
compressSkipped: (video: {
size: number
mimeType: string
@@ -155,6 +157,24 @@ export function createVideoTelemetry({
})
},
probed(metadata) {
metric('video:upload:probed', {
uploadId,
engine,
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,
})
},
compressSkipped({size, mimeType, skipReason}) {
metric('video:upload:compressSkipped', {
uploadId,
+1
View File
@@ -288,6 +288,7 @@ export async function processVideo(
dispatch({type: 'update_progress', progress: trunc2dp(num), signal})
},
signal,
onProbe: metadata => telemetry.probed(metadata),
})
} catch (e) {
const message = getCompressErrorMessage(e, i18n)