Add video upload telemetry events (#10991)
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
} from '@atproto/api'
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
|
||||
import {type VideoTelemetry} from '#/lib/media/video/telemetry'
|
||||
import {type SelfLabel} from '#/lib/moderation'
|
||||
import {insertMentionAt} from '#/lib/strings/mention-manip'
|
||||
import {shortenLinks} from '#/lib/strings/rich-text-manip'
|
||||
@@ -88,6 +89,7 @@ export type PostAction =
|
||||
type: 'embed_add_video'
|
||||
asset: ImagePickerAsset
|
||||
abortController: AbortController
|
||||
telemetry: VideoTelemetry
|
||||
}
|
||||
| {type: 'embed_remove_video'}
|
||||
| {type: 'embed_update_video'; videoAction: VideoAction}
|
||||
@@ -458,7 +460,11 @@ function postReducer(state: PostDraft, action: PostAction): PostDraft {
|
||||
if (!prevMedia) {
|
||||
nextMedia = {
|
||||
type: 'video',
|
||||
video: createVideoState(action.asset, action.abortController),
|
||||
video: createVideoState(
|
||||
action.asset,
|
||||
action.abortController,
|
||||
action.telemetry,
|
||||
),
|
||||
}
|
||||
}
|
||||
return {
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
UploadLimitError,
|
||||
VideoTooLargeError,
|
||||
} from '#/lib/media/video/errors'
|
||||
import {type VideoTelemetry} from '#/lib/media/video/telemetry'
|
||||
import {type CompressedVideo} from '#/lib/media/video/types'
|
||||
import {uploadVideo} from '#/lib/media/video/upload'
|
||||
import {createVideoAgent} from '#/lib/media/video/util'
|
||||
@@ -64,6 +65,7 @@ export const NO_VIDEO = Object.freeze({
|
||||
video: undefined,
|
||||
jobId: undefined,
|
||||
pendingPublish: undefined,
|
||||
telemetry: undefined,
|
||||
altText: '',
|
||||
captions: [],
|
||||
})
|
||||
@@ -79,6 +81,7 @@ type ErrorState = {
|
||||
jobId: string | null
|
||||
error: string
|
||||
pendingPublish?: undefined
|
||||
telemetry: VideoTelemetry
|
||||
altText: string
|
||||
captions: CaptionsTrack[]
|
||||
}
|
||||
@@ -91,6 +94,7 @@ type CompressingState = {
|
||||
video?: undefined
|
||||
jobId?: undefined
|
||||
pendingPublish?: undefined
|
||||
telemetry: VideoTelemetry
|
||||
altText: string
|
||||
captions: CaptionsTrack[]
|
||||
}
|
||||
@@ -103,6 +107,7 @@ type UploadingState = {
|
||||
video: CompressedVideo
|
||||
jobId?: undefined
|
||||
pendingPublish?: undefined
|
||||
telemetry: VideoTelemetry
|
||||
altText: string
|
||||
captions: CaptionsTrack[]
|
||||
}
|
||||
@@ -116,6 +121,7 @@ type ProcessingState = {
|
||||
jobId: string
|
||||
jobStatus: AppBskyVideoDefs.JobStatus | null
|
||||
pendingPublish?: undefined
|
||||
telemetry: VideoTelemetry
|
||||
altText: string
|
||||
captions: CaptionsTrack[]
|
||||
}
|
||||
@@ -128,6 +134,7 @@ type DoneState = {
|
||||
video: CompressedVideo
|
||||
jobId?: undefined
|
||||
pendingPublish: {blobRef: BlobRef}
|
||||
telemetry: VideoTelemetry
|
||||
altText: string
|
||||
captions: CaptionsTrack[]
|
||||
}
|
||||
@@ -142,12 +149,14 @@ export type VideoState =
|
||||
export function createVideoState(
|
||||
asset: ImagePickerAsset,
|
||||
abortController: AbortController,
|
||||
telemetry: VideoTelemetry,
|
||||
): CompressingState {
|
||||
return {
|
||||
status: 'compressing',
|
||||
progress: 0,
|
||||
abortController,
|
||||
asset,
|
||||
telemetry,
|
||||
altText: '',
|
||||
captions: [],
|
||||
}
|
||||
@@ -170,6 +179,7 @@ export function videoReducer(
|
||||
asset: state.asset ?? null,
|
||||
video: state.video ?? null,
|
||||
jobId: state.jobId ?? null,
|
||||
telemetry: state.telemetry,
|
||||
altText: state.altText,
|
||||
captions: state.captions,
|
||||
}
|
||||
@@ -198,6 +208,7 @@ export function videoReducer(
|
||||
abortController: state.abortController,
|
||||
asset: state.asset,
|
||||
video: action.video,
|
||||
telemetry: state.telemetry,
|
||||
altText: state.altText,
|
||||
captions: state.captions,
|
||||
}
|
||||
@@ -213,6 +224,7 @@ export function videoReducer(
|
||||
video: state.video,
|
||||
jobId: action.jobId,
|
||||
jobStatus: null,
|
||||
telemetry: state.telemetry,
|
||||
altText: state.altText,
|
||||
captions: state.captions,
|
||||
}
|
||||
@@ -239,6 +251,7 @@ export function videoReducer(
|
||||
pendingPublish: {
|
||||
blobRef: action.blobRef,
|
||||
},
|
||||
telemetry: state.telemetry,
|
||||
altText: state.altText,
|
||||
captions: state.captions,
|
||||
}
|
||||
@@ -265,9 +278,11 @@ export async function processVideo(
|
||||
did: string,
|
||||
signal: AbortSignal,
|
||||
i18n: I18n,
|
||||
telemetry: VideoTelemetry,
|
||||
) {
|
||||
let video: CompressedVideo | undefined
|
||||
try {
|
||||
telemetry.compressStarted()
|
||||
video = await compressVideo(asset, {
|
||||
onProgress: num => {
|
||||
dispatch({type: 'update_progress', progress: trunc2dp(num), signal})
|
||||
@@ -277,6 +292,7 @@ export async function processVideo(
|
||||
} catch (e) {
|
||||
const message = getCompressErrorMessage(e, i18n)
|
||||
if (message !== null) {
|
||||
telemetry.compressFailed(e)
|
||||
dispatch({
|
||||
type: 'to_error',
|
||||
error: message,
|
||||
@@ -285,6 +301,15 @@ export async function processVideo(
|
||||
}
|
||||
return
|
||||
}
|
||||
if (video.passthroughReason) {
|
||||
telemetry.compressSkipped({
|
||||
size: video.size,
|
||||
mimeType: video.mimeType,
|
||||
skipReason: video.passthroughReason,
|
||||
})
|
||||
} else {
|
||||
telemetry.compressCompleted({size: video.size, mimeType: video.mimeType})
|
||||
}
|
||||
dispatch({
|
||||
type: 'compressing_to_uploading',
|
||||
video,
|
||||
@@ -293,6 +318,7 @@ export async function processVideo(
|
||||
|
||||
let uploadResponse: AppBskyVideoDefs.JobStatus | undefined
|
||||
try {
|
||||
telemetry.uploadStarted(video.size)
|
||||
uploadResponse = await uploadVideo({
|
||||
video,
|
||||
agent,
|
||||
@@ -306,6 +332,7 @@ export async function processVideo(
|
||||
} catch (e) {
|
||||
const message = getUploadErrorMessage(e, i18n)
|
||||
if (message !== null) {
|
||||
telemetry.uploadFailed(e)
|
||||
dispatch({
|
||||
type: 'to_error',
|
||||
error: message,
|
||||
@@ -316,6 +343,8 @@ export async function processVideo(
|
||||
}
|
||||
|
||||
const jobId = uploadResponse.jobId
|
||||
telemetry.uploadCompleted(jobId)
|
||||
telemetry.processingStarted(jobId)
|
||||
dispatch({
|
||||
type: 'uploading_to_processing',
|
||||
jobId,
|
||||
@@ -354,6 +383,7 @@ export async function processVideo(
|
||||
}
|
||||
|
||||
logger.error('Error processing video', {safeMessage: e})
|
||||
telemetry.processingFailed(e)
|
||||
dispatch({
|
||||
type: 'to_error',
|
||||
error: i18n._(msg`Video failed to process`),
|
||||
@@ -363,6 +393,7 @@ export async function processVideo(
|
||||
}
|
||||
|
||||
if (blob) {
|
||||
telemetry.processingCompleted()
|
||||
dispatch({
|
||||
type: 'to_done',
|
||||
blobRef: blob,
|
||||
|
||||
Reference in New Issue
Block a user