Skip to content

Commit f8175f2

Browse files
authored
Fix base64 video/audio playing on ios (#905)
1 parent 11e8619 commit f8175f2

File tree

3 files changed

+25
-11
lines changed

3 files changed

+25
-11
lines changed

packages/core/src/components/MediaPlayer/AudioPlayer/HeadlessAudioPlayer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ const HeadlessAudioPlayer = React.forwardRef<
9393
isError: false,
9494
});
9595

96-
let finalSource = await normalizeBase64Source(source);
96+
let finalSource = await normalizeBase64Source(source, "audio");
9797

9898
const { sound } = await Audio.Sound.createAsync(finalSource);
9999
setCurrentSound(sound);

packages/core/src/components/MediaPlayer/MediaPlayerCommon.ts

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,37 @@ export function mapToMediaPlayerStatus(
5555
};
5656
}
5757

58-
// https://stackoverflow.com/a/7874175/8805150
59-
const BASE_64_REGEX =
60-
/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
58+
const URL_REGEX =
59+
/[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
6160

6261
/**
6362
* Base64 strings are not playable on iOS and needs to be saved to a file before playing
6463
*/
6564
export async function normalizeBase64Source(
66-
source: AVPlaybackSource
65+
source: AVPlaybackSource,
66+
type: "audio" | "video"
6767
): Promise<AVPlaybackSource> {
6868
const uri: string | undefined = (source as any)?.uri;
6969

70-
if (Platform.OS === "ios" && uri && uri.match(BASE_64_REGEX)) {
71-
const fileName = `${FileSystem.cacheDirectory}${uuid()}`;
72-
await FileSystem.writeAsStringAsync(fileName, uri, {
73-
encoding: FileSystem.EncodingType.Base64,
74-
});
70+
if (Platform.OS === "ios" && uri && !uri.match(URL_REGEX)) {
71+
const defaultMimeType = type === "audio" ? "wav" : "mp4";
72+
const mimeType = uri.startsWith(`data:${type}/`)
73+
? uri.substring(`data:${type}/`.length, uri.indexOf(";")) //Ex: extract 'mp4' from 'data:video/mp4;base64,....'
74+
: defaultMimeType;
75+
76+
const fileName = `${
77+
FileSystem.cacheDirectory
78+
}${uuid()}.${mimeType.toLowerCase()}`;
79+
80+
await FileSystem.writeAsStringAsync(
81+
fileName,
82+
uri.includes("base64,")
83+
? uri.substring(uri.indexOf("base64,") + "base64,".length) // skip header portion of base64 string
84+
: uri,
85+
{
86+
encoding: FileSystem.EncodingType.Base64,
87+
}
88+
);
7589
return { uri: fileName };
7690
}
7791

packages/core/src/components/MediaPlayer/VideoPlayer/VideoPlayer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ const VideoPlayer = React.forwardRef<VideoPlayerRef, VideoPlayerProps>(
120120

121121
useSourceDeepCompareEffect(() => {
122122
const updateSource = async () => {
123-
const finalSource = await normalizeBase64Source(source);
123+
const finalSource = await normalizeBase64Source(source, "video");
124124
setCurrentSource(finalSource);
125125
};
126126
updateSource();

0 commit comments

Comments
 (0)