当前位置: 首页 > news >正文

将抖音视频转成MP3并下载

这篇是在上一篇的基础上写的,这篇负责抖音作者详情页的视频转声音提取,这篇需要用到后端。
本地启动后端后,在控制台输入对应代码,即可实现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 fileconst response = await axios.get(videoUrl, { responseType: 'arraybuffer' });fs.writeFileSync(videoFileName, Buffer.from(response.data));// Convert video to audio using ffmpegawait 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 clientres.download(audioFileName, (err) => {if (err) {console.error(err);res.status(500).json({ error: 'Internal server error' });}// Clean up temporary filesfs.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}`);
});

如果不想用控制台,也可以用暴力猴,暴力猴脚本如下:

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      2024-01-12
// @description  try to take over the world!
// @author       You
// @match        https://www.douyin.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=douyin.com
// @grant        none
// ==/UserScript==(function() {'use strict';// Your code here...// 目标节点var targetNode = document.querySelector('ul[data-e2e="scroll-list"]');// 初始时的li数量var initialCount = targetNode.children.length;// 配置观察器的设置var config = { childList: true };// 观察器回调var callback = function(mutationsList, observer) {// 当前的li数量var currentCount = targetNode.children.length;// 检查li数量是否增加if (currentCount > initialCount) {// 执行你的函数addWatch();console.log('添加监听器')// 更新初始时的li数量initialCount = currentCount;}};// 创建一个观察器实例并传入回调函数var observer = new MutationObserver(callback);// 使用配置和目标节点开始观察observer.observe(targetNode, config);// 给所有 li 添加监听器function addWatch() {// 获取作者的视频列表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)});}})();

相关文章:

将抖音视频转成MP3并下载

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

C程序训练:与输入有关的错误

在录入程序时有时稍不注意就可能录入错误的字符导致程序运行结果出现错误&#xff0c;下面举例说明。 下面程序的运行结果是错的&#xff0c;但程序又没有错&#xff0c;到底问题出现在哪呢&#xff1f; #include <stdio.h> int main() {FILE *fp;int i, k, n;fpfopen(…...

制作 CentOS Stream9 的U盘系统启动盘

一、简述 注:请勿用于商用&#xff0c;如有版权纠纷&#xff0c;于博主无任何关系。&#xff08;仅用于学习研究使用&#xff09; 由于CentOs Linux 7和CentOs Stream8终止日期是2024年&#xff0c;需要将系统升级到最新版本的CentOs Stream9&#xff0c;下面是刻录系统盘的操…...

Vulnhub靶机:driftingblues 1

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;driftingblues1&#xff08;10.0.2.17&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entr…...

CloudCompare——点云空间圆拟合

目录 1.概述2.软件实现3.完整操作4.算法源码5.相关代码 本文由CSDN点云侠原创&#xff0c;CloudCompare——点云空间圆拟合&#xff0c;爬虫自重。如果你不是在点云侠的博客中看到该文章&#xff0c;那么此处便是不要脸的爬虫与GPT生成的文章。 1.概述 CloudCompare软件中的To…...

解决POI报错POIXMLTypeLoader不存在的问题

问题&#xff1a; springframework.web.util.NestedServletException: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/poi/POIXMLTypeLoaderat org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet…...

关于rewriteBatchedStatements的源码分析

在之前的优惠券兑换码需求中&#xff0c;涉及批量写入问题&#xff0c;其中有一个关键的连接配置参数非常重要——rewriteBatchedStatements&#xff0c;当该值配置为true时&#xff0c;Statement将可能对批量插入sql进行重写。 何谓重写&#xff1f;原来提交的批量执行语句&a…...

自动化神器 Playwright 的 Web 自动化测试解决方案

1. 主流框架的认识 总结&#xff1a; 由于Selenium在3.x和4.x两个版本的迭代中并没有发生多大的变化&#xff0c;因此Selenium一统天下的地位可能因新框架的出现而变得不那么稳固。后续的Cypress、TestCafe、Puppeteer被誉为后Selenium时代Web UI自动化的三驾马车。但是由于这三…...

docker filebeat 将日志多级目录和多维json数据日志同步到es

注 使用的时候先调试调试配置,调试成功在尝试写入es,如果es写入失败就是es账户.密码/白名单.和index未创建的问题,细节可以留言 setup.template.priority 模板优先级 调整这个可以配置一台机器多个filebeat 容器启动 多级目录日志和多维josn日志结构 filebeat.inputs:- typ…...

【机器学习】模型参数优化工具:Optuna使用分步指南(附XGB/LGBM调优代码)

常用的调参方式和工具包 常用的调参方式包括网格搜索(Grid Search)、**随机搜索(Random Search)和贝叶斯优化(Bayesian Optimization)**等。 工具包方面&#xff0c;Scikit-learn提供了GridSearchCV和RandomizedSearchCV等用于网格搜索和随机搜索的工具。另外&#xff0c;有一…...

webview全屏处理,即插即用

去年双十一有个直播的需求&#xff0c;听起来很简单&#xff0c;技术也都很成熟&#xff0c;但是真的开始实现后&#xff0c;还是有不少坑的&#xff0c;首先第一个uc内核不支持webRTC协议&#xff0c;需要重新开发chrome内核的webview&#xff0c;其次webview全屏处理、悬浮窗…...

实录分享 | 央企大数据平台架构发展趋势与应用场景的介绍

分享嘉宾&#xff1a; 孟子涵-中国华能集团信息中心平台架构师 2021年华能就与Alluxio建立了合作&#xff0c;共同写了整个华能统一纳管的架构方案。这个方案我认为是现在我们在央企里边比较核心的一套体系&#xff0c;能让全集团所有我们认为重要的数字化资源实现真正的统一集…...

UE5 将类修改目录

有个需求&#xff0c;需要修改ue里面类的位置&#xff0c;默认在Public类下面&#xff0c;我想创建一个二级目录&#xff0c;将所有的类分好位置&#xff0c;方便查看。 上图为创建一个类所在的默认位置。 接下来&#xff0c;将其移动到一个新的目录中。 首先在资源管理器中找…...

GPT实战系列-ChatGLM3管理工具的API接口

GPT实战系列-ChatGLM3管理外部借力工具 用ChatGLM的工具可以实现很多查询接口和执行命令&#xff0c;外部工具该如何配置使用&#xff1f;如何联合它们实现大模型查询助手功能&#xff1f;例如调用工具实现股票信息查询&#xff0c;网络天气查询等助手功能。 LLM大模型相关文章…...

Python 列表、元组、字典区别

1.列表、元组和字典都是序列 2.列表字典可以修改和删除序列中的某个元素&#xff0c;而元组就是一个整体&#xff0c;不能修改和删除&#xff0c;一定要修改或删除的话&#xff0c;只能修改和删除整个元组。 3.既然元组不能删除和修改&#xff0c;有什么作用呢&#xff1f; 1…...

[足式机器人]Part2 Dr. CAN学习笔记 - Ch03 傅里叶级数与变换

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-Ch03 傅里叶级数与变换 1. 三角函数的正交性2. 周期为 2 π 2\pi 2π的函数展开为傅里叶级数3. 周期为 2 L 2L 2L的函数展开4. 傅里叶级数的复数形式5. 从傅里叶级数推导傅里叶变换FT6. 总结 1. …...

你想使用域名访问一个ip的网页,你应该怎么办呢?

你想使用域名访问一个ip的网页,你应该怎么办呢? eg:你想用https://test.com/访问http://1.1.1.1/方法: eg:你想用https://test.com/访问http://1.1.1.1/ 方法: 1.首先,如果你是服务器的管理者,你需要在服务器的官网申请一个test.com的域名,然后在官网将域名映射到1.1.1.1上. …...

SAP存放状态的几个常用表

SAP存放状态的几个常用表 在sap中&#xff0c;包括订单、项目、计划、设备主数据等&#xff0c;存在审批流程的业务单据&#xff0c;这些业务对象都会有状态的属性&#xff0c;用来控制和约束该业务当前的操作。 主要的表 JEST&#xff1a;存放了该对象编号的当前状态 JCDS…...

AUTO SEG-LOSS SEARCHING METRIC SURROGATES FOR SEMANTIC SEGMENTATION

AUTO SEG-LOSS: 搜索度量替代语义分割 论文链接&#xff1a;https://arxiv.org/abs/2010.07930 项目链接&#xff1a;https://github.com/fundamentalvision/Auto-Seg-Loss ABSTRACT 设计合适的损失函数是训练深度网络的关键。特别是在语义分割领域&#xff0c;针对不同的场…...

openssl3.2 - 官方demo学习 - 索引贴

文章目录 openssl3.2 - 官方demo学习 - 索引贴概述笔记工程的搭建和调试环境BIOBIO - client-arg.cBIO - client-conf.cBIO - saccept.cBIO - sconnect.cBIO - server-arg.cBIO - server-cmod.cBIO - server-conf.cBIO - 总结certsciphercipher - aesccm.ccipher - aesgcm.ccip…...

Slickflow.NET 基于 AI 大模型实现智能客服多轮问答系统

正文 异步/等待解决了什么问题&#xff1f; 在传统同步I/O操作中&#xff08;如文件读取或Web API调用&#xff09;&#xff0c;调用线程会被阻塞直到操作完成。这在UI应用中会导致界面冻结&#xff0c;在服务器应用中则造成线程资源的浪费。async/await通过非阻塞的异步操作解…...

零基础玩转Ostrakon-VL-8B:餐饮零售AI视觉助手部署与使用

零基础玩转Ostrakon-VL-8B&#xff1a;餐饮零售AI视觉助手部署与使用 1. 为什么选择Ostrakon-VL-8B&#xff1f; 在餐饮零售行业&#xff0c;每天都有大量视觉数据需要处理&#xff1a;货架商品、门店环境、价格标签等。传统的人工检查方式效率低、成本高且容易出错。Ostrako…...

STM32主从定时器实战:用CubeMX搞定PWM移相+动态调占空比(附G474配置)

STM32主从定时器实战&#xff1a;CubeMX图形化配置PWM移相与动态调占空比 在电力电子和电机控制领域&#xff0c;精确的PWM信号控制是系统高效运行的关键。对于需要多路相位可调PWM的应用场景&#xff0c;如交错并联DC/DC变换器、三相逆变器等&#xff0c;传统的手动寄存器配置…...

Minica 源码解读:深入理解证书生成的核心算法

Minica 源码解读&#xff1a;深入理解证书生成的核心算法 【免费下载链接】minica minica is a small, simple CA intended for use in situations where the CA operator also operates each host where a certificate will be used. 项目地址: https://gitcode.com/gh_mirr…...

Python中的生成器和迭代器:原理与实践

Python中的生成器和迭代器&#xff1a;原理与实践 一、背景与动机 在Python编程中&#xff0c;处理大量数据时&#xff0c;内存管理是一个常见的挑战。生成器&#xff08;Generators&#xff09;和迭代器&#xff08;Iterators&#xff09;为解决这一问题提供了一种高效的方式&…...

OpenClaw:四大使用挑战与破局思路

子玥酱 &#xff08;掘金 / 知乎 / CSDN / 简书 同名&#xff09; 大家好&#xff0c;我是 子玥酱&#xff0c;一名长期深耕在一线的前端程序媛 &#x1f469;‍&#x1f4bb;。曾就职于多家知名互联网大厂&#xff0c;目前在某国企负责前端软件研发相关工作&#xff0c;主要聚…...

高效管理惠普OMEN游戏本:OmenSuperHub全面解析与实战指南

高效管理惠普OMEN游戏本&#xff1a;OmenSuperHub全面解析与实战指南 【免费下载链接】OmenSuperHub 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub OmenSuperHub是一款专为惠普OMEN系列游戏本设计的轻量级系统管理工具&#xff0c;它通过替代原厂Omen Ga…...

5分钟完成专业级黑苹果配置:OpCore Simplify终极简化指南

5分钟完成专业级黑苹果配置&#xff1a;OpCore Simplify终极简化指南 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 你是否曾经为黑苹果配置的复杂性…...

开源AI助手竟能自主建频道、做视频?李宏毅深度解析“小龙虾”的神秘工作原理!

最近全网爆火的「养龙虾」到底是什么&#xff1f;为什么一个开源的 AI 助理项目&#xff0c;能让 AI 自己创建 YouTube 频道、自己做教学视频、24 小时自主干活&#xff1f; 台大李宏毅老师的这堂《解剖小龙虾 — 以 OpenClaw 为例介绍 AI Agent 的运作原理》&#xff0c;用最通…...

AT32F435_437_USB_MSC_SDIO:实现高效SD卡U盘功能的开发指南

1. 从零开始&#xff1a;AT32F435/437的USB MSC功能初探 第一次接触AT32F435/437的USB大容量存储设备(MSC)功能时&#xff0c;我完全被它的实用性惊艳到了。想象一下&#xff0c;你的嵌入式设备突然变身成电脑上的U盘&#xff0c;可以直接拖拽文件读写SD卡&#xff0c;这对数据…...