diff --git a/src/lib/constants.ts b/src/lib/constants.ts index ccd5f2de..930f5732 100644 --- a/src/lib/constants.ts +++ b/src/lib/constants.ts @@ -136,3 +136,12 @@ export const GIF_FEATURED = (params: string) => `${GIF_SERVICE}/tenor/v2/featured?${params}` export const MAX_LABELERS = 20 + +export const SUPPORTED_MIME_TYPES = [ + 'video/mp4', + 'video/mpeg', + 'video/webm', + 'video/quicktime', +] as const + +export type SupportedMimeTypes = (typeof SUPPORTED_MIME_TYPES)[number] diff --git a/src/lib/media/video/compress.ts b/src/lib/media/video/compress.ts index 79c58f5d..e783a843 100644 --- a/src/lib/media/video/compress.ts +++ b/src/lib/media/video/compress.ts @@ -30,5 +30,5 @@ export async function compressVideo( const info = await getVideoMetaData(compressed) - return {uri: compressed, size: info.size, mimeType: `video/${info.extension}`} + return {uri: compressed, size: info.size, mimeType: `video/mp4`} } diff --git a/src/state/queries/video/util.ts b/src/state/queries/video/util.ts index 898f1736..e019848a 100644 --- a/src/state/queries/video/util.ts +++ b/src/state/queries/video/util.ts @@ -1,6 +1,8 @@ import {useMemo} from 'react' import {AtpAgent} from '@atproto/api' +import {SupportedMimeTypes} from '#/lib/constants' + const UPLOAD_ENDPOINT = 'https://video.bsky.app/' export const createVideoEndpointUrl = ( @@ -25,7 +27,7 @@ export function useVideoAgent() { }, []) } -export function mimeToExt(mimeType: string) { +export function mimeToExt(mimeType: SupportedMimeTypes | (string & {})) { switch (mimeType) { case 'video/mp4': return 'mp4' @@ -33,6 +35,8 @@ export function mimeToExt(mimeType: string) { return 'webm' case 'video/mpeg': return 'mpeg' + case 'video/quicktime': + return 'mov' default: throw new Error(`Unsupported mime type: ${mimeType}`) } diff --git a/src/state/queries/video/video.ts b/src/state/queries/video/video.ts index 87f31564..5e36ce35 100644 --- a/src/state/queries/video/video.ts +++ b/src/state/queries/video/video.ts @@ -5,6 +5,7 @@ import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {QueryClient, useQuery, useQueryClient} from '@tanstack/react-query' +import {SUPPORTED_MIME_TYPES, SupportedMimeTypes} from '#/lib/constants' import {logger} from '#/logger' import {isWeb} from '#/platform/detection' import {ServerError, VideoTooLargeError} from 'lib/media/video/errors' @@ -175,19 +176,19 @@ export function useUploadVideo({ }) const selectVideo = (asset: ImagePickerAsset) => { - switch (getMimeType(asset)) { - case 'video/mp4': - case 'video/mpeg': - case 'video/webm': - dispatch({ - type: 'SetAsset', - asset, - }) - onSelectVideo(asset) - break - default: - throw new Error(_(msg`Unsupported video type: ${getMimeType(asset)}`)) + // compression step on native converts to mp4, so no need to check there + if (isWeb) { + const mimeType = getMimeType(asset) + if (!SUPPORTED_MIME_TYPES.includes(mimeType as SupportedMimeTypes)) { + throw new Error(_(msg`Unsupported video type: ${mimeType}`)) + } } + + dispatch({ + type: 'SetAsset', + asset, + }) + onSelectVideo(asset) } const clearVideo = () => {