PHP项目语音播报内容如何动态拼接

wen PHP项目 27

本文目录导读:

PHP项目语音播报内容如何动态拼接

  1. 文本拼接后调用TTS接口
  2. 使用模板引擎
  3. 队列+异步处理
  4. 数据库动态配置播报内容
  5. 完整示例:订单系统语音播报
  6. 注意事项

在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);

注意事项

  1. 性能优化:使用队列和缓存避免实时合成
  2. 错误处理:添加重试机制和日志记录
  3. 并发控制:使用互斥锁避免同时播报
  4. 音频管理:定期清理临时音频文件
  5. 用户控制:提供静音、调节音量等功能
  6. 国际化:支持多语言播报

根据你的具体需求选择合适的方式,通常推荐使用模板+队列的方式来实现动态拼接和异步播报。

抱歉,评论功能暂时关闭!