将抖音视频转成MP3并下载

发布时间:2024年01月12日

这篇是在上一篇的基础上写的,这篇负责抖音作者详情页的视频转声音提取,这篇需要用到后端。
本地启动后端后,在控制台输入对应代码,即可实现hover在封面上,按d一键下载音频

  • 控制台代码

  // 获取作者的视频列表
  var liElements = document.querySelectorAll('ul[data-e2e="scroll-list"] li');

  // 添加鼠标悬停事件监听器
  liElements.forEach(function(li) {
    li.addEventListener('mouseenter', function() {
      // 添加键盘按下事件监听器
      document.addEventListener('keydown', keydownHandler);
    });

    li.addEventListener('mouseleave', function() {
      // 移除键盘按下事件监听器
      document.removeEventListener('keydown', keydownHandler);
    });
  });

  // 处理键盘按下事件
  function keydownHandler(event) {
    // 判断按下的键是否为 'D' 键,keyCode为 '68'
    if (event.keyCode === 68) {
      // 获取下载链接
      var sourceTag = document.querySelector('.basePlayerContainer xg-video-container > video > source:nth-child(1)');
      const alt = document.querySelector('.basePlayerContainer').previousElementSibling.querySelector('img').getAttribute('alt');
	  // 找到第一个冒号并截取之后的部分
	  let contentAfterColon = alt.includes(':') ? 
	  	alt.split(':').slice(1).join(':'):
	  	alt;
	  // 去除所有的.和空格
	  let resultString = contentAfterColon.replace(/[.\s]/g, '');
	  // 如果最终结果为空,替换为'空'
	  const name = resultString === '' ? '空' : resultString;
	
	  // 提取src属性值
	  var url = sourceTag.getAttribute('src');
      // 执行下载操作,这里使用一个假设的下载函数
      downloadFile(url, name);
    }
  }

  function downloadFile(url, name) {
  // 发送POST请求到后台接口
  fetch('http://localhost:3000/convert', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ videoUrl: url }),
  })
    .then((response) => response.blob())
    .then((blob) => {
      // 创建一个临时的<a>元素用于下载
      const a = document.createElement('a');
      const url = window.URL.createObjectURL(blob);
      a.href = url;
      a.download = name + '.mp3';

      // 触发点击事件以启动下载
      a.click();

      // 释放URL对象
      window.URL.revokeObjectURL(url);
    })
    .catch((error) => {
      console.error('Error:', error);
      alert('下载失败,原因:' + error)
    });
}


  • 后端 node 代码
const express = require('express');
const axios = require('axios');
const ffmpeg = require('fluent-ffmpeg');
const fs = require('fs');
const path = require('path');
const cors = require('cors');
const app = express();

app.use(express.json());
// 允许所有域的请求
app.use(cors());

app.post('/convert', async (req, res) => {
  try {
    const { videoUrl } = req.body;

    if (!videoUrl) {
      return res.status(400).json({ error: 'Missing videoUrl parameter' });
    }

    const videoFileName = 'inputVideo.mp4';
    const audioFileName = 'outputAudio.mp3';

    // Download the video file
    const response = await axios.get(videoUrl, { responseType: 'arraybuffer' });
    fs.writeFileSync(videoFileName, Buffer.from(response.data));

    // Convert video to audio using ffmpeg
    await new Promise((resolve, reject) => {
      ffmpeg()
        .input(videoFileName)
        .audioCodec('libmp3lame')
        .toFormat('mp3')
        .on('end', () => resolve())
        .on('error', (err) => reject(err))
        .save(audioFileName);
    });

    // Send the converted audio file to the client
    res.download(audioFileName, (err) => {
      if (err) {
        console.error(err);
        res.status(500).json({ error: 'Internal server error' });
      }

      // Clean up temporary files
      fs.unlinkSync(videoFileName);
      fs.unlinkSync(audioFileName);
    });
  } catch (err) {
    console.error(err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

文章来源:https://blog.csdn.net/qq_41569151/article/details/135548796
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。