about summary refs log tree commit diff
path: root/src/lib/media/video/compress.web.ts
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-08-30 19:05:38 +0100
committerGitHub <noreply@github.com>2024-08-30 19:05:38 +0100
commit8647c8e9f589401b1763fa8af596a6fd12bad04e (patch)
tree488475f9aec7423c9d8d6c230c04a20642cdf3fd /src/lib/media/video/compress.web.ts
parentc70ec1ce1aff6072934add1f543576d5200c1b02 (diff)
downloadvoidsky-8647c8e9f589401b1763fa8af596a6fd12bad04e.tar.zst
[Videos] avoid using fetch for blob handling where possible (#5041)
* avoid using fetch where possible

* whoopsie wrong branch

* more import fixes
Diffstat (limited to 'src/lib/media/video/compress.web.ts')
-rw-r--r--src/lib/media/video/compress.web.ts41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/lib/media/video/compress.web.ts b/src/lib/media/video/compress.web.ts
index 11ccb5104..c08702534 100644
--- a/src/lib/media/video/compress.web.ts
+++ b/src/lib/media/video/compress.web.ts
@@ -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})
 }