[Videos] avoid using fetch for blob handling where possible (#5041)

* avoid using fetch where possible

* whoopsie wrong branch

* more import fixes
This commit is contained in:
Samuel Newman 2024-08-30 19:05:38 +01:00 committed by GitHub
parent c70ec1ce1a
commit 8647c8e9f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 47 additions and 18 deletions

View file

@ -1,9 +1,6 @@
import {getVideoMetaData, Video} from 'react-native-compressor'
export type CompressedVideo = {
uri: string
size: number
}
import {CompressedVideo} from './types'
export async function compressVideo(
file: string,

View file

@ -1,12 +1,8 @@
import {VideoTooLargeError} from 'lib/media/video/errors'
import {CompressedVideo} from './types'
const MAX_VIDEO_SIZE = 1024 * 1024 * 100 // 100MB
export type CompressedVideo = {
uri: string
size: number
}
// doesn't actually compress, but throws if >100MB
export async function compressVideo(
file: string,
@ -15,8 +11,9 @@ export async function compressVideo(
onProgress?: (progress: number) => void
},
): Promise<CompressedVideo> {
const blob = await fetch(file).then(res => res.blob())
const video = URL.createObjectURL(blob)
const {mimeType, base64} = parseDataUrl(file)
const blob = base64ToBlob(base64, mimeType)
const uri = URL.createObjectURL(blob)
if (blob.size > MAX_VIDEO_SIZE) {
throw new VideoTooLargeError()
@ -24,6 +21,34 @@ export async function compressVideo(
return {
size: blob.size,
uri: video,
uri,
bytes: await blob.arrayBuffer(),
}
}
function parseDataUrl(dataUrl: string) {
const [mimeType, base64] = dataUrl.slice('data:'.length).split(';base64,')
if (!mimeType || !base64) {
throw new Error('Invalid data URL')
}
return {mimeType, base64}
}
function base64ToBlob(base64: string, mimeType: string) {
const byteCharacters = atob(base64)
const byteArrays = []
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
const slice = byteCharacters.slice(offset, offset + 512)
const byteNumbers = new Array(slice.length)
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i)
}
const byteArray = new Uint8Array(byteNumbers)
byteArrays.push(byteArray)
}
return new Blob(byteArrays, {type: mimeType})
}

View file

@ -0,0 +1,6 @@
export type CompressedVideo = {
uri: string
size: number
// web only, can fall back to uri if missing
bytes?: ArrayBuffer
}