代码之家  ›  专栏  ›  技术社区  ›  Ron Astle Lobo

在react native中使用base64编码字符串播放视频

  •  11
  • Ron Astle Lobo  · 技术社区  · 7 年前

    我使用base64编码格式和aes加密对视频文件进行了加密。我对数据流逐流解密并附加/写入每个流(作为.mp4文件)以实现最终视频,但要实现最终输出需要很多时间。

    专业编辑:

    我找到了资源 html5-media-and-data-uri 有助于在 webview ,但它不播放2000000+base64个字符的视频。

    函数在具有base64数据的Web视图中解密文件并初始化HTML代码

    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");
        });
      });
    }
    

    Web视图代码

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

    需要帮助来寻找在React Native中播放Base64视频的方法/替代方法。

    这是一个离线电子学习应用程序,视频存储在SD卡上,数据实时解密并在视频播放器中播放。

    1 回复  |  直到 7 年前
        1
  •  5
  •   diogenesgg    7 年前

    可以通过让webview嵌入javascript代码从设备存储读取文件内容来解决这个问题,以避免内联这个大的base64文本。

    如上所述 here ,建议的解决方法是使用blob url。

    基本上你必须:

    • 进口 RNFetchBlob simpleCrypto 在网络视图中。(见 here )
    • :获取文件并解密,
    • :创建blob url并将其设置为 <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来复制您的限制问题,WebVIEW嵌入了一个大的Base64内联文字(2.5MB)。它适用于850kbbase64视频。
    • 2:blob url方法通过获取包含较大base64视频的远程json文件,确实解决了web视图的这一限制。
    • 3:我没有测试将rnfetchblob导入webview方法。再次,如前所述 here 似乎很管用。

    附加代码

    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;
    }
    

    聚苯乙烯

    我本人不赞成这种Base64方法。我更希望有一些本机代码,由react native触发,用于编写和读取加密视频。读取将生成一个temp.mp4,从 react-native-video 模块。在幕后,加密是在字节级完成的。所以我们不需要来回解析到base64。我们毕竟是在处理二进制文件。