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:
@@ -1352,6 +1352,25 @@ export type Events = {
|
|||||||
engine: string
|
engine: string
|
||||||
sourceBytes?: number
|
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': {
|
'video:upload:compressCompleted': {
|
||||||
uploadId: string
|
uploadId: string
|
||||||
engine: string
|
engine: string
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import {
|
|||||||
VIDEO_MAX_SIZE,
|
VIDEO_MAX_SIZE,
|
||||||
} from '#/lib/constants'
|
} from '#/lib/constants'
|
||||||
import {logger} from '#/logger'
|
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 {
|
import {
|
||||||
COMPRESSION_MAX_DIMENSION,
|
COMPRESSION_MAX_DIMENSION,
|
||||||
COMPRESSION_PASSTHROUGH_BITRATE,
|
COMPRESSION_PASSTHROUGH_BITRATE,
|
||||||
@@ -19,6 +23,7 @@ export async function compressVideo(
|
|||||||
opts?: {
|
opts?: {
|
||||||
signal?: AbortSignal
|
signal?: AbortSignal
|
||||||
onProgress?: (progress: number) => void
|
onProgress?: (progress: number) => void
|
||||||
|
onProbe?: (metadata: VideoMetadata) => void
|
||||||
},
|
},
|
||||||
): Promise<CompressedVideo> {
|
): Promise<CompressedVideo> {
|
||||||
if (file.mimeType === 'image/gif') {
|
if (file.mimeType === 'image/gif') {
|
||||||
@@ -49,6 +54,8 @@ export async function compressVideo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opts?.onProbe?.(metadata)
|
||||||
|
|
||||||
if (!shouldCompress(metadata, isAcceptableFormat)) {
|
if (!shouldCompress(metadata, isAcceptableFormat)) {
|
||||||
return {
|
return {
|
||||||
uri: file.uri,
|
uri: file.uri,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import {nanoid} from 'nanoid/non-secure'
|
|||||||
import {type VideoCompressSkipReason} from '#/lib/media/video/types'
|
import {type VideoCompressSkipReason} from '#/lib/media/video/types'
|
||||||
import {Sentry} from '#/logger/sentry/lib'
|
import {Sentry} from '#/logger/sentry/lib'
|
||||||
import {type Metrics} from '#/analytics/metrics'
|
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
|
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 =
|
const COMPRESS_ENGINE =
|
||||||
Platform.OS === 'web'
|
Platform.OS === 'web'
|
||||||
? 'web:mediabunny@1.25.3'
|
? 'web:mediabunny@1.25.3'
|
||||||
: 'native:react-native-compressor@1.13.0'
|
: 'native:expo-bluesky-video-compress@1'
|
||||||
|
|
||||||
type Phase = 'compress' | 'upload' | 'processing'
|
type Phase = 'compress' | 'upload' | 'processing'
|
||||||
|
|
||||||
@@ -28,6 +29,7 @@ export type VideoTelemetry = {
|
|||||||
readonly engine: string
|
readonly engine: string
|
||||||
picked: () => void
|
picked: () => void
|
||||||
compressStarted: () => void
|
compressStarted: () => void
|
||||||
|
probed: (metadata: VideoMetadata) => void
|
||||||
compressSkipped: (video: {
|
compressSkipped: (video: {
|
||||||
size: number
|
size: number
|
||||||
mimeType: string
|
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}) {
|
compressSkipped({size, mimeType, skipReason}) {
|
||||||
metric('video:upload:compressSkipped', {
|
metric('video:upload:compressSkipped', {
|
||||||
uploadId,
|
uploadId,
|
||||||
|
|||||||
@@ -288,6 +288,7 @@ export async function processVideo(
|
|||||||
dispatch({type: 'update_progress', progress: trunc2dp(num), signal})
|
dispatch({type: 'update_progress', progress: trunc2dp(num), signal})
|
||||||
},
|
},
|
||||||
signal,
|
signal,
|
||||||
|
onProbe: metadata => telemetry.probed(metadata),
|
||||||
})
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const message = getCompressErrorMessage(e, i18n)
|
const message = getCompressErrorMessage(e, i18n)
|
||||||
|
|||||||
Reference in New Issue
Block a user