Skip to main content

Examples

info

Important: Don't forget to add the dependency in your ./android/app/build.gradle:

dependencies {
implementation fileTree(dir: "../../node_modules/@TheWidlarzGroup/react-native-video-stream-downloader/native-libs", include: ["*.aar"])
//...
}

Simple example of downloading and managing video content:

import React, { useEffect, useState } from "react";
import { Button, SafeAreaView, StyleSheet, Text, View } from "react-native";
import {
downloadStream,
useEvent,
pauseDownload,
resumeDownload,
getDownloadedAssets,
registerPlugin,
disablePlugin,
deleteDownloadedAsset,
type DownloadedAsset,
} from "@TheWidlarzGroup/react-native-video-stream-downloader";

// Define enum for download status
enum DownloadStatus {
READY = "Ready to Download",
DOWNLOADING = "Downloading...",
PAUSED = "Download Paused",
RESUMING = "Resuming Download...",
COMPLETED = "Download Completed",
}

const API_KEY = ""; // Use your actual API key

const VIDEO = {
title: "Video Title", // Replace with actual title
url: "https://example.com/video.m3u8", // Replace with actual video URL
};

export default function App() {
const [downloadId, setDownloadId] = useState<string | null>(null);
const [downloadProgress, setDownloadProgress] = useState(0);
const [downloadStatus, setDownloadStatus] = useState<DownloadStatus>(
DownloadStatus.READY
);
const [isDownloading, setIsDownloading] = useState(false);
const [isSDKRegistered, setIsSDKRegistered] = useState(false);
const [downloadedAsset, setDownloadedAsset] =
useState<DownloadedAsset | null>(null);

// Load downloaded assets and update progress if needed
const loadAssets = async () => {
const result = await getDownloadedAssets();
console.log(result);
setDownloadedAsset(result[0] ? result[0] : null);
setIsDownloading(result.length > 0);
setDownloadProgress(result.length > 0 ? 100 : 0);
};

// Event listeners for download progress and errors
useEvent("onDownloadProgress", (statuses) => {
if (statuses && statuses[0]) {
setDownloadProgress(Math.round(statuses[0].progress * 100));
}
});

useEvent("onDownloadEnd", async () => {
console.log("Download completed");
setDownloadProgress(100);
setDownloadStatus(DownloadStatus.COMPLETED);
loadAssets();
});

// Register and disable plugin
useEffect(() => {
const registerSDK = async () => {
try {
await registerPlugin(API_KEY);
setIsSDKRegistered(true);
console.log("Plugin registered successfully");
loadAssets();
} catch (error) {
setIsSDKRegistered(false);
console.log("Error registering plugin", error);
}
};

registerSDK();

return () => {
disablePlugin();
};
}, []);

// Handle video download
const handleDownload = async () => {
setDownloadStatus(DownloadStatus.DOWNLOADING);
const result = await downloadStream(VIDEO.url, {
checkStorageBeforeDownload: true,
expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours
metadata: {
title: VIDEO.title,
type: "video",
tags: ["example", "video"],
},
});
setDownloadId(result.id);
setIsDownloading(true);
};

// Pause and resume download actions
const handlePause = async () => {
if (downloadId) {
await pauseDownload(downloadId);
setDownloadStatus(DownloadStatus.PAUSED);
}
};

const handleResume = async () => {
if (downloadId) {
await resumeDownload(downloadId);
setDownloadStatus(DownloadStatus.RESUMING);
}
};

const handlePlay = () => {
console.log(
`Playing video... The correct source.uri is ${downloadedAsset?.pathToFile}`
);
};

// Delete the downloaded video
const handleDelete = async () => {
if (downloadedAsset) {
await deleteDownloadedAsset(downloadedAsset.id);
setDownloadStatus(DownloadStatus.READY);
setDownloadedAsset(null);
loadAssets();
console.log("Deleted asset with ID:", downloadedAsset.id);
}
};

return (
<SafeAreaView style={styles.container}>
<View style={styles.card}>
<Text style={styles.title}>{VIDEO.title}</Text>

{!isDownloading ? (
<Button title="Download" onPress={handleDownload} color="#4caf50" />
) : (
<View style={styles.progressContainer}>
<Text style={styles.text}>Progress: {downloadProgress}%</Text>
<Text style={styles.text}>{downloadStatus}</Text>
<View style={styles.buttonContainer}>
<Button title="Pause" onPress={handlePause} color="#ff5722" />
<Button title="Resume" onPress={handleResume} color="#4caf50" />
</View>
</View>
)}

{downloadProgress === 100 && (
<Button title="Play Video" onPress={handlePlay} color="#3f51b5" />
)}

<Text style={styles.text}>
SDK Registration: {isSDKRegistered ? "✅ Active" : "❌ Inactive"}
</Text>

{downloadedAsset && (
<View style={styles.deleteContainer}>
<Button
title="Delete Video"
onPress={handleDelete}
color="#d32f2f"
/>
</View>
)}
</View>
</SafeAreaView>
);
}

const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: "#121212",
justifyContent: "center",
},
card: {
backgroundColor: "#1e1e1e",
padding: 20,
marginVertical: 30,
borderRadius: 8,
shadowColor: "#000",
shadowOpacity: 0.1,
shadowRadius: 8,
shadowOffset: { width: 0, height: 2 },
},
title: {
fontSize: 20,
color: "#fff",
marginBottom: 15,
textAlign: "center",
},
text: {
color: "#bbb",
marginBottom: 10,
textAlign: "center",
},
progressContainer: {
marginBottom: 20,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "space-between",
},
deleteContainer: {
marginTop: 20,
alignItems: "center",
},
});