如何将Blob转换为MP4文件上传至WordPress,解决文件类型不允许报错
修复方案
问题根源
- 核心错误:
localStorage仅支持存储字符串类型,直接存储Blob对象会被自动转为[object Blob]无效字符串,取出的内容不是原始二进制数据,因此type属性为undefined,生成的File对象内容异常,PHP识别为默认的application/octet-stream,触发WordPress文件类型校验失败 - 次要逻辑错误:代码在判断
videoBlob是否为null之前就生成了videoFile对象,逻辑顺序不合理
前端修复
方案1:Base64转存localStorage(适合小于100M的小体积视频)
首先修改Blob存储逻辑,将Blob转为Base64后存入localStorage:
// 存储Blob时的代码示例 const reader = new FileReader(); reader.readAsDataURL(originalVideoBlob); // originalVideoBlob是你录制生成的原始Blob reader.onloadend = () => { localStorage.setItem('videoBlobBase64', reader.result); }
然后修改上传逻辑,从Base64还原Blob再生成File:
var formData = new FormData(form.get(0)); formData.append('action', 'hm_share_your_song_submission'); formData.append('email', emailInput.val()) let videoBase64 = localStorage.getItem('videoBlobBase64'); if(videoBase64 !== null) { // Base64转Blob const [metaPart, base64Data] = videoBase64.split(','); const mimeType = metaPart.match(/:(.*?);/)[1] || 'video/mp4'; const byteCharacters = atob(base64Data); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); } const videoBlob = new Blob([new Uint8Array(byteNumbers)], { type: mimeType }); // 生成合法File对象 const videoFile = new File([videoBlob], 'video-name.mp4', { lastModified: Date.now(), type: 'video/mp4' }); formData.append('recorded-video-file', videoFile); localStorage.removeItem('videoBlobBase64'); } $.ajax({ url: ajax_url, data: formData, processData: false, contentType: false, type: 'POST', success: function(res) { console.log(res); } });
方案2:IndexedDB存储(适合大体积视频)
如果视频体积超过100M,Base64会带来30%左右的体积膨胀,建议改用IndexedDB直接存储Blob对象,无需转码,性能更好。
后端兼容修复(前端修复后仍报错时使用)
WordPress部分场景下会出现MIME类型识别异常,可将以下代码添加到主题functions.php文件或者自定义插件中,放开MP4上传校验:
// 新增MP4格式到允许上传列表 add_filter('upload_mimes', function($existing_mimes) { $existing_mimes['mp4'] = 'video/mp4'; return $existing_mimes; }); // 修复MP4文件MIME识别错误问题 add_filter('wp_check_filetype_and_ext', function($check_result, $file_path, $file_name, $allowed_mimes) { $file_info = wp_check_filetype($file_name, $allowed_mimes); if ($file_info['ext'] === 'mp4' && $file_info['type'] === 'video/mp4') { $check_result['ext'] = 'mp4'; $check_result['type'] = 'video/mp4'; } return $check_result; }, 10, 4);
另外请确认服务器php.ini配置中upload_max_filesize和post_max_size参数大于上传的视频体积,避免文件大小超标导致上传失败。
内容的提问来源于stack exchange,提问作者cgrant
相关产品推荐
相关产品推荐

