You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CryptoJS加密视频存Firebase,解密后无法在HTML5 Video播放求助

问题分析与解决方案

你遇到的核心问题是错误地将二进制视频文件当作文本处理,导致原始二进制数据在编码/解码过程中丢失或损坏。视频是二进制格式,不能用readAsText()或UTF-8字符串来传递——这会破坏非文本字节,最终解密后的内容不再是有效的MP4文件。

下面是具体的修复步骤和完整代码:

关键错误点拆解

  1. 加密阶段:用reader.readAsText(file)读取视频,将二进制转为UTF-8字符串,丢失了视频中无法被UTF-8正确编码的字节。
  2. 解密阶段:将解密结果转为UTF-8字符串,再转Blob,这进一步破坏了二进制结构,生成的Blob不是有效的MP4。
  3. CryptoJS适配:CryptoJS默认处理的是WordArray类型,而非字符串,直接对文本字符串加密解密会导致数据格式不匹配。

修复后的代码

1. 加密并上传到Firebase Storage

function almacenarFicheroGrabacionVideo(file) {
  const storageRef = firebase.storage().ref('videos/' + file.name);
  const reader = new FileReader();

  reader.onload = function () {
    // 将ArrayBuffer转为CryptoJS需要的WordArray
    const fileWordArray = CryptoJS.lib.WordArray.create(reader.result);
    // 加密,得到CipherParams对象
    const encrypted = CryptoJS.AES.encrypt(fileWordArray, getCookie('key'));
    // 将加密结果转为Base64字符串(适合存储)
    const encryptedBase64 = encrypted.toString();

    // 上传Base64字符串到Firebase,指定格式为base64
    const task = storageRef.putString(encryptedBase64, 'base64');

    task.on('state_changed', 
      (snapshot) => { /* 进度处理 */ },
      (err) => { console.error('上传错误:', err); },
      () => { console.log("文件上传完成"); }
    );
  };

  // 用readAsArrayBuffer读取二进制文件,保留原始数据
  reader.readAsArrayBuffer(file);
}

2. 解密并在HTML5 Video中播放

$scope.verVideo = function() {
  const videoRef = firebase.storage().ref('videos/').child('Blurred Bokeh Video 2.mp4');
  
  videoRef.getDownloadURL().then((url) => {
    return fetch(url).then(res => res.text()); // 下载Base64加密字符串
  }).then((encryptedBase64) => {
    // 解密Base64字符串,得到原始的WordArray
    const decryptedWordArray = CryptoJS.AES.decrypt(encryptedBase64, getCookie('clave'));
    // 将WordArray转为Uint8Array(二进制数组)
    const decryptedBytes = new Uint8Array(decryptedWordArray.sigBytes);
    for (let i = 0; i < decryptedWordArray.sigBytes; i++) {
      const wordIndex = Math.floor(i / 4);
      const byteIndex = i % 4;
      decryptedBytes[i] = (decryptedWordArray.words[wordIndex] >> (8 * (3 - byteIndex))) & 0xff;
    }

    // 创建有效的MP4 Blob
    const videoBlob = new Blob([decryptedBytes], { type: 'video/mp4' });
    // 生成Blob URL并赋值给video标签
    const videoUrl = URL.createObjectURL(videoBlob);
    const videoNode = document.getElementsByTagName('video')[0];
    videoNode.src = videoUrl;
    videoNode.load(); // 触发视频加载

    // 如果你需要下载功能,保留这段代码
    const element = document.createElement('a');
    element.href = videoUrl;
    element.download = 'Blurred Bokeh Video 2.mp4';
    element.style.display = 'none';
    document.body.appendChild(element);
    element.click();
    document.body.removeChild(element);
  }).catch((error) => {
    console.error('处理错误:', error);
  });
};

额外说明

  • WordArray与二进制转换:CryptoJS的WordArray是其内部处理二进制的格式,我们需要手动将其转为Uint8Array才能生成有效的Blob。
  • Firebase上传格式:用putString(..., 'base64')告诉Firebase我们上传的是Base64编码的字符串,这样存储和下载时能正确解析。
  • 避免文本转换:全程不要用readAsText()或toString(CryptoJS.enc.Utf8)处理二进制数据,仅在处理真正的文本时使用。

这样修改后,视频的二进制数据会被完整保留,解密后的Blob是有效的MP4文件,就能正常在HTML5 Video标签中播放了。

内容的提问来源于stack exchange,提问作者asierta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:27:58