批量提取某音文案

news2024/11/13 16:10:50

牙叔教程 简单易懂

我想学习某个人的文案, 怎么把它的文案全下载下来?

  1. 批量下载视频和音频
  2. 批量音频转文字

下载视频和音频

我在github找到的是这个仓库

GitHub - Johnserf-Seed/TikTokDownload: 抖音去水印批量下载用户主页作品、喜欢、图文、音频

经过实际测试, 可以使用, 只是失败的频率略高.

获取用户信息的时候, 尝试了5次才正确获取到用户信息,

只有获取到用户信息, 才能下载到视频;

虽然失败的概率有点高, 但是也仅是要多按几下 ↑ 和 回车键, 也不费啥事.

如果, 填写了cookie, 那么成功率大大提高, 不懂的话就看仓库的 issue.

这是下载好的视频和音频, 可以看到mp4和mp3的后缀名,

音频是直接下载下来的, 不是后期提取的.

文件 conf.ini 默认是不下载音频的, 所以要改一下.

music后面默认是no, 改成yes

[music]
# 视频原声保存(yes|no)
music = yes

其他的就照着README.md做就可以了


语音转文字

一共三种方案

  • 某讯
  • 微软
  • 有道

某讯

我看了一下某讯的价格, 70块30个小时,


微软

微软也有语音转文字的服务, 就是要绑卡, 绑卡的话, 某宝是几十块左右;


网易

网易, 他是2块钱一个小时, 这个就很人性化,

某讯开始就是30个小时, 我又用不了那么多, 至少我现在用不了.

批量自动化的时候, 你才需要买它, 你单独转的话, 可以直接使用

网易见外 网易见外工作台

网易见外不用花一分钱, 但是依然很好用


那么今天给大家试试两种方案

  • 微软
  • 网易 - 长语音转写服务

微软

如果你没有卡, 可以去某宝搞;

如果你不会创建微软的服务, 可以看这个教程

文本转语音-微软Azure-一步一步教你从注册到使用

文本转语音-微软Azure-一步一步教你从注册到使用


我们要把音频转文字, 所以选择第二个, 脱机字幕

他的文档有代码, 直接复制黏贴就可以使用了

代码在此

语音转文本快速入门 - 语音服务 - Azure Cognitive Services | Microsoft Learn

下面是我的代码例子

语音转文字, 分两步

  • mp3转wav
  • wav转文字
// 此示例支持最多 30 秒的音频。
const fs = require("fs");
const sdk = require("microsoft-cognitiveservices-speech-sdk");
const { exec } = require("child_process");

const { secretKey: YourSubscriptionKey, region: YourServiceRegion, mp3FilePath } = require("./config.js");

let wavFilePath = mp3FilePath.replace(".mp3", ".wav");
let mp3ToWavCmd = `ffmpeg -i "${mp3FilePath}" "${wavFilePath}"`;

const speechConfig = sdk.SpeechConfig.fromSubscription(YourSubscriptionKey, YourServiceRegion);
speechConfig.speechRecognitionLanguage = "zh-CN";

async function recognizeSpeechFromFile() {
  let speechRecognizer;
  try {
    // Convert MP3 to WAV
    await new Promise((resolve, reject) => {
      exec(mp3ToWavCmd, (error) => {
        if (error) {
          console.error(`Error converting MP3 to WAV: ${error.message}`);
          reject(error);
        } else {
          console.log("MP3 file converted to WAV successfully.");
          resolve();
        }
      });
    });

    const audioConfig = sdk.AudioConfig.fromWavFileInput(fs.readFileSync(wavFilePath));
    speechRecognizer = new sdk.SpeechRecognizer(speechConfig, audioConfig);
    await new Promise((resolve, reject) => {
      speechRecognizer.recognizeOnceAsync((result) => {
        switch (result.reason) {
          case sdk.ResultReason.RecognizedSpeech:
            console.log(`RECOGNIZED: Text=${result.text}`);
            resolve(result.text);
            break;
          case sdk.ResultReason.NoMatch:
            console.log("NOMATCH: Speech could not be recognized.");
            reject("NOMATCH");
            break;
          case sdk.ResultReason.Canceled: {
            const cancellation = sdk.CancellationDetails.fromResult(result);
            console.log(`CANCELED: Reason=${cancellation.reason}`);

            if (cancellation.reason === sdk.CancellationReason.Error) {
              console.log(`CANCELED: ErrorCode=${cancellation.ErrorCode}`);
              console.log(`CANCELED: ErrorDetails=${cancellation.errorDetails}`);
              console.log("CANCELED: Did you set the speech resource key and region values?");
            }
            reject("CANCELED");
            break;
          }
        }
      });
    });
  } catch (error) {
    console.error("Error during recognition:", error);
  } finally {
    if (speechRecognizer) {
      speechRecognizer.close();
    }
  }
}

recognizeSpeechFromFile();

不过, 还是应该看看文档再动手,

这是微软文字转语音的文档

使用语音转文本添加字幕 - 语音服务 - Azure Cognitive Services | Microsoft Learn


上面的代码只支持30s, 如果改成这种订阅式的代码, 就支持更长时间了

我们将订阅从 SpeechRecognizer 发送的事件:

recognizing:事件信号,包含中间识别结果。
recognized:包含最终识别结果的事件信号,指示成功的识别尝试。
sessionStopped:事件信号,指示识别会话的结束(操作)。
canceled:事件信号,包含已取消的识别结果。 这些结果指示因直接取消请求而取消的识别尝试。 或者,它们指示传输或协议失败。
speechRecognizer.recognizing = (s, e) => {
    console.log(`RECOGNIZING: Text=${e.result.text}`);
};

speechRecognizer.recognized = (s, e) => {
    if (e.result.reason == sdk.ResultReason.RecognizedSpeech) {
        console.log(`RECOGNIZED: Text=${e.result.text}`);
    }
    else if (e.result.reason == sdk.ResultReason.NoMatch) {
        console.log("NOMATCH: Speech could not be recognized.");
    }
};

speechRecognizer.canceled = (s, e) => {
    console.log(`CANCELED: Reason=${e.reason}`);

    if (e.reason == sdk.CancellationReason.Error) {
        console.log(`"CANCELED: ErrorCode=${e.errorCode}`);
        console.log(`"CANCELED: ErrorDetails=${e.errorDetails}`);
        console.log("CANCELED: Did you set the speech resource key and region values?");
    }

    speechRecognizer.stopContinuousRecognitionAsync();
};

speechRecognizer.sessionStopped = (s, e) => {
    console.log("\n    Session stopped event.");
    speechRecognizer.stopContinuousRecognitionAsync();
};

下载的数据

mp4 + mp3 + txt

语音转的文字

这是一个5分钟的电影解说, 1412个字,

如果是小说, 估计字数得翻倍, 这个是电影, 有一些时间是放的电影片段, 没有台词.


ffmpge

由于微软默认支持wav, 所以我们需要转换语音格式, 把mp3转成wav,

因此, 需要在电脑上安装 FFMPEG, 不会装的可以百度 Windows 10系统下安装FFmpeg教程详解

ffmpeg使用注意事项

  • 如果文件存在, 那么命令会卡住

网易

长语音转写文档

产品文档-语音识别ASR服务


创建应用时, 选择 长语音转写


网易文档中的错误

这个sliceId是 大写的i (爱),

但是他这个文档里是小写的l (矮楼)


文档中的响应结果, 是写文档的人复制黏贴的.

比如, 这几张响应结果, msg都是sucess


实际上, msg的值都是 null


文件上传的时候, 这里是字节数组, 而不是text

你就说这样写文档快不快吧, 类型全是text


网易长语音转文本的代码

const fs = require("fs");
const axios = require("axios");
const path = require("path");
const crypto = require("crypto");
const FormData = require("form-data");
const util = require("util");
const { wangyi } = require("./config.js");
const stat = util.promisify(fs.stat);

async function getFileSize(filePath) {
  try {
    const stats = await stat(filePath);
    const fileSizeInBytes = stats.size;
    console.log(`文件大小: ${fileSizeInBytes} 字节`);
    return fileSizeInBytes;
  } catch (err) {
    console.error("发生错误:", err);
  }
}

async function wangYiRcognizeSpeechFromFile(audioFilePath) {
  let fileName = path.basename(audioFilePath);
  // 请在这里设置您的应用ID和应用密钥
  const appKey = wangyi.appKey;
  const appSecret = wangyi.secretKey;
  let fileSize = await getFileSize(audioFilePath);
  let salt = uuidv4();
  let curtime = Math.floor(Date.now() / 1000);
  let sign = crypto
    .createHash("sha256")
    .update(appKey + salt + curtime + appSecret)
    .digest("hex");

  let formData = new FormData();
  formData.append("salt", salt);
  formData.append("type", 1);
  formData.append("appKey", appKey);
  formData.append("sliceNum", "1");
  formData.append("name", fileName);
  formData.append("fileSize", fileSize);
  formData.append("curtime", curtime);
  formData.append("langType", "zh-CHS");
  formData.append("sign", sign);
  formData.append("signType", "v4");
  formData.append("format", "mp3");
  formData.append("noitn", 1);

  const prepareResponse = await axios.post("http://openapi.youdao.com/api/audio/prepare", formData, { headers: formData.getHeaders() });

  if (prepareResponse.data.errorCode !== "0") {
    throw new Error(`Prepare failed: ${prepareResponse.data.msg}`);
  }
  console.log("准备上传");
  console.log(prepareResponse.data);
  const taskid = prepareResponse.data.result;
  formData = new FormData();
  formData.append("q", taskid);
  formData.append("appKey", appKey);
  salt = uuidv4();

  formData.append("salt", salt);
  formData.append("curtime", curtime);

  sign = crypto
    .createHash("sha256")
    .update(appKey + salt + curtime + appSecret)
    .digest("hex");

  formData.append("sign", sign);
  formData.append("signType", "v4");
  formData.append("sliceId", "1");
  // 判断文件是否存在
  if (!fs.existsSync(audioFilePath)) {
    throw new Error(`File not found: ${audioFilePath}`);
  }
  // 打印文件大小
  console.log(`文件大小: ${fs.statSync(audioFilePath).size} 字节`);
  formData.append("file", fs.readFileSync(audioFilePath), { contentType: "audio/mp3", filename: fileName });
  formData.append("type", "1");

  const uploadResponse = await axios.post("http://openapi.youdao.com/api/audio/upload", formData, { headers: formData.getHeaders() });

  if (uploadResponse.data.errorCode !== "0") {
    throw new Error(`Upload failed: ${uploadResponse.data.msg}`);
  }
  console.log("上传文件");
  console.log(uploadResponse.data);
  /* -------------------------------------------------------------------------- */
  formData = new FormData();
  formData.append("q", taskid);
  formData.append("appKey", appKey);
  salt = uuidv4();
  formData.append("salt", salt);
  curtime = Math.floor(Date.now() / 1000);
  formData.append("curtime", curtime);
  sign = crypto
    .createHash("sha256")
    .update(appKey + salt + curtime + appSecret)
    .digest("hex");

  formData.append("sign", sign);
  formData.append("signType", "v4");

  const mergeResponse = await axios.post("http://openapi.youdao.com/api/audio/merge", formData, { headers: formData.getHeaders() });

  if (mergeResponse.data.errorCode !== "0") {
    throw new Error(`Merge failed: ${mergeResponse.data.msg}`);
  }
  console.log("合并文件");
  console.log(mergeResponse.data);
  // process.exit(0);

  let progressResponse;
  do {
    await new Promise((resolve) => setTimeout(resolve, 60 * 1000));
    formData = new FormData();
    formData.append("q", taskid);
    formData.append("appKey", appKey);
    salt = uuidv4();
    formData.append("salt", salt);
    curtime = Math.floor(Date.now() / 1000);
    formData.append("curtime", curtime);
    sign = crypto
      .createHash("sha256")
      .update(appKey + salt + curtime + appSecret)
      .digest("hex");

    formData.append("sign", sign);
    formData.append("signType", "v4");
    progressResponse = await axios.post("http://openapi.youdao.com/api/audio/get_progress", formData, { headers: formData.getHeaders() });
    console.log("获取进度");
    console.log(progressResponse.data);
  } while (progressResponse.data.result[0].status !== "9");

  formData = new FormData();
  formData.append("q", taskid);
  formData.append("appKey", appKey);
  salt = uuidv4();
  formData.append("salt", salt);
  curtime = Math.floor(Date.now() / 1000);
  formData.append("curtime", curtime);
  sign = crypto
    .createHash("sha256")
    .update(appKey + salt + curtime + appSecret)
    .digest("hex");

  formData.append("sign", sign);
  formData.append("signType", "v4");

  const resultResponse = await axios.post("http://openapi.youdao.com/api/audio/get_result", formData, { headers: formData.getHeaders() });

  if (resultResponse.data.errorCode !== "0") {
    throw new Error(`Get result failed: ${resultResponse.data.msg}`);
  }
  console.log("获取结果");
  console.log(resultResponse.data);
  const text = resultResponse.data.result.map((item) => item.sentence).join("\n");
  fs.writeFileSync(fileName, text);
}

// 生成 UUID v4
function uuidv4() {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
    var r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

网易与微软对比

微软

网易

获取结果需要轮询

不需要

需要

准确度

略高

略低

接口方便程度

一个订阅模式, 每秒钟都会给你返回信息, 直到任务完成,

感觉比网易方便一些

四个步骤: 准备, 上传, 获取状态, 获取结果

需要mp3转wav

需要

不需要

建议用哪个

都可以, 都差不多

写代码利器

本文的代码大部分是 ChatGPT4 写的,

你如果不想动手, 可以像我一样, 直接复制黏贴网易有道云的文档, 然后叫chatgpt给你代码

就像这样

我用的 ChatGPT4, 是这个

ChatGPT联网版, Stable Diffusion画图, 这个星球全都有, 低调使用, 别外传

声明

本文仅供学习研究使用, 禁止用于其他用途


微信公众号 牙叔教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/536194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[FMC149】基于VITA57.1标准的16通道65MSPS 14位直流耦合AD采集FMC子卡

板卡概述 FMC149是一款16通道65MHz采样率14位直流耦合AD采集FMC子卡,符合VITA57.1规范,可以作为一个理想的IO模块耦合至FPGA前端,16通道AD通过FMC连接器(HPC)连接至FPGA从而大大降低了系统信号延迟。 该板卡支持板上可…

【STL】vector的模拟实现

目录 前言 结构解析 构造析构 构造 默认构造 初始化成 n 个 val 以迭代器区间构造 拷贝构造 析构 运算符重载 赋值重载 下标访问 迭代器 const迭代器 容量操作 查看大小和容量 容量修改 数据修改 尾插尾删 指定位置插入和删除 insert erase 清空 判空 …

Redis系列--主从复制

一、redis主从复制介绍 在 Redis 复制的基础上,使用和配置主从复制非常简单,能使得从 Redis 服务器(下文称 slave)能精确得复制主 Redis 服务器(下文称 master)的内容。每次当 slave 和 master 之间的连接断…

chatGpt 对前端的开发帮助

chatGpt 是 什么? ChatGPT是一个基于GPT-3的聊天机器人,可以用来帮助前端开发人员解决各种问题。它可以回答关于前端开发的各种问题,包括HTML、CSS、JavaScript、React、Vue等等。它可以提供代码片段、示例代码、文档链接等等,帮助…

javascript 创建 array

javascript 创建 array 补一下笔记,constructor 这块之前还真没怎么太琢磨过…… 最常见的就是 literal array syntax: const arr1 [1, 2, 3];console.log(arr1);这是最主流的用法,也是目前最推荐的用法,原因有以下几点: 这是…

SOLIDWORKS 30个使用技巧

很多人在学习SolidWorks时,会有很多疑问,都不知道如何解答,所以走了很多弯路。今天,我们就来讲讲在学习SolidWorks中的那些小技巧吧! 1、按“空格键:”弹出快捷菜单双击某一视图,模型将转向某一…

3分钟带你入门接口自动化测试(建议收藏)

接口测试简介 1) 什么是接口测试 开始学习接口自动化测试之前,我们先要来了解什么是接口,以及什么是接口测试。 我们都知道,测试从级别上划分可以分为 ◆ 组件测试 ◆ 集成测试 ◆ 系统测试 ◆ 验收测试 其中在集成测试这个…

Vue3系列——computed、watch

目录 Computed watch 侦听单个数据 侦听多个数据 immediate deep 精确侦听对象的某个属性 Computed 计算属性computed是依赖于使用它的数据,当数据发生变化时,自定义方法重新调用执行一次计算属性,监测的是依赖值,依赖值不…

GPT专业应用:生成会议通知

正文共 917 字,阅读大约需要 3 分钟 公务员/文秘必备技巧,您将在3分钟后获得以下超能力: 快速生成会议通知 Beezy评级 :B级 *经过简单的寻找, 大部分人能立刻掌握。主要节省时间。 推荐人 | Kim 编辑者 | Linda ●图…

Qt6之万能数据类型QVariant详解

QVariant,被称为万能数据类型,实际上它是类似C的联合union类型。简单的说自定义性能强就像一个盒子几乎可以让你放任意的qt类型,同时可以轻松构造任意类型的任意复杂数据结构,但请注意复杂类型意味着性能和效率的让步。 qt6在文档…

好的CRM系统拥有哪些功能

随着客户对企业的重要性越来越高,他们需要一款好用的CRM系统来帮助他们管理客户、销售管道和营销活动。那么国内目前比较好的CRM系统有哪些?下面我们来详细说一下。 国内有很多知名的CRM系统,从本土品牌到国际厂商都有。选择 CRM以高性价比、…

永久免费域名PP.UA最新注册指南

PP.UA是乌克兰个人的域名,支持CF托管,可用于建站或者个人代理用,其永久免费(每年续期即可)。不过网上关于这个免费域名的申请教程已经全部过期了,多数都是2021年的,本次我来做一个最新的可用教程…

【Redis】Redis 命令之 String

文章目录 ⛄String 介绍⛄命令⛄对应 RedisTemplate API⛄应用场景 ⛄String 介绍 String 类型,也就是字符串类型,是Redis中最简单的存储类型。 其value是字符串,不过根据字符串的格式不同,又可以分为3类: ● string&…

flutter系列之:使用AnimationController来控制动画效果

文章目录 简介构建一个要动画的widget让图像动起来总结 简介 之前我们提到了flutter提供了比较简单好用的AnimatedContainer和SlideTransition来进行一些简单的动画效果,但是要完全实现自定义的复杂的动画效果,还是要使用AnimationController。 今天我…

H桥电机驱动芯片CS9029C可pin对pin兼容DRV8841

CS9029C为打印机和其它电机一体化应用提供一种双通道集成电机驱动方案。CS9029C有两路H桥驱动,最大输出2.5A,可驱动两路刷式直流电机,或者一路双极步进电机,或者螺线管或者其它感性负载。双极步进电机可以以整步、2细分、4细分运行…

未来源码|Dart 3正式发布:100%健全的空值安全、迄今为止最大版本

推荐语: 自从 Flutter Forword 发布了 Dart 3α 预览 之后,大家对 Dart 3 的正式发布就一直翘首以待,这不仅仅是 Dart 版本号追上了 Flutter 版本号,更是 Dart 在 2.0 之后迎来的最大一次更新。Dart 3将只支持健全的Null安全&am…

微信小程序等待wx.requestPayment的回调函数执行完后再执行后续代码

async/await & Promise的再认识 背景 在开发微信小程序过程中,遇到如下需求: 需要等待wx.requestPayment的回调函数执行完后再执行后续代码 这是因为在调用wx.requestPayment之后,会弹出一个支付弹窗,如果此时点击右上角的…

从ChatGPT到大模型

AIGC AIGC1. 关于ChatGPT2. 关于大模型模型即服务。现在大模型的两种:大模型发展趋势:大模型作用:大模型核心: 3. 要复现一个ChatGPT需要的资源支持?4. ChatGPT的局限性5. 类ChatGPT 未来的发展ChatGPT 体现的通用性&…

Java从高德地图获取全国地铁站数据

Java从高德地图获取全国地铁站数据。 数据来源(高德地图):http://map.amap.com/subway/index.html?&4401 采集代码 /*** 从高德地图地铁线路同步全国地铁站数据(非必要不调用)* 数据来源:http://ma…

【电厂用 JL-8D/3X2定时限电流继电器 复合继电器 功耗低 JOSEF约瑟】

JL-8D/3X2定时限电流继电器名称;定时限电流继电器型号:JL-8D/3X2触点容量250V5A功率消耗<5W返回系数0.90.97整定范围0.039.9A;0.130A辅助电源24220VDC/AC 系列型号: JL-8D/3X1定时限电流继电器; JL-8D/3X111A2定时限电流继电器&#xff1b…