Эту проблему можно решить с помощью встроенного JavaScript-кода WebView для чтения содержимого файла из хранилища устройства, чтобы избежать встроенного большого литерала base64.
Как описано здесь Рекомендуется использовать URL-адрес BLOB-объекта.
В основном вам необходимо:
- 1 : импортировать
RNFetchBlob
и simpleCrypto
внутриWebView.(см. здесь ) - 2 : извлечь файл и расшифровать его,
- 3 : создать URL-адрес BLOB-объекта иустановите для него атрибут
<video>
src.
Ваш код будет выглядеть примерно так:
componentDidMount() {
this.setState({htmlCode: `
<html>
<body>
<video id="myvideo" style="width: 50%; height: 50%; margin-top: 10%; margin-left: 22%;" controls></video>
<script src="${RNFetchBlob.fs.dirs.MainBundleDir}/bundle.js"></script>
<script src="${path/to/simpleCrypto.js}"></script>
<script type="text/javascript">
function b64toBlob(b64Data, contentType, sliceSize) {
//... returns a new Blob using the b64Data.
}
//for simplicity, onDecodeEnd abstracts your decryption code
RNFetchBlob.fs.readStream('encryptfile1.dat').onDecodeEnd((decryptText) => {
var blob = b64toBlob(base64Video, "video/mp4");
var url = URL.createObjectURL(blob);
document.getElementById('myvideo').src = url;
})
</script>
</body>
</html>
`})
render() {
return (
<WebView
style={{ flex: 1 }}
source={{ html: this.state.htmlCode, baseUrl: RNFetchBlob.fs.dirs.DCIMDir }}>
</WebView>
);
}
Отказ от ответственности
- 1: Я смог воспроизвести вашу проблему с ограничениями, используя Webview, в который встроен большой встроенный литерал base64 (2,5 МБ).Он работал для видео 864 КБ base64.
- 2: подход с использованием Blob URL решил это ограничение для веб-представления, загрузив удаленный json-файл, содержащий более крупное видео base64.
- 3: Iне тестировал импорт RNFetchBlob в подход WebView.Опять же, как описано здесь , похоже, работает.
Дополнительный код
function b64toBlob(b64Data, contentType, sliceSize) {
contentType = contentType || '';
sliceSize = sliceSize || 512;
var byteCharacters = atob(b64Data);
var byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
var slice = byteCharacters.slice(offset, offset + sliceSize);
var byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
var byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
var blob = new Blob(byteArrays, {type: contentType});
return blob;
}
PS
Я бы сам не пошел на этот подход base64.Я предпочел бы иметь некоторый нативный код, запущенный из React Native, который будет писать и читать зашифрованные видео.Чтение будет генерировать temp.mp4 для загрузки из модуля react-native-video
.Под капотом шифрование выполняется на уровне байтов.Поэтому нам не нужно анализировать его взад и вперед в base64.В конце концов, мы имеем дело с двоичными файлами.