网上找了一个百度文本转语音的python脚本,自己转了一份shell,待需。
使用之前应当先去申请应用,拿到api_key和api_secert
申请地址

http://yuyin.baidu.com/

  • python版代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #!/usr/bin/python3
    import urllib.request
    import urllib
    import json
    import base64
    import subprocess
    import sys
    class BaiduRest:
    def __init__(self, cu_id, api_key, api_secert):
    self.token_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
    self.getvoice_url = "http://tsn.baidu.com/text2audio?tex=%s&lan=zh&cuid=%s&ctp=1&tok=%s"
    self.upvoice_url = 'http://vop.baidu.com/server_api'
    self.cu_id = cu_id
    self.getToken(api_key, api_secert)
    return

    def getToken(self, api_key, api_secert):
    token_url = self.token_url % (api_key,api_secert)

    r_str = urllib.request.urlopen(token_url).read()
    token_data = json.loads(r_str.decode('UTF-8'))
    self.token_str = token_data['access_token']
    pass

    def getVoice(self, text, filename):
    get_url = self.getvoice_url % (urllib.parse.quote(text), self.cu_id, self.token_str)
    voice_data = urllib.request.urlopen(get_url).read()
    voice_fp = open(filename,'wb+')
    voice_fp.write(voice_data)
    voice_fp.close()
    pass

    def getText(self, filename):
    data = {}
    data['format'] = 'wav'
    data['rate'] = 8000
    data['channel'] = 1
    data['cuid'] = self.cu_id
    data['token'] = self.token_str
    wav_fp = open(filename,'rb')
    voice_data = wav_fp.read()
    data['len'] = len(voice_data)
    data['speech'] = base64.b64encode(voice_data).decode('utf-8')
    post_data = json.dumps(data)
    r_data = urllib.request.urlopen(self.upvoice_url,data=bytes(post_data,encoding="utf-8")).read()
    return json.loads(r_data.decode('UTF-8'))['result']

    if __name__ == "__main__":
    api_key = ""
    api_secert = ""
    txt_parm=sys.argv
    bdr = BaiduRest("RaspberryPi", api_key, api_secert)
    bdr.getVoice(txt_parm[1], "out.mp3")
    #print(bdr.getText("out.wav"))
  • shell版代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    #!/bin/bash
    ####################################################
    # 百度应用的key和secert
    api_key=""
    api_secert=""

    # 缓存文件路径,用于暂存access_token,减少获取次数
    baidu_config=/tmp/baidu.ini
    ####################################################

    # 此方法用于获取access_token
    # return token
    getToken ()
    {
    # 获取token的url
    oauth_url="https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=${api_key}&client_secret=${api_secert}"
    # 获取token
    temp=`curl ${oauth_url}`
    # 截取access_token
    temp=${temp#*\{\"access_token\"\:\"}
    token=${temp%%\"*}
    echo ${token}
    }

    # 此方法用于读取配置文件
    # $1 key
    # return config value
    getConfig ()
    {
    temp=`awk '$1~/\[.*/{_cdr_par_=0}\$0 ~ /^ *\[ *baidu *\]/{_cdr_par_=1}\$0~/^[\011 ]*'$1' *=.*/ { if(_cdr_par_==1) { sub("="," "); print $2; exit 0} }\' ${baidu_config}`
    echo ${temp}
    }
    echo "检查配置文件..."
    if [ ! -f $baidu_config ] ; then
    echo "初始化配置文件...."
    echo -e "[baidu]\ntime=`date +'%Y-%m-%d#%H:%M:%S'`\ntoken=$(getToken)" >>$baidu_config
    else
    # 计算时间是否超过86400秒
    echo "检查令牌周期..."
    time="$(getConfig time)"
    time=${time/\#/ }
    endtime=`date +'%Y-%m-%d %H:%M:%S'`
    time=$(date --date="$time" +%s)
    endtime=$(date --date="$endtime" +%s)
    time_value=$(($endtime - $time))
    if [ $time_value -ge 86300 ] ; then
    echo "令牌过期,重新获得令牌..."
    echo -e "[baidu]\ntime=`date +'%Y-%m-%d#%H:%M:%S'`\ntoken=$(getToken)" >$baidu_config
    fi
    fi
    token=$(getConfig token)

    # 拼接url
    # 参数说明
    # vol 音量,默认5,0-15
    vol=5
    # per 发音人,默认0,0普通女声,1普通男声,3情感合成-度逍遥,4情感合成-度丫丫
    per=0
    # spd 语速,默认5,0-9
    spd=5
    # pit 音调,默认5,0-9
    pit=5

    voice_url="http://tsn.baidu.com/text2audio?tex=${1}&lan=zh&cuid=RaspberryPi&ctp=1&tok=${token}&vol=${vol}&per=${per}&spd=${spd}&pit=${pit}"

    # 播放
    # 下面命令需sox
    # apt-get install sox libsox-fmt-mp3

    play $voice_url
  • 用法
    替换api_key、api_secert的值
    shell

    ./audio.sh 你好,度丫丫

python

./audio.py 你好,度丫丫
play out.mp3