diff --git a/native/media/identifier-utils.js b/native/media/identifier-utils.js
--- a/native/media/identifier-utils.js
+++ b/native/media/identifier-utils.js
@@ -1,5 +1,11 @@
// @flow
+import {
+ getBlobFetchableURL,
+ holderFromBlobServiceURI,
+ isBlobServiceURI,
+} from 'lib/utils/blob-service.js';
+
function getCompatibleMediaURI(uri: string, ext: ?string): string {
if (!ext) {
return uri;
@@ -42,6 +48,11 @@
}
function getFetchableURI(inputURI: string): string {
+ if (isBlobServiceURI(inputURI)) {
+ const holder = holderFromBlobServiceURI(inputURI);
+ return getBlobFetchableURL(holder);
+ }
+
// React Native always resolves Apple's assets-library:// and FBMediaKit's
// ph:// scheme as an image so that the Image component can render thumbnails
// of videos. In order to force fetch() to return a blob of the video, we need
diff --git a/web/media/encryption-utils.js b/web/media/encryption-utils.js
--- a/web/media/encryption-utils.js
+++ b/web/media/encryption-utils.js
@@ -12,6 +12,7 @@
import { calculatePaddedLength, pad, unpad } from 'lib/utils/pkcs7-padding.js';
import * as AES from './aes-crypto-utils.js';
+import { fetchableMediaURI } from './media-utils.js';
const PADDING_THRESHOLD = 5000000; // 5MB
@@ -139,8 +140,9 @@
// Step 1 - Fetch the encrypted media and convert it to a Uint8Array
let data;
const fetchStartTime = Date.now();
+ const url = fetchableMediaURI(holder);
try {
- const response = await fetch(holder);
+ const response = await fetch(url);
const buffer = await response.arrayBuffer();
data = new Uint8Array(buffer);
} catch (e) {
@@ -149,7 +151,7 @@
}
steps.push({
step: 'fetch_buffer',
- url: holder,
+ url,
time: Date.now() - fetchStartTime,
success,
exceptionMessage,
diff --git a/web/media/media-utils.js b/web/media/media-utils.js
--- a/web/media/media-utils.js
+++ b/web/media/media-utils.js
@@ -6,6 +6,11 @@
MediaMissionStep,
MediaMissionFailure,
} from 'lib/types/media-types.js';
+import {
+ isBlobServiceURI,
+ getBlobFetchableURL,
+ holderFromBlobServiceURI,
+} from 'lib/utils/blob-service.js';
import { getMessageForException } from 'lib/utils/errors.js';
import { probeFile } from './blob-utils.js';
@@ -193,4 +198,13 @@
};
}
-export { preloadImage, validateFile };
+function fetchableMediaURI(uri: string): string {
+ if (isBlobServiceURI(uri)) {
+ const holder = holderFromBlobServiceURI(uri);
+ return getBlobFetchableURL(holder);
+ }
+
+ return uri;
+}
+
+export { preloadImage, validateFile, fetchableMediaURI };
diff --git a/web/media/multimedia-modal.react.js b/web/media/multimedia-modal.react.js
--- a/web/media/multimedia-modal.react.js
+++ b/web/media/multimedia-modal.react.js
@@ -8,6 +8,7 @@
import type { EncryptedMediaType, MediaType } from 'lib/types/media-types.js';
import EncryptedMultimedia from './encrypted-multimedia.react.js';
+import { fetchableMediaURI } from './media-utils.js';
import css from './media.css';
type MediaInfo =
@@ -42,11 +43,13 @@
let mediaModalItem;
const { media } = this.props;
if (media.type === 'photo') {
- mediaModalItem = ;
+ const uri = fetchableMediaURI(media.uri);
+ mediaModalItem = ;
} else if (media.type === 'video') {
+ const uri = fetchableMediaURI(media.uri);
mediaModalItem = (
);
} else {
diff --git a/web/media/multimedia.react.js b/web/media/multimedia.react.js
--- a/web/media/multimedia.react.js
+++ b/web/media/multimedia.react.js
@@ -17,6 +17,7 @@
import type { MediaType, EncryptedMediaType } from 'lib/types/media-types.js';
import EncryptedMultimedia from './encrypted-multimedia.react.js';
+import { fetchableMediaURI } from './media-utils.js';
import css from './media.css';
import MultimediaModal from './multimedia-modal.react.js';
import Button from '../components/button.react.js';
@@ -118,11 +119,13 @@
// Media element is the actual image or video element (or encrypted version)
let mediaElement;
if (mediaSource.type === 'photo') {
- mediaElement = ;
+ const uri = fetchableMediaURI(mediaSource.uri);
+ mediaElement = ;
} else if (mediaSource.type === 'video') {
+ const uri = fetchableMediaURI(mediaSource.uri);
mediaElement = (
);
} else if (