Воспроизведение видео с использованием строки в кодировке base64 в React-Native - PullRequest
0 голосов
/ 24 января 2019

Я зашифровал видеофайл, используя формат кодировки base64 и AES-шифрование. Я расшифровываю поток данных за потоком и добавляю / записываю каждый поток (в виде файла .mp4) для получения окончательного видео, но для получения окончательного результата требуется много времени.

Major Edit:

Я нашел ресурсы html5-media-and-data-uri , которые помогают воспроизводить данные в формате webview, но не воспроизводят видео с 2 000 000+ символов base64.

Функция для расшифровки файла и инициализации HTML-кода в веб-представлении с данными base64

decryptfile() {
RNFetchBlob.fs
  .readStream(
    RNFetchBlob.fs.dirs.DCIMDir + "/encryptfile1.dat",
    "base64",
    2796256, //character to be read at a time for decryption
    2500  // Time taken before each stream enters for decryption
  )
  .then(stream => {
    let data = "";
    stream.open();
    stream.onData(chunk => {
      var decipherText = simpleCrypto.decrypt(chunk.toString()); // Decryption
      decryptText = decryptText + decipherText; // appending decrypted data
    });
    stream.onEnd(() => {
      htmlCode =
        `<html>
           <body>
              <video style="width: 50%; height: 50%; margin-top: 10%; margin-left: 22%;"
              controls>
                <source type="video/mp4" src="data:video/mp4;base64,` +
                 decryptText.toString() + // final decrypted data
                `">
             </video>
          </body>
        </html>`;
      this.setState({ playvideo: !this.state.playvideo }); // state set for playing video at end of decryption
      console.log("File decrypted");
    });
  });
}

Код веб-просмотра

<WebView
     style={{ flex: 1 }}
     source={{ html: htmlCode }}
 />

Нужна помощь в поиске способов / альтернатив для воспроизведения видео с base64 на реагирующем языке.

Это автономное приложение для электронного обучения, в котором видео хранится на SD-карте, а данные расшифровываются на лету и воспроизводятся в видеоплеере.

1 Ответ

0 голосов
/ 02 февраля 2019

Эту проблему можно решить с помощью встроенного 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.В конце концов, мы имеем дело с двоичными файлами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...