index.vue 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <template>
  2. <div class="ffmpeg">
  3. <input type="file" @change="onFileChange" accept="video/mp4" />
  4. <button @click="extractAudio()" :disabled="!videoFile">提取音频</button>
  5. <audio v-if="audioUrl" :src="audioUrl" controls></audio>
  6. </div>
  7. </template>
  8. <script>
  9. import FFmpeg from "@ffmpeg/ffmpeg";
  10. const { createFFmpeg, fetchFile } = FFmpeg;
  11. const ffmpeg = createFFmpeg({
  12. corePath: './static/ffmpeg/ffmpeg-core.js',
  13. log: true,
  14. });
  15. export default {
  16. data() {
  17. return {
  18. videoFile: null,
  19. audioUrl: null
  20. };
  21. },
  22. methods: {
  23. async onFileChange(event){
  24. this.videoFile = event.target.files[0];
  25. },
  26. async extractAudio(file) {//提取音频
  27. return new Promise(async(resolve) => {
  28. try {
  29. file = file || this.videoFile;
  30. if (!file){
  31. window.parent.postMessage({code:1,msg:'请选择视频文件'},'*');
  32. resolve({code:1,msg:'请选择视频文件'});
  33. return;
  34. };
  35. // 加载FFmpeg
  36. if (!ffmpeg.isLoaded()) {
  37. await ffmpeg.load();
  38. }
  39. // 将视频文件加载到FFmpeg
  40. ffmpeg.FS("writeFile", "input.mp4", await fetchFile(file));
  41. // 提取音频
  42. await ffmpeg.run(
  43. "-i",
  44. "input.mp4",
  45. "-q:a",
  46. "0",
  47. "-map",
  48. "a",
  49. "output.mp3"
  50. );
  51. // 从FFmpeg文件系统中读取音频文件
  52. const data = ffmpeg.FS("readFile", "output.mp3");
  53. // 创建音频URL
  54. let audioBlob = new Blob([data.buffer], { type: "audio/mp3" });
  55. audioBlob.name = "output.mp3"
  56. if(this.videoFile){
  57. this.audioUrl = URL.createObjectURL(audioBlob);
  58. }
  59. let resultFile = new File([audioBlob], "output.mp3", { type: "audio/mp3" });
  60. window.parent.postMessage({code:0,msg:'提取音频成功',file:resultFile},'*');
  61. resolve({file:audioBlob});
  62. } catch (error) {
  63. console.log(error);
  64. window.parent.postMessage({code:1,msg:'提取音频失败',error:error},'*');
  65. resolve({code:1,msg:'提取音频失败',error:error});
  66. }
  67. })
  68. },
  69. },
  70. mounted(){
  71. window.addEventListener('message',(e)=>{
  72. let _data = e.data;
  73. if(_data.type === 'extractAudio'){
  74. this.extractAudio(_data.file);
  75. }
  76. })
  77. }
  78. };
  79. </script>
  80. <style scoped>
  81. .ffmpeg {
  82. width: 100vw;
  83. height: 100vh;
  84. background-color: #fff;
  85. }
  86. </style>