nginx
location ~* \.avi$ { add_header Cross-Origin-Opener-Policy "same-origin"; add_header Cross-Origin-Embedder-Policy "require-corp"; }
vue.config.js
devServer: { proxy: {}, // 可能会影响图片的加载 headers: { "Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Embedder-Policy": "require-corp", }, }
package.json
"dependencies": { "@ffmpeg/core": "0.9.0", "@ffmpeg/ffmpeg": "0.9.8", }
从 node_modules/@ffmpeg 的 dist 目录中找到以下文件放入 public/js/
ffmpeg-core.js ffmpeg-core.wasm ffmpeg-core.worker.js
AviPlayer.vue (节选)
import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg"; export default { data() { return { src: null, loading: false, // false 或 xx% }; }, computed: { ext() { let self = this; let ext = null; if (self.src) { ext = self.src .replace(/.*(?=\.w+)/, "") // http://a/b/c/d.e?f=g -> .e?f=g .replace(/\?.*/, ""); // .e?f=g -> .e ext = ext && ext.toLowerCase(); } return ext; }, }, methods: { async convertAvi2mp4(aviSrc) { let self = this; let src = aviSrc; try { const ffmpeg = createFFmpeg({ log: true, corePath: "/js/ffmpeg-core.js", // 不写这行时会从 CDN 中加载 }); ffmpeg.setProgress(({ ratio }) => { let progress = Math.floor(ratio * 100); progress = progress < 100 ? `${progress}%` : "准备中"; self.loading = progress; }); await ffmpeg.load(); ffmpeg.FS("writeFile", `videoFile${self.ext}`, await fetchFile(src)); await ffmpeg.run("-i", `videoFile${self.ext}`, "videoFile.mp4"); const data = ffmpeg.FS("readFile", "videoFile.mp4"); src = URL.createObjectURL(new Blob([data.buffer], { type: "video/mp4" })); } catch (e) { console.log("avi2mp4.fail", e); } }, }, };