Vue+Flask项目中Base64解码视频触发MEDIA_ERR_SRC_NOT_SUPPORTED错误求助
Vue+Flask项目中Base64解码视频触发MEDIA_ERR_SRC_NOT_SUPPORTED错误求助
大家好,我现在在排查一个Vue+Flask视频处理应用的问题,折腾了好几天没搞定,想请教下各位大佬的思路!
问题背景与现象
我做的是前端用Vue上传视频,后端Flask处理视频(转MP4+跑ML模型),最后返回包含处理后视频Base64、分析图Base64、结果文本的JSON。现在遇到的诡异问题是:
- 用video.js播放解码后的视频时,直接触发了
MEDIA_ERR_SRC_NOT_SUPPORTED错误(界面显示Video.js的报错提示) - 但同一份JSON里的JPG图片Base64却能完美解码显示(截图里的图表就是正常显示的那张图,忽略布局错乱的问题)
相关代码片段
Vue端上传视频的请求代码
async handleFileUpload($evt) { const file = $evt.target.files[0]; if (file) { // VIDEO REQUEST const urlServer = "http://localhost:5000/analysis"; const formData = new FormData(); formData.append("file", file); // 'file'是后端接收的key (async () => { try { const result = await axios.post(urlServer, formData, { headers: { "Content-Type": "multipart/form-data" }, }); console.log(`RESULT`, result); const resultJSON = result.data; const strResult = resultJSON.string; const grafico_base64 = resultJSON.grafico; let video_base64 = resultJSON.video; console.log("RECEIVED VIDEO: ", video_base64, typeof video_base64); const extension = resultJSON.extVideo; const mimeVar = mime.lookup(extension); await db.open(); const videoData = { string: strResult, video: video_base64, grafico: grafico_base64, mimeVideo: mimeVar, }; console.log(videoData); let constId = await db.add(videoData); console.log(constId + " " + typeof constId); alert(constId); console.log("VIDEO PROCESSADO"); this.$router.push({ name: "analiseVideo", query: { idVideoAnalise: constId }, }); } catch (error) { console.error(error + "An error occurred while uploading the file."); } })(); } },
Vue端解码视频的代码
<script> import db from "../db.js"; import videojs from "video.js"; import "video.js/dist/video-js.css"; import { Buffer } from "node:buffer"; export default { name: "Player_de_Video", components: {}, data() { return { videoSource: "", }; }, async mounted() { console.log("MOUNTED VIDEOPLAYER:"); const res = await this.pegarVideo(); this.videoSource = res.videoURL; const mimeVideo = res.mime; this.graficoURL = res.graficoURL; this.$refs.imgGraf.src = this.graficoURL; this.strResult = res.strResult; const sources = [{ src: this.videoSource, type: `${mimeVideo}` }]; this.setupPlayer(sources); }, methods: { setupPlayer(sources) { //Initial videoplayer setup using data from VideoPlayer.vue this.player = videojs(this.$refs.videoplayer, { sources: sources, }); }, onVoltar() { this.$router.push("/"); }, async pegarVideo() { try { const resultData = await db.get(parseInt(this.$route.query.idVideoAnalise)); const mime = resultData.mimeVideo; const videoURL = this.base64ToURL(resultData.video, mime, "video.mp4"); console.log(`VIDEO URL: ${videoURL}`); const graficoURL = this.base64ToURL(resultData.grafico, "image/jpg"); const strResult = resultData.string; return { strResult, graficoURL, mime, videoURL }; } catch (error) { console.error("ERROR! " + error); } }, base64ToURL(base64String, mimeType) { // Decode the Base64 string try { const binaryString = Buffer.from(base64String, "base64").toString("binary"); console.log("base64 STRING: ", base64String); const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } const blob = new Blob([bytes], { type: String(mimeType) }); // Adjust the MIME type as needed // Generate a URL for the Blob and set it as the video source const url = URL.createObjectURL(blob); return url; } catch (error) { console.error("Error decoding Base64 string:", error); return null; } }, } }; </script>
我的排查思路(求补充!)
我已经试过检查前后端的Base64字符串是否一致,也确认了后端转码后的视频本地能正常播放,但就是前端解码后播放失败。有没有大佬遇到过类似的情况?为什么同一份JSON里的图片没问题,视频就不行呢?
可能的解决方案(来自社区经验)
我之前处理过类似的Base64视频播放问题,给你几个实测有效的思路:
1. 修复Base64转Blob的编码损耗问题
你当前用Buffer转二进制字符串再生成Uint8Array的方式,可能会因为编码兼容问题损坏视频数据。可以改成直接用浏览器原生API解码:
base64ToURL(base64String, mimeType) { try { // 先移除后端可能附带的data前缀(如果有的话) const pureBase64 = base64String.replace(/^data:.+;base64,/, ''); // 直接用浏览器原生API解码Base64为二进制数组 const byteChars = atob(pureBase64); const byteNumbers = new Array(byteChars.length); for (let i = 0; i < byteChars.length; i++) { byteNumbers[i] = byteChars.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); const blob = new Blob([byteArray], { type: mimeType }); return URL.createObjectURL(blob); } catch (error) { console.error("Error decoding Base64 string:", error); return null; } }
2. 确认后端视频Base64的生成逻辑
- 检查Flask后端生成视频Base64时,有没有添加
data:video/mp4;base64,前缀,如果有,前端必须先移除前缀再解码 - 后端转码后的视频,建议强制用H.264编码(浏览器兼容性最好的MP4编码格式),比如用FFmpeg转码时加上参数:
-vcodec libx264 -acodec aac
3. 开启Video.js的Debug模式排查
初始化Video.js时开启debug模式,能拿到更详细的播放错误日志:
this.player = videojs(this.$refs.videoplayer, { sources: sources, controls: true, preload: 'auto', debug: true // 开启调试,控制台会输出详细的媒体加载日志 });
备注:内容来源于stack exchange,提问作者Luís Felipe Araujo de Oliveira
相关产品推荐
相关产品推荐

