fix: Fix video and audio loading with authenicated media (#1946)
author夜坂雅 <23130178+ShadowRZ@users.noreply.github.com>
Wed, 11 Sep 2024 05:13:15 +0000 (13:13 +0800)
committerGitHub <noreply@github.com>
Wed, 11 Sep 2024 05:13:15 +0000 (10:43 +0530)
Appeareantly Firefox (and maybe Chrome) won't let service workers take over requests from <video> and <audio> tags, so we just fetch the URL ourselves.

src/app/components/message/content/AudioContent.tsx
src/app/components/message/content/VideoContent.tsx
src/app/components/message/content/util.ts

index b426654fbd56345c29827552ba7ccc88a52944f5..d6a82a3bc84e0a0e31b5b018cc6be0f38e20eee1 100644 (file)
@@ -50,7 +50,7 @@ export function AudioContent({
 
   const [srcState, loadSrc] = useAsyncCallback(
     useCallback(
-      () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo),
+      () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo, true),
       [mx, url, useAuthentication, mimeType, encInfo]
     )
   );
index 46f82fae50b6722e566927ae1ec8ac3c702cec76..1683075bffa0fde17736ebe0123e49814bdc87e0 100644 (file)
@@ -71,7 +71,7 @@ export const VideoContent = as<'div', VideoContentProps>(
 
     const [srcState, loadSrc] = useAsyncCallback(
       useCallback(
-        () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo),
+        () => getFileSrcUrl(mxcUrlToHttp(mx, url, useAuthentication) ?? '', mimeType, encInfo, true),
         [mx, url, useAuthentication, mimeType, encInfo]
       )
     );
index 2cc434184ed730b89a327d65b9d281f73b370bfe..8614b8ece5b9df652fc4b303fae864718d1ddfef 100644 (file)
@@ -4,7 +4,8 @@ import { decryptFile } from '../../../utils/matrix';
 export const getFileSrcUrl = async (
   httpUrl: string,
   mimeType: string,
-  encInfo?: EncryptedAttachmentInfo
+  encInfo?: EncryptedAttachmentInfo,
+  forceFetch?: boolean
 ): Promise<string> => {
   if (encInfo) {
     if (typeof httpUrl !== 'string') throw new Error('Malformed event');
@@ -13,6 +14,12 @@ export const getFileSrcUrl = async (
     const decryptedBlob = await decryptFile(encData, mimeType, encInfo);
     return URL.createObjectURL(decryptedBlob);
   }
+  if (forceFetch) {
+    const res = await fetch(httpUrl, { method: 'GET' });
+    const blob = await res.blob();
+    return URL.createObjectURL(blob);
+  }
+
   return httpUrl;
 };