本文目录导读:

在PHP项目中实现语音播报内容的动态拼接,常见的方法有以下几种:
文本拼接后调用TTS接口
<?php
class VoiceBroadcast {
private $ttsApi;
public function __construct($apiKey) {
$this->ttsApi = new TTSService($apiKey);
}
// 动态拼接播报内容
public function buildBroadcastContent($data) {
$content = '';
// 根据不同类型拼接
switch($data['type']) {
case 'order':
$content .= "您有新的订单,";
$content .= "订单编号:{$data['order_no']},";
$content .= "订单金额:{$data['amount']}元,";
$content .= "请及时处理。";
break;
case 'warning':
$content .= "系统警告:";
$content .= $data['message'];
$content .= ",请立即关注!";
break;
case 'schedule':
$content .= "提醒您:";
$content .= "在{$data['time']},";
$content .= "需要{$data['task']},";
$content .= "请做好准备。";
break;
}
return $content;
}
// 生成语音并播报
public function broadcast($data) {
$text = $this->buildBroadcastContent($data);
return $this->ttsApi->textToSpeech($text);
}
}
// 使用示例
$broadcast = new VoiceBroadcast('your-api-key');
// 订单提醒
$orderData = [
'type' => 'order',
'order_no' => '20231201001',
'amount' => 158.00
];
$broadcast->broadcast($orderData);
// 警告提醒
$warningData = [
'type' => 'warning',
'message' => '服务器CPU使用率超过90%'
];
$broadcast->broadcast($warningData);
使用模板引擎
<?php
class TemplateBroadcast {
private $templates = [];
private $ttsService;
public function __construct() {
// 定义模板
$this->templates = [
'order' => '您有新的订单,订单编号:{order_no},金额:{amount}元',
'warning' => '警告:{level}级别警告,{message}',
'weather' => 'date},{city}天气:{weather},温度:{temp}度',
'custom' => '{content}'
];
}
// 动态渲染模板
public function render($type, $params) {
if (!isset($this->templates[$type])) {
throw new Exception("模板不存在");
}
$template = $this->templates[$type];
// 替换变量
foreach ($params as $key => $value) {
$template = str_replace('{' . $key . '}', $value, $template);
}
return $template;
}
// 播报语音
public function speak($type, $params) {
$content = $this->render($type, $params);
return $this->ttsService->synthesize($content);
}
}
// 使用示例
$broadcast = new TemplateBroadcast();
// 天气播报
$weatherParams = [
'date' => date('Y-m-d'),
'city' => '北京',
'weather' => '晴',
'temp' => 25
];
$broadcast->speak('weather', $weatherParams);
队列+异步处理
<?php
// 语音播报任务类
class BroadcastTask {
private $redis;
private $ttsService;
public function __construct() {
$this->redis = new Redis();
$this->ttsService = new TTSService();
}
// 添加播报任务到队列
public function addTask($type, $data) {
$task = [
'type' => $type,
'data' => $data,
'time' => time(),
'priority' => $data['priority'] ?? 1
];
// 添加到队列
$this->redis->lPush('broadcast_queue', json_encode($task));
return true;
}
// 处理队列任务
public function processQueue() {
while (true) {
$taskJson = $this->redis->rPop('broadcast_queue');
if (!$taskJson) {
sleep(1);
continue;
}
$task = json_decode($taskJson, true);
$this->processTask($task);
}
}
// 处理单个任务
private function processTask($task) {
$content = $this->buildContent($task['type'], $task['data']);
// 添加语音标签
$ssml = $this->buildSSML($content, $task['data']);
// 合成语音
$audioFile = $this->ttsService->synthesize($ssml);
// 播报
$this->playAudio($audioFile);
}
// 构建SSML标签
private function buildSSML($text, $options = []) {
$ssml = '<speak>';
// 语速控制
$rate = $options['rate'] ?? '1.0';
$ssml .= "<prosody rate='{$rate}'>";
// 音量控制
$volume = $options['volume'] ?? 'medium';
$ssml .= "<prosody volume='{$volume}'>";
$ssml .= htmlspecialchars($text);
$ssml .= '</prosody></prosody>';
$ssml .= '</speak>';
return $ssml;
}
}
// 使用示例
$broadcast = new BroadcastTask();
// 添加紧急播报
$broadcast->addTask('warning', [
'message' => '系统即将进行维护',
'priority' => 5,
'rate' => '1.2' // 加快语速
]);
// 添加普通播报
$broadcast->addTask('order', [
'order_no' => '20231201002',
'amount' => 299.00
]);
数据库动态配置播报内容
<?php
class DynamicBroadcast {
private $db;
private $settings;
public function __construct() {
$this->db = new PDO('mysql:host=localhost;dbname=system', 'user', 'pass');
$this->loadSettings();
}
// 加载播报设置
private function loadSettings() {
$stmt = $this->db->query("SELECT * FROM broadcast_settings WHERE status = 1");
$this->settings = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 根据规则生成播报内容
public function generateContent($event, $params) {
foreach ($this->settings as $setting) {
if ($this->matchRule($setting['rule'], $event, $params)) {
$content = $this->replacePlaceholders($setting['template'], $params);
return [
'content' => $content,
'priority' => $setting['priority'],
'voice' => $setting['voice_type']
];
}
}
return null;
}
// 匹配规则
private function matchRule($rule, $event, $params) {
return $rule == $event || $rule == '*';
}
// 替换占位符
private function replacePlaceholders($template, $params) {
preg_match_all('/\{(\w+)\}/', $template, $matches);
foreach ($matches[1] as $key) {
if (isset($params[$key])) {
$template = str_replace('{' . $key . '}', $params[$key], $template);
}
}
return $template;
}
}
完整示例:订单系统语音播报
<?php
// broadcast.php
class OrderBroadcastSystem {
private $tts;
private $interval = 5; // 播报间隔(秒)
private $lastBroadcastTime = 0;
public function __construct() {
$this->tts = new BaiduAipSpeech('app_id', 'api_key', 'secret_key');
}
// 新订单播报
public function newOrderBroadcast($order) {
$content = $this->buildOrderContent($order);
$this->broadcastWithDelay($content, 'order');
}
// 构建订单内容
private function buildOrderContent($order) {
$parts = [];
// 开头
if ($order['type'] == 'new') {
$parts[] = "叮咚,您有新的外卖订单";
} else {
$parts[] = "订单更新提醒";
}
// 订单号
$parts[] = "订单号{$order['order_no']}";
// 内容
if (!empty($order['items'])) {
$items = [];
foreach ($order['items'] as $item) {
$items[] = "{$item['name']}×{$item['quantity']}";
}
$parts[] = "包含:" . implode('、', $items);
}
// 金额
$parts[] = "共计{$order['total_amount']}元";
// 地址
if (!empty($order['address'])) {
$parts[] = "送到{$order['address']}";
}
return implode(',', $parts) . '。';
}
// 延迟播报(避免频繁播报)
private function broadcastWithDelay($content, $type) {
$now = time();
if ($now - $this->lastBroadcastTime < $this->interval) {
// 添加到延迟队列
$this->addToDelayQueue($content, $type);
return;
}
$this->doBroadcast($content, $type);
$this->lastBroadcastTime = $now;
}
// 执行播报
private function doBroadcast($content, $type) {
$options = [
'spd' => 5, // 语速
'pit' => 5, // 音调
'vol' => 5 // 音量
];
$result = $this->tts->synthesis($content, $options);
if (!is_array($result)) {
// 保存音频文件
$filename = "broadcast_{$type}_" . time() . ".mp3";
file_put_contents("audio/{$filename}", $result);
// 播放音频
$this->playAudioFile("audio/{$filename}");
}
}
// 播放音频文件
private function playAudioFile($file) {
// 根据系统调用播放器
if (PHP_OS == 'Linux') {
exec("mpg123 {$file} &");
} else {
exec("start {$file}");
}
}
// 添加到延迟队列
private function addToDelayQueue($content, $type) {
// 存入Redis或数据库
$queue = new RedisQueue('broadcast_delay');
$queue->push([
'content' => $content,
'type' => $type,
'time' => time()
]);
}
}
// 使用示例
$broadcast = new OrderBroadcastSystem();
// 模拟新订单
$order = [
'type' => 'new',
'order_no' => '20231201003',
'items' => [
['name' => '红烧肉', 'quantity' => 1],
['name' => '米饭', 'quantity' => 2]
],
'total_amount' => 45.00,
'address' => '北京市海淀区xx路xx号'
];
$broadcast->newOrderBroadcast($order);
注意事项
- 性能优化:使用队列和缓存避免实时合成
- 错误处理:添加重试机制和日志记录
- 并发控制:使用互斥锁避免同时播报
- 音频管理:定期清理临时音频文件
- 用户控制:提供静音、调节音量等功能
- 国际化:支持多语言播报
根据你的具体需求选择合适的方式,通常推荐使用模板+队列的方式来实现动态拼接和异步播报。