火山引擎语音合成SDK文档

简介

火山引擎语音合成SDK (CallVolcanoTTS) 提供了一套完整的接口,用于实现文本到语音的转换功能。该SDK封装了火山引擎语音合成API,提供了丰富的配置选项,可以灵活调整语音的音色、语速、音量等参数。

基本用法

快速调用

使用静态方法run()可以快速实现文本到语音的转换:

use ai\model\CallVolcanoTTS;

try {
    $result = CallVolcanoTTS::run(
        '这是一段需要转换成语音的文本', 
        '您的应用ID', 
        '您的访问令牌',
        'zh_male_M392_conversation_wvae_bigtts'  // 默认使用中文男声
    );
  
    // $result['audio_data'] 包含base64编码的音频数据
} catch (\Exception $e) {
    echo '错误:' . $e->getMessage();
}

实例化方式

如果需要更多自定义配置,可以实例化类后调用:

use ai\model\CallVolcanoTTS;

try {
    // 初始化SDK
    $tts = new CallVolcanoTTS('您的应用ID', '您的访问令牌');
  
    // 设置参数
    $tts->setVoiceType('zh_female_M347_emotion_wvae_bigtts')
        ->setSpeedRatio(1.2)
        ->setLoudnessRatio(1.5)
        ->setEncoding('mp3')
        ->setEnableEmotion(true)
        ->setEmotion('happy');
  
    // 执行转换
    $result = $tts->textToSpeech('这是一段需要转换成语音的文本');
  
    // 处理结果
    // $result['audio_data'] 包含base64编码的音频数据
    // $result['duration'] 表示音频时长(毫秒)
  
} catch (\Exception $e) {
    echo '错误:' . $e->getMessage();
}

参数配置

构造函数参数

实例化时可传入以下参数:

参数 类型 说明
appId string 应用ID(必填)
accessToken string 访问令牌(必填)
options array 可选配置项

options数组可包含以下配置项:

配置项 类型 说明 默认值
base_url string 自定义API接口URL https://openspeech.bytedance.com/api/v1/tts
cluster string 业务集群 volcano_tts
user_id string 用户ID user_001
voice_type string 音色类型 zh_male_M392_conversation_wvae_bigtts
encoding string 音频编码格式 mp3
speed_ratio float 语速 1.0
rate int 音频采样率 24000
bitrate int 比特率 160
loudness_ratio float 音量调节 1.0
enable_emotion bool 是否开启情感 false
emotion string 情感类型
emotion_scale float 情感强度 4.0
explicit_language string 明确语种
context_language string 参考语种
secret_key string 密钥

主要方法

设置方法

SDK提供了一系列设置方法,用于配置各种参数:

  • setAppId($appId) - 设置应用ID
  • setAccessToken($accessToken) - 设置访问令牌
  • setCluster($cluster) - 设置业务集群
  • setUserId($userId) - 设置用户ID
  • setVoiceType($voiceType) - 设置音色类型
  • setEncoding($encoding) - 设置音频编码格式(可用:wav/pcm/ogg_opus/mp3)
  • setSpeedRatio($speedRatio) - 设置语速(范围:0.8-2.0)
  • setRate($rate) - 设置音频采样率
  • setBitrate($bitrate) - 设置比特率(kb/s)
  • setLoudnessRatio($loudnessRatio) - 设置音量(范围:0.5-2.0)
  • setEnableEmotion($enableEmotion) - 是否开启音色情感
  • setEmotion($emotion) - 设置情感类型
  • setEmotionScale($emotionScale) - 设置情感强度(范围:1-5)
  • setExplicitLanguage($explicitLanguage) - 设置明确语种
  • setContextLanguage($contextLanguage) - 设置参考语种
  • setSecretKey($secretKey) - 设置密钥
核心方法
  • textToSpeech($text, $options = []) - 执行文本转语音

textToSpeech方法支持的附加选项:

选项 类型 说明
reqid string 自定义请求ID
text_type string 文本类型
silence_duration int 静音时长(毫秒)
with_timestamp bool 是否返回时间戳
extra_param array 额外参数
静态方法
  • run($text, $appId, $accessToken, $voiceType, $options) - 快速调用接口

完整代码

<?php
/**
 * @NodeAnotation(title="火山引擎语音合成SDK")
 * @Return:data
 */

namespace ai\model;

use ai\Index;
use think\facade\Log;

/**
 * 火山引擎语音合成SDK
 */
class CallVolcanoTTS
{
    /**
     * API接口URL
     * @var string
     */
    protected $apiUrl = 'https://openspeech.bytedance.com/api/v1/tts';

    /**
     * 应用ID
     * @var string
     */
    protected $appId;

    /**
     * 访问令牌
     * @var string
     */
    protected $accessToken;

    /**
     * 业务集群
     * @var string
     */
    protected $cluster = 'volcano_tts';

    /**
     * 用户ID
     * @var string
     */
    protected $userId = 'user_001';

    /**
     * 音色类型
     * @var string
     */
    protected $voiceType = 'zh_male_M392_conversation_wvae_bigtts';

    /**
     * 音频编码格式
     * @var string
     */
    protected $encoding = 'mp3';

    /**
     * 语速
     * @var float
     */
    protected $speedRatio = 1.0;

    /**
     * 音频采样率
     * @var int
     */
    protected $rate = 24000;

    /**
     * 比特率
     * @var int
     */
    protected $bitrate = 160;

    /**
     * 音量调节
     * @var float
     */
    protected $loudnessRatio = 1.0;

    /**
     * 开启音色情感
     * @var bool
     */
    protected $enableEmotion = false;

    /**
     * 音色情感
     * @var string
     */
    protected $emotion = '';

    /**
     * 情绪值设置
     * @var float
     */
    protected $emotionScale = 4.0;

    /**
     * 明确语种
     * @var string
     */
    protected $explicitLanguage = '';

    /**
     * 参考语种
     * @var string
     */
    protected $contextLanguage = '';

    /**
     * 密钥
     * @var string
     */
    protected $secretKey = '';

    /**
     * 构造函数
     *
     * @param string $appId 应用ID
     * @param string $accessToken 访问令牌
     * @param array $options 其他选项
     */
    public function __construct($appId = '', $accessToken = '', $options = [])
    {
        $this -> appId       = $appId;
        $this -> accessToken = $accessToken;

        // 如果传入了自定义URL,则直接使用自定义URL
        if (!empty($options['base_url'])) {
            $this -> apiUrl = trim($options['base_url']);
        }

        // 设置其他参数
        if (isset($options['cluster'])) {
            $this -> cluster = $options['cluster'];
        }

        if (isset($options['user_id'])) {
            $this -> userId = $options['user_id'];
        }

        if (isset($options['voice_type'])) {
            $this -> voiceType = $options['voice_type'];
        }

        if (isset($options['encoding'])) {
            $this -> encoding = $options['encoding'];
        }

        if (isset($options['speed_ratio'])) {
            $this -> speedRatio = (float)$options['speed_ratio'];
        }

        if (isset($options['rate'])) {
            $this -> rate = (int)$options['rate'];
        }

        if (isset($options['bitrate'])) {
            $this -> bitrate = (int)$options['bitrate'];
        }

        if (isset($options['loudness_ratio'])) {
            $this -> loudnessRatio = (float)$options['loudness_ratio'];
        }

        if (isset($options['enable_emotion'])) {
            $this -> enableEmotion = (bool)$options['enable_emotion'];
        }

        if (isset($options['emotion'])) {
            $this -> emotion = $options['emotion'];
        }

        if (isset($options['emotion_scale'])) {
            $this -> emotionScale = (float)$options['emotion_scale'];
        }

        if (isset($options['explicit_language'])) {
            $this -> explicitLanguage = $options['explicit_language'];
        }

        if (isset($options['context_language'])) {
            $this -> contextLanguage = $options['context_language'];
        }

        // 设置密钥
        if (isset($options['secret_key'])) {
            $this -> secretKey = $options['secret_key'];
        }
    }

    /**
     * 设置应用ID
     *
     * @param string $appId 应用ID
     * @return $this
     */
    public function setAppId($appId)
    {
        $this -> appId = $appId;
        return $this;
    }

    /**
     * 设置访问令牌
     *
     * @param string $accessToken 访问令牌
     * @return $this
     */
    public function setAccessToken($accessToken)
    {
        $this -> accessToken = $accessToken;
        return $this;
    }

    /**
     * 设置业务集群
     *
     * @param string $cluster 业务集群
     * @return $this
     */
    public function setCluster($cluster)
    {
        $this -> cluster = $cluster;
        return $this;
    }

    /**
     * 设置用户ID
     *
     * @param string $userId 用户ID
     * @return $this
     */
    public function setUserId($userId)
    {
        $this -> userId = $userId;
        return $this;
    }

    /**
     * 设置音色类型
     *
     * @param string $voiceType 音色类型
     * @return $this
     */
    public function setVoiceType($voiceType)
    {
        $this -> voiceType = $voiceType;
        return $this;
    }

    /**
     * 设置音频编码格式
     *
     * @param string $encoding 音频编码格式(wav/pcm/ogg_opus/mp3)
     * @return $this
     */
    public function setEncoding($encoding)
    {
        $this -> encoding = $encoding;
        return $this;
    }

    /**
     * 设置语速
     *
     * @param float $speedRatio 语速(0.8-2.0)
     * @return $this
     */
    public function setSpeedRatio($speedRatio)
    {
        $this -> speedRatio = $speedRatio;
        return $this;
    }

    /**
     * 设置音频采样率
     *
     * @param int $rate 音频采样率
     * @return $this
     */
    public function setRate($rate)
    {
        $this -> rate = $rate;
        return $this;
    }

    /**
     * 设置比特率
     *
     * @param int $bitrate 比特率(kb/s)
     * @return $this
     */
    public function setBitrate($bitrate)
    {
        $this -> bitrate = $bitrate;
        return $this;
    }

    /**
     * 设置音量调节
     *
     * @param float $loudnessRatio 音量调节(0.5-2.0)
     * @return $this
     */
    public function setLoudnessRatio($loudnessRatio)
    {
        $this -> loudnessRatio = $loudnessRatio;
        return $this;
    }

    /**
     * 开启音色情感
     *
     * @param bool $enableEmotion 是否开启
     * @return $this
     */
    public function setEnableEmotion($enableEmotion)
    {
        $this -> enableEmotion = $enableEmotion;
        return $this;
    }

    /**
     * 设置音色情感
     *
     * @param string $emotion 情感类型
     * @return $this
     */
    public function setEmotion($emotion)
    {
        $this -> emotion = $emotion;
        return $this;
    }

    /**
     * 设置情绪值
     *
     * @param float $emotionScale 情绪值(1-5)
     * @return $this
     */
    public function setEmotionScale($emotionScale)
    {
        $this -> emotionScale = $emotionScale;
        return $this;
    }

    /**
     * 设置明确语种
     *
     * @param string $explicitLanguage 明确语种
     * @return $this
     */
    public function setExplicitLanguage($explicitLanguage)
    {
        $this -> explicitLanguage = $explicitLanguage;
        return $this;
    }

    /**
     * 设置参考语种
     *
     * @param string $contextLanguage 参考语种
     * @return $this
     */
    public function setContextLanguage($contextLanguage)
    {
        $this -> contextLanguage = $contextLanguage;
        return $this;
    }

    /**
     * 设置密钥
     *
     * @param string $secretKey 密钥
     * @return $this
     */
    public function setSecretKey($secretKey)
    {
        $this -> secretKey = $secretKey;
        return $this;
    }

    /**
     * 生成文本转语音
     *
     * @param string $text 要转换的文本
     * @param array $options 其他选项
     * @return array 响应结果
     * @throws \Exception
     */
    public function textToSpeech($text, $options = [])
    {
        try {
            if (empty($this -> appId)) {
                throw new \Exception('应用ID不能为空');
            }

            if (empty($this -> accessToken)) {
                throw new \Exception('访问令牌不能为空');
            }

            if (empty($text)) {
                throw new \Exception('文本内容不能为空');
            }

            // 生成唯一请求ID
            $reqId = $options['reqid'] ?? $this -> generateUuid();

            // 构建请求数据
            $data = [
                'app'     => [
                    'appid'   => $this -> appId,
                    'token'   => $this -> accessToken,
                    'cluster' => $this -> cluster,
                ],
                'user'    => [
                    'uid' => $this -> userId
                ],
                'audio'   => [
                    'voice_type'  => $this -> voiceType,
                    'encoding'    => $this -> encoding,
                    'speed_ratio' => $this -> speedRatio,
                ],
                'request' => [
                    'reqid'     => $reqId,
                    'text'      => $text,
                    'operation' => 'query',
                ]
            ];

            // 如果密钥不为空,添加到请求数据中
            if (!empty($this -> secretKey)) {
                $data['app']['secret_key'] = $this -> secretKey;
            }

            // 添加可选音频参数
            if ($this -> rate != 24000) {
                $data['audio']['rate'] = $this -> rate;
            }

            if ($this -> bitrate != 160) {
                $data['audio']['bitrate'] = $this -> bitrate;
            }

            if ($this -> loudnessRatio != 1.0) {
                $data['audio']['loudness_ratio'] = $this -> loudnessRatio;
            }

            // 添加情感相关参数
            if ($this -> enableEmotion) {
                $data['audio']['enable_emotion'] = true;

                if (!empty($this -> emotion)) {
                    $data['audio']['emotion'] = $this -> emotion;
                }

                if ($this -> emotionScale != 4.0) {
                    $data['audio']['emotion_scale'] = $this -> emotionScale;
                }
            }

            // 添加语种相关参数
            if (!empty($this -> explicitLanguage)) {
                $data['audio']['explicit_language'] = $this -> explicitLanguage;
            }

            if (!empty($this -> contextLanguage)) {
                $data['audio']['context_language'] = $this -> contextLanguage;
            }

            // 添加其他可选参数
            if (isset($options['text_type'])) {
                $data['request']['text_type'] = $options['text_type'];
            }

            if (isset($options['silence_duration'])) {
                $data['request']['enable_trailing_silence_audio'] = true;
                $data['request']['silence_duration']              = $options['silence_duration'];
            }

            if (isset($options['with_timestamp'])) {
                $data['request']['with_timestamp'] = $options['with_timestamp'];
            }

            if (isset($options['extra_param']) && is_array($options['extra_param'])) {
                $data['request']['extra_param'] = json_encode($options['extra_param']);
            }

            // 发送请求
            $response = $this -> httpRequest($this -> apiUrl, $data, [
                'Authorization: Bearer;' . $this -> accessToken,
                'Content-Type: application/json'
            ]);

            // 检查响应
            if (!isset($response['code']) || $response['code'] != 3000) {
                $errorMsg = isset($response['message']) ? $response['message'] : '未知错误';
                throw new \Exception('语音合成失败: ' . $errorMsg);
            }

            // 处理结果
            return [
                'reqid'      => $response['reqid'],
                'code'       => $response['code'],
                'message'    => $response['message'],
                'audio_data' => $response['data'], // base64编码的音频数据
                'duration'   => isset($response['addition']['duration']) ? $response['addition']['duration'] : 0,
                'format'     => $this -> encoding
            ];

        } catch (\Exception $e) {
            throw new \Exception('火山引擎语音合成调用失败:' . $e -> getMessage());
        }
    }

    /**
     * 生成UUID
     *
     * @return string
     */
    protected function generateUuid()
    {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
            mt_rand(0, 0xffff), mt_rand(0, 0xffff),
            mt_rand(0, 0xffff),
            mt_rand(0, 0x0fff) | 0x4000,
            mt_rand(0, 0x3fff) | 0x8000,
            mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }

    /**
     * HTTP请求封装
     *
     * @param string $url 请求URL
     * @param array $data 请求数据
     * @param array $headers 请求头
     * @return array 响应结果
     * @throws \Exception
     */
    protected function httpRequest($url, $data, $headers = [])
    {
        try {
            // 使用公共函数中的http_post方法
            $result = http_post($url, $data, $headers);

            if (empty($result)) {
                throw new \Exception('接口返回数据为空');
            }

            return $result;
        } catch (\Exception $e) {
            throw new \Exception('HTTP请求失败:' . $e -> getMessage());
        }
    }

    /**
     * 快速调用方法
     *
     * @param string $text 要转换的文本
     * @param string $appId 应用ID
     * @param string $accessToken 访问令牌
     * @param string $voiceType 音色类型
     * @param array $options 其他选项
     * @return array 响应结果
     * @throws \Exception
     */
    public static function run($text, $appId, $accessToken, $voiceType = 'zh_male_M392_conversation_wvae_bigtts', $options = [])
    {
        $instance = new self($appId, $accessToken, ['voice_type' => $voiceType]);
        return $instance -> textToSpeech($text, $options);
    }
} 

返回结果

成功执行后,textToSpeechrun方法会返回包含以下字段的数组:

字段 类型 说明
reqid string 请求ID
code int 状态码
message string 状态消息
audio_data string Base64编码的音频数据
duration int 音频时长(毫秒)
format string 音频格式

错误处理

SDK使用异常机制处理错误,在调用时应使用try-catch捕获可能的异常:

try {
    $result = CallVolcanoTTS::run($text, $appId, $accessToken);
    // 处理结果
} catch (\Exception $e) {
    // 处理异常
    echo '错误:' . $e->getMessage();
}

注意事项

  1. 必须提供有效的应用ID和访问令牌
  2. 默认音频格式为mp3
  3. 语速范围建议在0.8-2.0之间
  4. 音量范围建议在0.5-2.0之间
  5. 情感强度范围在1-5之间
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐