Fish Speech 1.5实战教程:对接企业微信/钉钉机器人语音播报接口

1. 引言:当通知有了声音

想象一下这个场景:你正在专心写代码,突然,一个清晰、自然的语音播报在你耳边响起:“服务器CPU使用率超过90%,请立即处理。” 或者,你的团队群里,机器人用你熟悉的声音播报了今天的销售数据。这不再是科幻电影里的场景,而是我们今天要实现的。

Fish Speech 1.5 是一个强大的文本转语音模型,它能生成非常自然、高质量的语音。但它的价值远不止于在网页上点一下“播放”。真正的威力在于把它接入到你的工作流里,让冷冰冰的文字通知变成有温度的语音提醒。

这篇文章,我将带你从零开始,把 Fish Speech 1.5 变成一个能为你所用的“语音播报员”。我们会把它和企业微信、钉钉的机器人对接起来,实现一个自动化、智能化的语音通知系统。无论你是运维工程师、项目经理,还是产品经理,这套方案都能让你的工作更高效、更有趣。

2. 准备工作:部署你的语音工厂

在开始对接之前,我们需要先把 Fish Speech 1.5 跑起来。别担心,过程很简单。

2.1 快速部署 Fish Speech 1.5

如果你还没有部署 Fish Speech 1.5,可以按照以下步骤快速完成。这里假设你使用的是支持 GPU 的云服务器环境。

首先,通过 SSH 连接到你的服务器,然后执行以下命令来拉取和启动服务:

# 1. 拉取最新的 Fish Speech 1.5 镜像(假设使用Docker)
docker pull fishaudio/fish-speech:latest

# 2. 运行容器,映射端口到7860
docker run -d --gpus all \
  -p 7860:7860 \
  --name fish-speech \
  fishaudio/fish-speech:latest

# 3. 检查服务是否正常运行
docker logs fish-speech --tail 20

看到服务启动成功的日志后,你就可以在浏览器里访问 http://你的服务器IP:7860 来打开 Fish Speech 的 Web 界面了。

2.2 验证核心功能

打开 Web 界面后,我们先做个简单的测试,确保一切正常。

  1. 在「输入文本」框里,输入:“你好,世界!这是一条测试语音。”
  2. 点击「开始合成」按钮。
  3. 稍等片刻,你应该能听到一个清晰、自然的语音。

如果测试成功,恭喜你,你的“语音工厂”已经准备就绪了。接下来,我们要为它搭建一条“生产线”,让它能自动接收文本并生成语音。

3. 核心思路:构建自动化语音流水线

我们的目标不是手动在网页上输入文字,而是让程序自动完成。整个流程可以分解为三个核心步骤:

  1. 接收触发:企业微信或钉钉机器人收到一条消息(比如告警信息、数据报表)。
  2. 文本处理:程序提取消息中的关键文本,并发送给 Fish Speech 1.5。
  3. 语音生成与推送:Fish Speech 1.5 生成语音文件,程序再将这个语音文件发回给机器人,在群里播报。

为了实现这个流程,我们需要一个“中间人”服务。这个服务负责监听机器人的消息,调用 Fish Speech 的 API 生成语音,最后把语音文件传回去。我将用 Python 来编写这个“中间人”服务,因为它简单、高效,有丰富的库支持。

4. 实战第一步:编写语音生成服务

Fish Speech 1.5 提供了 HTTP API 供我们调用。我们先来写一个 Python 脚本,实现最基本的文本转语音功能。

4.1 调用 Fish Speech API

创建一个名为 tts_service.py 的文件,写入以下代码:

import requests
import json
import time
import os

class FishSpeechTTS:
    def __init__(self, base_url="http://localhost:7860"):
        """
        初始化 TTS 客户端
        :param base_url: Fish Speech 服务的地址
        """
        self.base_url = base_url.rstrip('/')
        self.api_url = f"{self.base_url}/api/generate"
        
    def text_to_speech(self, text, output_path="output.wav", language="zh", **kwargs):
        """
        将文本转换为语音并保存为文件
        :param text: 要转换的文本
        :param output_path: 输出音频文件路径
        :param language: 语言代码,如 'zh'(中文)、'en'(英文)
        :param kwargs: 其他高级参数,如 temperature, top_p 等
        :return: 成功返回文件路径,失败返回 None
        """
        # 构造请求数据
        payload = {
            "text": text,
            "language": language,
            **kwargs  # 可以传入其他参数,如 temperature=0.7
        }
        
        headers = {
            "Content-Type": "application/json"
        }
        
        try:
            print(f"正在合成语音: {text[:50]}...")
            response = requests.post(self.api_url, json=payload, headers=headers, timeout=60)
            
            if response.status_code == 200:
                # 保存音频文件
                with open(output_path, 'wb') as f:
                    f.write(response.content)
                print(f"语音文件已保存: {output_path}")
                return output_path
            else:
                print(f"API 调用失败,状态码: {response.status_code}")
                print(f"响应内容: {response.text}")
                return None
                
        except requests.exceptions.RequestException as e:
            print(f"请求发生错误: {e}")
            return None
        except Exception as e:
            print(f"处理过程中发生未知错误: {e}")
            return None

# 示例:快速测试
if __name__ == "__main__":
    tts = FishSpeechTTS()
    
    # 测试合成一段中文语音
    test_text = "各位同事请注意,下午三点在会议室召开项目周会,请准时参加。"
    result = tts.text_to_speech(test_text, "meeting_notice.wav", language="zh", temperature=0.7)
    
    if result:
        print("测试成功!你可以播放 meeting_notice.wav 文件来听效果。")
    else:
        print("测试失败,请检查服务是否正常运行。")

运行这个脚本,如果一切正常,你会在当前目录下得到一个名为 meeting_notice.wav 的语音文件。双击播放,听听效果。

4.2 添加声音克隆功能(可选但强大)

Fish Speech 1.5 支持声音克隆。这意味着你可以用一段短短的录音,让机器人用你(或任何指定人)的声音来播报。这在个性化通知场景下非常有用。

我们在 FishSpeechTTS 类中添加一个方法:

def text_to_speech_with_clone(self, text, reference_audio_path, reference_text, output_path="output_cloned.wav", language="zh"):
    """
    使用参考音频进行声音克隆的语音合成
    :param reference_audio_path: 参考音频文件路径(5-10秒清晰语音)
    :param reference_text: 参考音频对应的文本
    """
    # 注意:此API端点可能与基础合成不同,请根据实际部署的Fish Speech版本调整
    clone_api_url = f"{self.base_url}/api/generate_with_reference"
    
    # 需要以 multipart/form-data 形式上传文件
    files = {
        'audio': open(reference_audio_path, 'rb'),
    }
    
    data = {
        'text': text,
        'reference_text': reference_text,
        'language': language
    }
    
    try:
        print(f"正在使用声音克隆合成: {text[:50]}...")
        response = requests.post(clone_api_url, files=files, data=data, timeout=90)
        
        if response.status_code == 200:
            with open(output_path, 'wb') as f:
                f.write(response.content)
            print(f"克隆语音文件已保存: {output_path}")
            return output_path
        else:
            print(f"克隆API调用失败: {response.status_code}, {response.text}")
            return None
    except Exception as e:
        print(f"克隆过程中发生错误: {e}")
        return None
    finally:
        files['audio'].close()

重要提示:声音克隆的 API 端点 (/api/generate_with_reference) 和参数可能需要根据你部署的 Fish Speech 1.5 具体版本进行调整。最准确的方法是查阅其官方文档或通过 Web 界面抓取网络请求。

5. 实战第二步:对接企业微信机器人

现在我们的“语音工厂”可以工作了,接下来要打通“物流”——把企业微信的消息送进来,把生成的语音送出去。

5.1 创建企业微信群机器人

  1. 打开企业微信,进入你需要接收语音通知的群聊。
  2. 点击右上角的群菜单,选择「添加群机器人」。
  3. 给机器人起个名字,比如“语音播报员”,然后点击「添加」。
  4. 系统会生成一个 Webhook 地址,格式类似 https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx请务必复制并保存好这个地址,这是机器人的唯一密钥。

5.2 编写消息接收与处理服务

我们需要一个 Web 服务来接收企业微信机器人推送的消息(虽然群机器人通常是我们主动推给它,但为了处理复杂交互,我们可以自建接收服务)。这里使用 Flask 框架快速搭建。

创建一个名为 wechat_bot_server.py 的文件:

from flask import Flask, request, jsonify
import requests
import json
from fish_speech_tts import FishSpeechTTS  # 导入我们之前写的类
import os

app = Flask(__name__)

# 初始化 TTS 客户端
tts_client = FishSpeechTTS(base_url="http://localhost:7860")

# 你的企业微信机器人 Webhook URL
WECHAT_WEBHOOK_URL = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的KEY"

def send_voice_to_wechat(voice_file_path):
    """
    将语音文件发送到企业微信群
    """
    if not os.path.exists(voice_file_path):
        return False
    
    # 企业微信发送语音需要先上传媒体文件,这里简化流程,实际需按API分两步操作
    # 注意:企业微信机器人API默认不支持直接发送语音文件,以下为概念流程
    print(f"概念流程:此处应调用企业微信API上传 {voice_file_path} 并发送到群聊")
    # 实际开发请参考企业微信机器人文档的“上传临时素材”和“发送语音消息”部分
    return True

@app.route('/wechat/webhook', methods=['POST'])
def handle_wechat_message():
    """
    处理企业微信机器人推送的消息(如果需要接收用户@机器人的消息,需配置接收消息模式)
    """
    data = request.json
    print(f"收到企业微信消息: {json.dumps(data, indent=2, ensure_ascii=False)}")
    
    # 提取消息文本。这里结构根据企业微信回调格式而定。
    # 假设我们收到的是一个简单的文本命令,例如:@机器人 播报:服务器状态正常
    text_to_speak = "未识别到有效播报文本"
    
    # 这里需要解析 data 结构,提取出用户发送的文本内容
    # 例如:data.get('text', {}).get('content', '')
    # 由于企业微信机器人回调格式多样,此处省略具体解析代码
    
    # 假设我们提取到了文本
    extracted_text = "这是一条测试播报内容"
    
    # 调用 TTS 生成语音
    voice_file = tts_client.text_to_speech(
        text=extracted_text,
        output_path=f"temp_voice_{int(time.time())}.wav",
        language="zh"
    )
    
    if voice_file:
        # 发送语音到企业微信(需完善 send_voice_to_wechat 函数)
        send_voice_to_wechat(voice_file)
        # 清理临时文件
        os.remove(voice_file)
        return jsonify({"code": 0, "msg": "语音播报任务已处理"})
    else:
        return jsonify({"code": -1, "msg": "语音生成失败"}), 500

@app.route('/speak', methods=['GET', 'POST'])
def speak_directly():
    """
    一个直接触发播报的接口,方便测试
    例如访问:http://你的服务器IP:5000/speak?text=你好世界
    """
    text = request.args.get('text') or (request.json and request.json.get('text'))
    if not text:
        return jsonify({"code": -1, "msg": "请提供 text 参数"}), 400
    
    voice_file = tts_client.text_to_speech(
        text=text,
        output_path=f"direct_voice_{int(time.time())}.wav",
        language="zh"
    )
    
    if voice_file:
        # 这里可以直接播放或转发,我们简单返回文件下载
        # 实际应用中,你可能需要将文件上传到图床或存储服务,返回URL
        return jsonify({
            "code": 0,
            "msg": "成功",
            "file_path": voice_file,
            "note": "实际场景中,应返回可访问的音频URL"
        })
    else:
        return jsonify({"code": -1, "msg": "语音生成失败"}), 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

关键点说明

  1. 企业微信机器人发送语音消息的流程比文本复杂,需要先调用“上传临时素材”API获取媒体ID,再用该ID发送语音消息。上述代码中的 send_voice_to_wechat 函数需要你根据官方文档完善。
  2. 我们提供了一个 /speak 接口用于直接测试,非常方便。

5.3 更实用的方案:主动推送语音

大多数情况下,我们不需要机器人“听”我们说话,而是我们主动让机器人“说”话。比如,从监控系统、CI/CD流水线、数据库定时任务中触发播报。

我们可以写一个更简单的推送脚本 push_announcement.py

#!/usr/bin/env python3
import requests
import base64
import json
import sys
from fish_speech_tts import FishSpeechTTS

def push_voice_announcement(text, webhook_key):
    """
    主流程:生成语音 -> 上传到企业微信 -> 发送到群
    """
    # 1. 生成语音
    tts = FishSpeechTTS()
    voice_file = tts.text_to_speech(text, f"announcement.wav", language="zh")
    if not voice_file:
        print("语音生成失败")
        return False
    
    # 2. 上传到企业微信(获取media_id)
    upload_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media"
    params = {
        "key": webhook_key,
        "type": "voice"
    }
    
    with open(voice_file, 'rb') as f:
        files = {'media': f}
        upload_resp = requests.post(upload_url, params=params, files=files)
    
    if upload_resp.status_code != 200:
        print(f"上传语音文件失败: {upload_resp.text}")
        return False
    
    media_info = upload_resp.json()
    if media_info['errcode'] != 0:
        print(f"上传失败: {media_info}")
        return False
    
    media_id = media_info['media_id']
    
    # 3. 发送语音消息到群
    send_url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={webhook_key}"
    voice_message = {
        "msgtype": "voice",
        "voice": {
            "media_id": media_id
        }
    }
    
    send_resp = requests.post(send_url, json=voice_message)
    result = send_resp.json()
    
    if result['errcode'] == 0:
        print("语音消息推送成功!")
        return True
    else:
        print(f"推送失败: {result}")
        return False

if __name__ == "__main__":
    # 用法示例: python push_announcement.py "你的Webhook Key" "播报内容"
    if len(sys.argv) < 3:
        print("用法: python push_announcement.py <webhook_key> <text_to_speak>")
        sys.exit(1)
    
    webhook_key = sys.argv[1]
    text_to_speak = sys.argv[2]
    
    success = push_voice_announcement(text_to_speak, webhook_key)
    sys.exit(0 if success else 1)

现在,你可以在服务器上运行 python push_announcement.py YOUR_KEY “数据库备份完成,一切正常。”,你的企业微信群就会收到一条语音通知了!

6. 实战第三步:对接钉钉机器人

钉钉机器人的对接逻辑与企业微信类似,但 API 细节不同。钉钉机器人发送语音消息相对更直接一些。

6.1 创建钉钉群机器人

  1. 打开钉钉群,点击右上角的群设置。
  2. 选择「智能群助手」->「添加机器人」。
  3. 选择「自定义」机器人,设置名字和安全设置(如关键词、IP白名单等)。
  4. 完成后,同样会获得一个 Webhook 地址,格式类似 https://oapi.dingtalk.com/robot/send?access_token=xxxx

6.2 编写钉钉语音推送脚本

创建一个 dingtalk_push.py 文件:

#!/usr/bin/env python3
import requests
import hashlib
import base64
import time
import hmac
import json
import sys
from fish_speech_tts import FishSpeechTTS
from urllib.parse import quote_plus

def push_voice_to_dingtalk(text, webhook_url, secret=None):
    """
    推送语音到钉钉群
    :param webhook_url: 完整的Webhook地址
    :param secret: 机器人的加签密钥(如果设置了)
    """
    # 1. 生成语音文件
    tts = FishSpeechTTS()
    timestamp = str(int(time.time() * 1000))
    voice_filename = f"ding_voice_{timestamp}.wav"
    
    voice_file = tts.text_to_speech(text, voice_filename, language="zh")
    if not voice_file:
        return False
    
    # 2. 钉钉机器人发送语音需要先将语音文件上传到钉钉服务器,获取mediaId
    # 注意:钉钉机器人API不支持直接发送语音文件。官方支持的 msgtype 中不包括 voice。
    # 一种变通方案是发送一个 text 消息,里面包含语音文件的下载链接(需先将文件上传到其他存储服务)。
    # 另一种方案是使用钉钉的“工作通知”API,但需要企业授权,更复杂。
    
    print("钉钉机器人标准Webhook目前不支持直接发送语音消息。")
    print("替代方案1:发送包含音频链接的文本消息。")
    print("替代方案2:使用‘钉钉开放平台’的‘发送工作通知’API,该API支持语音消息类型。")
    
    # 这里演示替代方案1:生成一个文本消息,告知用户有语音通知(假设语音文件可通过URL访问)
    # 你需要先将 voice_file 上传到你的文件服务器或云存储,并获得一个可公开访问的URL
    voice_url = f"https://your-file-server.com/{voice_filename}"  # 请替换为实际URL
    
    # 构造签名(如果设置了加签)
    final_webhook_url = webhook_url
    if secret:
        string_to_sign = f"{timestamp}\n{secret}"
        sign = base64.b64encode(
            hmac.new(secret.encode('utf-8'), string_to_sign.encode('utf-8'), digestmod=hashlib.sha256).digest()
        ).decode('utf-8')
        final_webhook_url = f"{webhook_url}&timestamp={timestamp}&sign={sign}"
    
    # 发送文本消息,包含语音链接
    text_message = {
        "msgtype": "text",
        "text": {
            "content": f"语音播报通知:{text}\n点击收听:{voice_url}"
        }
    }
    
    headers = {'Content-Type': 'application/json'}
    resp = requests.post(final_webhook_url, json=text_message, headers=headers)
    result = resp.json()
    
    if result.get('errcode') == 0:
        print("钉钉消息推送成功(文本形式,含语音链接)")
        return True
    else:
        print(f"钉钉消息推送失败: {result}")
        return False

if __name__ == "__main__":
    # 示例:python dingtalk_push.py “你的Webhook URL” “播报内容” [你的Secret]
    if len(sys.argv) < 3:
        print("用法: python dingtalk_push.py <webhook_url> <text> [secret]")
        sys.exit(1)
    
    webhook = sys.argv[1]
    text = sys.argv[2]
    secret = sys.argv[3] if len(sys.argv) > 3 else None
    
    success = push_voice_to_dingtalk(text, webhook, secret)
    sys.exit(0 if success else 1)

重要提示:与企业微信不同,钉钉的群机器人 Webhook API 目前可能不支持直接发送 voice 类型的消息。官方文档支持 textlinkmarkdownactionCardfeedCard。因此,上述代码采用了变通方案:发送一条文本消息,里面包含语音文件的链接。你需要先将生成的语音文件上传到一个可公开访问的存储服务(如阿里云OSS、腾讯云COS,或你自己的服务器目录并通过Nginx提供访问)。

7. 总结:让语音通知为你工作

通过以上步骤,我们已经成功搭建了一个从 Fish Speech 1.5 到企业微信/钉钉机器人的语音播报流水线。让我们回顾一下关键收获:

  1. 核心价值:我们不仅仅是“用”了一个TTS工具,而是把它深度集成到了日常协作工具中,创造了自动化、主动式的语音通知场景。这比单纯的文字提醒更醒目,体验也更好。
  2. 技术要点
    • Fish Speech 1.5 的部署与 API 调用是基础。
    • 企业微信机器人发送语音需要“上传素材”和“发送消息”两步。
    • 钉钉机器人发送语音可能需要变通方案,如发送带音频链接的文本。
    • 编写一个健壮的、可处理异常和重试的中间服务是关键。
  3. 应用场景扩展
    • 运维监控:服务器CPU、内存、磁盘告警,用急促的语音第一时间通知。
    • CI/CD:代码构建成功、部署完成、测试失败,用语音播报结果。
    • 数据报表:每日销售额、用户增长数,用语音在晨会上播报。
    • 日程提醒:会议开始前10分钟,用语音在群里提醒大家。
    • 个性化问候:用老板或团队领袖的声音克隆,在特殊日子发送祝福。

下一步建议

  • 完善服务:为你的中间服务添加配置管理、日志记录和监控告警,让它更稳定。
  • 探索高级功能:深入研究 Fish Speech 1.5 的声音克隆参数,让合成的声音更逼真、更有情感。
  • 构建管理界面:可以做一个简单的Web页面,让非技术人员也能输入文本、选择声音、触发播报。

技术真正的魅力在于解决实际问题。希望这篇教程能帮你打开思路,用 Fish Speech 1.5 为你和你的团队打造一个更智能、更高效的工作环境。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐