PHP实现wav文件拼接

缘起

众所周知 科大讯飞的在线语音合成好使,但每天只有少得可怜的500次的配额, 想用但又不想出钱怎么办? 针对自己的特定业务场景, 同频词汇多,变化词汇少的情况. 将要请求的短句自己分词后分别获取wav 然后存于数据库. 是一个还不错的解决方案.

数据库设计

CREATE TABLE `tp_user_voice` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sName` varchar(32) DEFAULT NULL,
  `sVoice` mediumtext,
  PRIMARY KEY (`id`),
  UNIQUE KEY `sName` (`sName`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

PHP 代码

<?php

use app\index\model\UserVoice;

class VoiceMixer
{
	
	// 向科大讯飞发起语音合成请求
    private static function _DownloadVoice($sWord)
    {
		$curtime = strval(time());
		// 您在科大讯飞申请的APPID 和 APPKEY
		
		$appid = '*********';
		$appkey = '*******************************';
		
		$xParam = base64_encode(json_encode([
			'auf' => 'audio/L16;rate=16000',
			'aue' => 'raw', // raw lame
			'voice_name' => 'aisjinger',
			'engine_type'=>'x'
		]));
		
		$headers = [
			'X-CurTime: '. $curtime,
			'X-Param: '. $xParam,
			'X-Appid: '.$appid,
			'X-CheckSum: '.md5($appkey.$curtime.$xParam),
			'Content-Type: application/x-www-form-urlencoded; charset=utf-8'
		];
		$contents = ['text'=>$sWord];
		return form_post('http://api.xfyun.cn/v1/service/v1/tts', $headers, $contents);
    }

    private static function _GetWord($sWord)
    {
        $record = UserVoice::where('sName','EQ',$sWord)->find();
        if(is_object($record)){
            if(!is_null($record->sVoice)){
                
                return base64_decode($record->sVoice);
            }else{
                $record->sVoice = base64_encode(Self::_DownloadVoice($sWord));
                $record->save();
                return base64_decode($record->sVoice);
            }
        } else {
            $record = new UserVoice([
                'sName'=>$sWord,
                'sVoice'=>base64_encode(Self::_DownloadVoice($sWord))
            ]);
            $record->save();
            return base64_decode($record->sVoice);
        }
        return false;
    }
    

    /*
        传入一个单词数组, 混音成一个单词短句.
    */
    static public function GetVoice($words)
    {
        $vocArray = [];
        $index = 0;
        //第一步 获取所有单词语音
        foreach($words as $item){
            $voc = Self::_GetWord($item);
            if($index==0){
                $vocArray [] = $voc;
            }else{
                $vocArray [] = substr($voc, 44);
            }
            $index++;
        }
        //第二步 混音.
        $voc = implode('', $vocArray);
        $len = strlen($voc) - 8;

        $voc{4} = chr($len & 0xFF);
        $voc{5} = chr(($len >> 8) & 0xFF);
        $voc{6} = chr(($len >> 16) & 0xFF);
        $voc{7} = chr(($len >> 24) & 0xFF);

        $len -=36;
        $voc{40} = chr($len & 0xFF);
        $voc{41} = chr(($len >> 8) & 0xFF);
        $voc{42} = chr(($len >> 16) & 0xFF);
        $voc{43} = chr(($len >> 24) & 0xFF);
        return $voc;
    }
}

猜你喜欢

转载自blog.csdn.net/bywayboy/article/details/89482217