火山引擎语音合成调用示例
火山引擎语音合成SDK提供了完整的文本转语音功能,支持多种音色选择和参数自定义。主要功能包括:1) 快速调用API或实例化配置两种使用方式;2) 可设置音色、语速、音量、情感等参数;3) 支持多种音频格式输出。开发者需提供应用ID和访问令牌,可通过异常机制处理错误。该SDK封装了火山引擎语音合成API,适合需要灵活语音合成的应用场景。
·
火山引擎语音合成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)- 设置应用IDsetAccessToken($accessToken)- 设置访问令牌setCluster($cluster)- 设置业务集群setUserId($userId)- 设置用户IDsetVoiceType($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);
}
}
返回结果
成功执行后,textToSpeech和run方法会返回包含以下字段的数组:
| 字段 | 类型 | 说明 |
|---|---|---|
| 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();
}
注意事项
- 必须提供有效的应用ID和访问令牌
- 默认音频格式为mp3
- 语速范围建议在0.8-2.0之间
- 音量范围建议在0.5-2.0之间
- 情感强度范围在1-5之间
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)