Skip to content

Instantly share code, notes, and snippets.

@benjaminmiles
Last active February 20, 2024 17:09
Show Gist options
  • Save benjaminmiles/de1f4e9828be11e1bd62987dbd573e28 to your computer and use it in GitHub Desktop.
Save benjaminmiles/de1f4e9828be11e1bd62987dbd573e28 to your computer and use it in GitHub Desktop.
Use the Web Share API to save and share a media file on supported mobile apps with a direct link fallback.
import React, { useCallback, useState, useEffect } from "react";
export async function mediaToBlob(src = "", mimetype = "video/mp4") {
// Fetch the media file as ArrayBuffer
const response = await fetch(src);
const mediaData = await response.arrayBuffer();
// Create a Blob from the video data
const blob = new Blob([mediaData], { type: mimetype });
return blob;
}
export const ShareMediaButton = ({
hostUrl = "https://example.com",
mediaSrc = "/media/filename.mp4",
mediaSaveAs = "takeaway.mp4",
mimetype = "video/mp4",
...props
}) => {
const [shareApiSupported, setShareApiSupported] = useState(false);
const handleShare = useCallback(() => {
if (!shareApiSupported) {
window.open(`${hostUrl}${mediaSrc}`, "_blank");
return;
}
mediaToBlob(mediaSrc, mimetype)
.then((blob) => {
const fileToInclude = new File([blob], mediaSaveAs, {
type: mimetype,
});
const shareObject = {
files: [fileToInclude],
};
if (navigator?.share) {
navigator.share(shareObject);
}
})
.catch((error) => {
console.error("Error converting media to Blob:", error);
});
}, [hostUrl, mediaSrc, mediaSaveAs, mimetype, shareApiSupported]);
useEffect(() => {
if (navigator?.canShare && navigator?.share) {
setShareApiSupported(true);
}
}, []);
return (
<button onClick={handleShare} {...props}>
Share
</button>
);
};
export default ShareMediaButton;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment