$csCode = @"
using System;
using System.IO;
using System.Text;
using System.Runtime.InteropServices;
namespace Test
{
public class MultMedia
{
[DllImport("winmm.dll",EntryPoint="mciSendStringA", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true, CallingConvention=CallingConvention.Cdecl)]
private static extern int mciSendString(string lpstrCommand, string lpstrReturnString, int uReturnLength, int hwndCallback);
[DllImport("winmm.dll",EntryPoint="mciGetErrorStringA", ExactSpelling=true, CharSet=CharSet.Ansi, SetLastError=true, CallingConvention=CallingConvention.Cdecl)]
private static extern int mciGetErrorString(int nError, ref byte strErrorText, int nErrorText);
/// 调用系统麦克风,设置音频参数,开始录音
public static void StartRecord() {
mciSendString("open new type waveaudio alias recSound", "", 0, 0);
string strCMD = "set recSound time format ms";
strCMD += " bitspersample 16";
strCMD += " channels 1";
strCMD += " samplespersec 16000";
strCMD += " bytespersec 32000"; // bytespersec = bitspersample*channels*samplespersec/8
strCMD += " alignment 2"; // alignment = bitspersample*channels/8
strCMD += " format tag pcm";
mciSendString(strCMD, "", 0, 0);
mciSendString("record recSound", "", 0, 0);
}
/// 停止录音并保存音频数据至指定文件
public static void SaveRecord(string strFileName) {
string strCMD = "save recSound " + strFileName + " wait";
mciSendString(strCMD, "", 0, 0);
mciSendString("close recSound", "", 0, 0);
}
/// 播放WAV文件
public static void Play(string strFileName) {
int nRet = 0;
byte[] szError = new byte[255];
string strCMD = "open " + strFileName + " type waveaudio alias playSound";
nRet = mciSendString(strCMD, "", 0, 0);
if (nRet != 0) {
Console.WriteLine("Open error code : {0}", nRet);
mciGetErrorString(nRet, ref szError[0], 255);
Console.WriteLine("Description : {0}", System.Text.Encoding.Default.GetString(szError, 0, szError.Length));
return;
}
nRet = mciSendString("play playSound wait", "", 0, 0);
if (nRet != 0) {
Console.WriteLine("Play error code : {0}", nRet);
mciGetErrorString(nRet, ref szError[0], 255);
Console.WriteLine("Description : {0}", System.Text.Encoding.Default.GetString(szError, 0, szError.Length));
return;
}
nRet = mciSendString("close playSound", "", 0, 0);
if (nRet != 0) {
Console.WriteLine("Close error code : {0}", nRet);
mciGetErrorString(nRet, ref szError[0], 255);
Console.WriteLine("Description : {0}", System.Text.Encoding.Default.GetString(szError, 0, szError.Length));
return;
}
}
}
}
"@
Add-Type -TypeDefinition $csCode
function pause() {
Write-Host "Press any key to continue..."
[Console]::ReadKey() | Out-Null
}
# 定义使用常量
$URL = "https://api.xfyun.cn/v1/service/v1/tts"
$AUE = "raw"
$APPID = "YOUR_APPID"
$API_KEY = "YOUR_API_KEY"
$arrayAgents = $Null
$nAgentNum = 0
$strContent = ""
# 组装网页请求Header
function getHeader() {
# 获取当前世界标准时间与1970年初的时间差总秒数
$dtNow = Get-Date
$dtDiff = $dtNow.ToUniversalTime() - $(Get-Date -Date "1970/01/01 00:00:00")
$curTime = [Math]::Floor($dtDiff.TotalSeconds)
Write-Host $curTime
# 组装配置信息
$param = "{`"aue`":`"$AUE`",`"auf`":`"audio/L16;rate=16000`",`"voice_name`":`"$VOICE_NAME`",`"engine_type`":`"intp65`"}"
Write-Host $param
$oUTF8 = New-Object -TypeName System.Text.UTF8Encoding
$oMD5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
# 配置信息BASE64编码
$strBase64 = [Convert]::ToBase64String($oUTF8.GetBytes($param))
Write-Host `$strBase64 : $strBase64
# API_KEY+时间差+BASE64密文进行UTF8编码备用
$strUTF8Con = $API_KEY + $curTime + $strBase64
$arrayUTF8Con = $oUTF8.GetBytes($strUTF8Con)
Write-Host `$strUTF8Con : $strUTF8Con
Write-Host `$arrayUTF8Con : $arrayUTF8Con
# 计算API_KEY+时间差+配置信息BASE64密文的MD5值
$arrayBinCon = $oMD5.ComputeHash($arrayUTF8Con)
$checkSum = [BitConverter]::ToString($arrayBinCon) -Replace "-", ""
$checkSum = $checkSum.ToLower()
Write-Host `$checkSum : $checkSum
# 按需求组合请求Header的HASH表(一一对应相关变量)
$header = @{
"X-CurTime" = $curTime
"X-Param" = $strBase64
"X-Appid" = $APPID
"X-CheckSum" = $checkSum
"X-Real-Ip" = "127.0.0.1"
"Content-Type" = "application/x-www-form-urlencoded; charset=utf-8"
}
#Write-Host $header
return $header
}
# 组装合成语音文本的HASH表,仅TEXT一个字典
function getBody($text) {
$data = @{
#"text" = [Web.HttpUtility]::UrlEncode($text) #技术文档里面说需要URLENCODE编码,实际上不需要
"text" = $text
}
#Write-Host "转化的内容为 : $text"
return $data
}
# 将返回音频流写入对应文件
function writeFile($file, $content){
#param ([string] $file, [Byte[]] $content)
[System.IO.File]::WriteAllBytes($file, $content)
}
# 选择发音角色
function getAgentList() {
$oVoice1 = @{"index" = "1"; "name" = "讯飞小燕"; "type" = "普通话"; "nameID" = "xiaoyan"}
$oVoice2 = @{"index" = "2"; "name" = "讯飞许久"; "type" = "普通话"; "nameID" = "aisjiuxu"}
$oVoice3 = @{"index" = "3"; "name" = "讯飞小萍"; "type" = "普通话"; "nameID" = "aisxping"}
$oVoice4 = @{"index" = "4"; "name" = "讯飞小婧"; "type" = "普通话"; "nameID" = "aisjinger"}
$oVoice5 = @{"index" = "5"; "name" = "讯飞许小宝"; "type" = "普通话"; "nameID" = "aisbabyxu"}
$oVoice6 = @{"index" = "6"; "name" = "讯飞小东"; "type" = "山东话"; "nameID" = "x_xiaodong"}
$oVoice7 = @{"index" = "7"; "name" = "讯飞小王"; "type" = "湖北话"; "nameID" = "x_xiaowang"}
$oVoice8 = @{"index" = "8"; "name" = "讯飞萌萌-中立"; "type" = "普通话"; "nameID" = "x_mengmengneutral"}
$oVoice9 = @{"index" = "9"; "name" = "讯飞宁宁"; "type" = "普通话"; "nameID" = "x_ningning"}
$oVoice10 = @{"index" = "10"; "name" = "讯飞小南"; "type" = "普通话"; "nameID" = "x_xiaonan"}
$oVoice11 = @{"index" = "11"; "name" = "讯飞玲姐姐"; "type" = "普通话"; "nameID" = "x_xiaoling"}
$oVoice12 = @{"index" = "12"; "name" = "讯飞小坤"; "type" = "河南话"; "nameID" = "x_xiaokun"}
$oVoice13 = @{"index" = "13"; "name" = "讯飞小梅"; "type" = "广东话"; "nameID" = "x_xiaomei"}
$oVoice14 = @{"index" = "14"; "name" = "讯飞小瑞"; "type" = "普通话"; "nameID" = "x_xiaonuo_novel"}
$oVoice15 = @{"index" = "15"; "name" = "讯飞小师"; "type" = "普通话"; "nameID" = "x_xiaoshi_cts"}
$oVoice16 = @{"index" = "16"; "name" = "讯飞小梦"; "type" = "普通话"; "nameID" = "x_xiaomeng"}
$oVoice17 = @{"index" = "17"; "name" = "讯飞小施"; "type" = "普通话"; "nameID" = "x_xiaoshi"}
$oVoice18 = @{"index" = "18"; "name" = "讯飞小强"; "type" = "湖南话"; "nameID" = "x_xiaoqiang"}
$oVoice19 = @{"index" = "19"; "name" = "讯飞一峰"; "type" = "普通话"; "nameID" = "x_yifeng"}
$oVoice20 = @{"index" = "20"; "name" = "讯飞小媛"; "type" = "普通话"; "nameID" = "x_xiaoyuan"}
$oVoice21 = @{"index" = "21"; "name" = "讯飞晓倩"; "type" = "东北话"; "nameID" = "x_xiaoqian"}
$oVoice22 = @{"index" = "22"; "name" = "讯飞小莹"; "type" = "陕西话"; "nameID" = "x_xiaoying"}
$oVoice23 = @{"index" = "23"; "name" = "讯飞小乔"; "type" = "普通话"; "nameID" = "x_xiaoqiao"}
$oVoice24 = @{"index" = "24"; "name" = "讯飞小瑶"; "type" = "普通话"; "nameID" = "x_xiaoyao"}
$oVoice25 = @{"index" = "25"; "name" = "讯飞晓燕"; "type" = "普通话"; "nameID" = "x_xiaoyan"}
$oVoice26 = @{"index" = "26"; "name" = "讯飞萌萌-悲伤"; "type" = "普通话"; "nameID" = "x_mengmengsad"}
$oVoice27 = @{"index" = "27"; "name" = "讯飞小春"; "type" = "普通话"; "nameID" = "x_mengchun"}
$oVoice28 = @{"index" = "28"; "name" = "讯飞马叔"; "type" = "普通话"; "nameID" = "x_laoma"}
$oVoice29 = @{"index" = "29"; "name" = "讯飞小蓉"; "type" = "四川话"; "nameID" = "x_xiaorong"}
$oVoice30 = @{"index" = "30"; "name" = "讯飞芳芳"; "type" = "普通话"; "nameID" = "x_xiaofang"}
$oVoice31 = @{"index" = "31"; "name" = "讯飞晓峰"; "type" = "普通话"; "nameID" = "x_xiaofeng"}
$oVoice32 = @{"index" = "32"; "name" = "讯飞小魏"; "type" = "普通话"; "nameID" = "x_xiaowei"}
$oVoice33 = @{"index" = "33"; "name" = "讯飞楠楠"; "type" = "普通话"; "nameID" = "x_nannan"}
$oVoice34 = @{"index" = "34"; "name" = "讯飞小肥"; "type" = "安徽合肥话"; "nameID" = "x_xiaofei"}
$oVoice35 = @{"index" = "35"; "name" = "讯飞小雪"; "type" = "普通话"; "nameID" = "x_xiaoxue"}
$oVoice36 = @{"index" = "36"; "name" = "讯飞晓琳"; "type" = "台湾普通话"; "nameID" = "x_xiaolin"}
$oVoice37 = @{"index" = "37"; "name" = "讯飞小包"; "type" = "内蒙古方言"; "nameID" = "x_xiaobao"}
$oVoice38 = @{"index" = "38"; "name" = "讯飞小华"; "type" = "普通话"; "nameID" = "x_xiaoyang_story"}
$oVoice39 = @{"index" = "39"; "name" = "讯飞宋宝宝"; "type" = "普通话"; "nameID" = "x_xiaosong"}
$oVoice40 = @{"index" = "40"; "name" = "讯飞玉儿"; "type" = "台湾普通话"; "nameID" = "x_yuer"}
$oVoice41 = @{"index" = "41"; "name" = "讯飞萌萌-高兴"; "type" = "普通话"; "nameID" = "x_mengmenghappy"}
$arrayVoices = @($oVoice1, $oVoice2, $oVoice3, $oVoice4, $oVoice5, $oVoice6, $oVoice7, $oVoice8,
$oVoice9, $oVoice10, $oVoice11, $oVoice12, $oVoice13, $oVoice14, $oVoice15, $oVoice16,
$oVoice17, $oVoice18, $oVoice19, $oVoice20, $oVoice21, $oVoice22, $oVoice23, $oVoice24,
$oVoice25, $oVoice26, $oVoice27, $oVoice28, $oVoice29, $oVoice30, $oVoice31, $oVoice32,
$oVoice33, $oVoice34, $oVoice35, $oVoice36, $oVoice37, $oVoice38, $oVoice39, $oVoice40,
$oVoice41)
return $arrayVoices
}
# 从参数或用户输入取得发音角色
function chooseAct() {
Write-Host "请选择你要发音的角色 : "
$arrayAgents | %{
Write-Host "$($_["index"]). $($_["name"])-$($_["type"])"
}
$nRetAct = Read-Host "角色编号"
return $nRetAct
}
function main() {
$arrayAgents = getAgentList
$VOICE_NAME = ""
if ( $nAgentNum -eq 0 ) {
$nAgentNum = chooseAct
}
do {
clear
$bFound = $false
$arrayAgents | %{
if ( $nAgentNum -eq $_["index"] ) {
$bFound = $true
$VOICE_NAME = "$($_["nameID"])"
Write-Host `$VOICE_NAME : $VOICE_NAME
break
}
}
if ( $bFound ) {
break
} else {
Write-Host "错误编号,请重新输入..."
pause
}
$nAgentNum = chooseAct
} while ($true)
# 从参数或用户输入取得合成文本
$strConTmp = ""
if ( $strContent -ne "" ) {
$strConTmp = $strContent
} else {
$strConTmp = Read-Host "Input translated text"
}
# 组装请求Header
$oHeader = getHeader
# 转换成JSON格式便于输出调试
$strHeader = ConvertTo-Json $oHeader
# 组装请求内容
$oBody = getBody $strConTmp
# 转换成JSON格式便于输出调试
$strBody = ConvertTo-Json $oBody
Write-Host "`n`n`n"
try {
# 请求服务接口,传入需求数据
Write-Host `$oPage = Invoke-WebRequest `-URI $URL `-Method Post `-Headers $strHeader `-Body $strBody
$oPage = Invoke-WebRequest -URI "$URL" -Method Post -Headers $oHeader -Body $oBody
#$oPage
Write-Host "`n`n`n"
# 取出内容分析返回格式,若为音频格式继续
$contentType = $oPage.Headers['Content-Type']
if ( $contentType -eq "audio/mpeg") {
# 返回SID值,作为文件名
$sid = $oPage.Headers['sid']
# WAVE格式与MP3格式处理
$strAudio = ""
if ( !(Test-Path "audio") ) { mkdir "audio" }
if ($AUE -eq "raw") {
$strAudio = "$pwd\audio\$($sid).wav"
writeFile -file $strAudio -content $($oPage.Content)
} else {
$strAudio = "$pwd\audio\$($sid).mp3"
writeFile -file $strAudio -content $($oPage.Content)
}
Write-Host "success, sid = $sid"
#ffplay -hide_banner -autoexit -i $strAudio -showmode 1
[Test.MultMedia]::Play($strAudio)
} else {
# 错误请求,输出返回结果
Write-Host "Execute error, the detail is : $($oPage.RawContent)"
}
} catch {
# 例外捕获
Write-Host Erron on : $Error[0]
}
}
if ($args.Count -ge 1) {
$strContent = $args[0]
Write-Host "获取内容参数 : $strContent"
}
if ($args.Count -ge 2) {
$nAgentNum = $args[1]
Write-Host "获取角色参数 : $nAgentNum"
}
main
pause
注:请至 http://www.xfyun.cn注册账号并申请APPID
