예제 #1
0
    def exec(command_id):
        try:
            conn = ""
            conn = connector.connect(host=mysql_con.HOST,
                                     user=mysql_con.USERNAME,
                                     password=mysql_con.PASSWORD,
                                     port=mysql_con.PORT,
                                     database=mysql_con.DATABASE,
                                     charset=mysql_con.CHARSET)

            cursor = conn.cursor()
            cursor.execute("UPDATE  command  SET `status`=%s WHERE id=%s",
                           ('1', command_id))

            # 提交记录
            conn.commit()

            log.normal("更新命令状态 命令编号:%d" % command_id)

        except Exception as e:
            log.exp("更新命令状态 命令编号:%d" % command_id, e)

        finally:
            if "" != conn:
                conn.close()
예제 #2
0
    def get_text(cls, file_name):
        log.normal("音频转文字: " + file_name)
        # 请求地址
        request_url = "http://vop.baidu.com/server_api"

        # 参数
        p_rate = config.RATE  # 采样率,支持 8000 或者 16000
        p_cuid = "FC-AA-14-D0-1D-67"  # 用户唯一标识,用来区分用户,填写机器 MAC 地址,长度为60以内
        p_token = cls.get_access_token()  # 开放平台获取到的开发者 access_token
        fp = wave.open(file_name, 'rb')
        nf = fp.getnframes()
        p_len = nf * 2
        p_speech = fp.readframes(nf)

        srv_url = request_url + '?cuid=' + p_cuid + '&token=' + p_token
        http_header = [
            'Content-Type: audio/pcm; rate=%d' % p_rate,
            'Content-Length: %d' % p_len
        ]

        c = pycurl.Curl()
        c.setopt(pycurl.URL, str(srv_url))  # curl doesn't support unicode
        c.setopt(c.HTTPHEADER, http_header)  # must be list, not dict
        c.setopt(c.POST, 1)
        c.setopt(c.CONNECTTIMEOUT, 30)
        c.setopt(c.TIMEOUT, 30)
        c.setopt(c.WRITEFUNCTION, cls.parse_text_result)
        c.setopt(c.POSTFIELDS, p_speech)
        c.setopt(c.POSTFIELDSIZE, p_len)
        try:
            c.perform()
        except Exception as e:
            log.exp("语音转文字发生异常。", e)
예제 #3
0
    def insert(text):
        try:
            conn = ""
            conn = connector.connect(host=mysql_con.HOST,
                                     user=mysql_con.USERNAME,
                                     password=mysql_con.PASSWORD,
                                     port=mysql_con.PORT,
                                     database=mysql_con.DATABASE,
                                     charset=mysql_con.CHARSET)

            cursor = conn.cursor()
            cursor.execute(
                "INSERT INTO command (`content`,`status`,`posttime`) VALUES (%s,%s,%s)",
                (text, 0, datetime.timestamp(datetime.now())))

            # 提交记录
            conn.commit()

            log.normal("往数据库中插入新命令:" + text)

        except Exception as e:
            log.exp("往数据库中插入新命令:" + text, e)

        finally:
            if "" != conn:
                conn.close()
예제 #4
0
    def deal(trans_id, trans_script_name,trans_script_arvg):
        try:
            log.normal("执行命令: 命令编号: %d 脚本名称: %s 参数:%s" % (trans_id, trans_script_name, trans_script_arvg))

            os.system("python script/%s %s" % (trans_script_name, trans_script_arvg))

        except Exception as e:
            log.exp("执行命令: 命令编号: %d 脚本名称: %s 参数:%s" % (trans_id, trans_script_name, trans_script_arvg), e)
예제 #5
0
    def deal(filename):
        try:
            filename_before = "cache/sound/" + "before_" + filename
            log.normal("开始处理音频文件:" + filename_before)
            # 转换文字
            baidu_voice.Voice.get_text(filename_before)

            # 重命名文件,避免表明重复扫描
            os.rename(filename_before, "cache/sound/" + "end_" + filename)
            log.normal("音频文件处理完毕:" + filename_before)

        except Exception as e:
            log.exp("处理音频文件发生异常: ", e)
예제 #6
0
    def parse_text_result(data):
        data = json.loads(data.decode("utf-8"))
        if "success." == data["err_msg"]:
            result = data["result"][0]
            # 正则去除标点符号,空格等
            p = re.compile("([,。 ]?)")
            result = p.sub("", result)
            if "" != result:
                command.Command.insert(result)
            else:
                log.normal("语音转文字为空")

        else:
            log.warning("语音转文字失败。原因:" + data["err_msg"])
예제 #7
0
    def start():
        # 扫描目录
        root_dir = "cache/sound"
        log.normal("开始扫描音频文件...")
        while True:
            try:
                for file in os.listdir(root_dir):
                    # 搜索 before_ 开头的wav文件
                    re_wav = re.compile(r'^before_(.+)')
                    m = re_wav.match(file)
                    if m:
                        # 开始处理音频文件
                        VoiceScan.deal(m.group(1))

            except Exception as e:
                log.exp("扫描音频文件发生异常: ", e)
예제 #8
0
    def tts(cls, text):
        if len(text) > 1024:
            log.warning("tts文本过长")
            return False

        log.normal("TTS: " + text)
        # 参数
        p_token = cls.get_access_token()  # 开放平台获取到的开发者 access_token
        p_cuid = "FC-AA-14-D0-1D-67"  # 用户唯一标识,用来区分用户,填写机器 MAC 地址,长度为60以内
        request_url = "http://tsn.baidu.com/text2audio?"
        data = {
            "tex": text,
            "lan": "zh",
            "tok": p_token,
            "cuid": p_cuid,
            "ctp": 1,
            "spd": "4",
            "pit": "3",
            "vol": "9",
            "per": "3",
        }
        request_url_tts = request_url + parse.urlencode(data)

        try:
            with request.urlopen(request_url_tts) as f:
                data = f.read()
                if 200 != f.status:
                    # 获取错误,返回false
                    log.warning("获取baidu_tts失败,网络错误")
                    return False
                log.normal("获取baidu_tts成功")

                # 保存到文件
                random.seed()
                filename = "cache/mp3/" + datetime.now().strftime("%Y-%m-%d_%H_%M_%S") + \
                           str(random.randint(0, 99999)) + ".mp3"

                with open(filename, "wb") as file:
                    file.write(data)

                # 播放
                cls.play_mp3(filename)
                return True

        except Exception as e:
            log.exp("获取baidu_tts发生异常。", e)
            return False
예제 #9
0
def start():
    # 开启声音输入
    pa = pyaudio.PyAudio()
    stream = pa.open(format=pyaudio.paInt16,
                     channels=1,
                     rate=config.RATE,
                     input=True,
                     frames_per_buffer=config.NUM_BLOCK)

    save_count = 0
    save_buffer = []
    start_recode = 0
    log.normal("开始监听麦克风...")
    while True:
        # 读入NUM_SAMPLES个取样
        string_audio_data = stream.read(config.NUM_BLOCK)
        # 将读入的数据转换为数组
        audio_data = np.fromstring(string_audio_data, dtype=np.short)
        # 计算大于LEVEL的取样的个数
        large_sample_count = np.sum(audio_data > config.LEVEL)
        if large_sample_count < config.COUNT_NUM:
            # 未达到记录等级
            if save_count > 1:
                save_count -= 1
                save_buffer.append(string_audio_data)
            else:
                if 1 == start_recode:
                    start_recode = 0
                    save_buffer.append(string_audio_data)
                    log.normal("录音结束")
                else:
                    save_buffer = [
                        string_audio_data,
                    ]
                    time.sleep(0.01)

        else:
            # 达到记录等级
            # 将要保存的数据存放到save_buffer中
            save_buffer.append(string_audio_data)
            if 0 == start_recode:
                save_count = config.SAVE_LENGTH
                start_recode = 1
                log.normal("开始录音")

        if 0 == start_recode:
            # 将save_buffer中的数据写入WAV文件,WAV文件的文件名是保存的时刻
            if len(save_buffer) > 1:
                filename = "cache/sound/before_" + datetime.now().strftime(
                    "%Y-%m-%d_%H_%M_%S") + ".wav"
                save_wave_file(filename, save_buffer)
                save_buffer = []
                log.normal(filename + " 保存文件")
예제 #10
0
    def trans(command_id, content):
        try:
            log.normal("执行命令: 命令编号: %d 内容: %s" % (command_id, content))

            try:
                conn = ""
                conn = connector.connect(host=mysql_con.HOST,
                                         user=mysql_con.USERNAME,
                                         password=mysql_con.PASSWORD,
                                         port=mysql_con.PORT,
                                         database=mysql_con.DATABASE,
                                         charset=mysql_con.CHARSET)
                cursor = conn.cursor()
                cursor.execute("""SELECT * FROM translates WHERE
                                (`type`=1 AND command=%s)
                                OR
                                (`type`=0 AND command LIKE %s)""",
                               (content, "%" + content + "%", ))

                is_exec = False
                # 获取所有记录
                row = cursor.fetchone()
                if None is not row:
                    # 处理
                    CommandScan.deal(row[0], row[2], row[3])
                    is_exec = True

                cursor.close()
                if False is is_exec:
                    log.normal("命令未执行: 命令编号: %d 内容: %s" % (command_id, content))

            except Exception as e:
                log.exp("翻译命令: %s" % content, e)

            finally:
                command.Command.exec(command_id)
                if "" != conn:
                    conn.close()

        except Exception as e:
            log.exp("翻译命令: 命令编号: %d 内容: %s" % (command_id, content), e)
예제 #11
0
    def play_mp3(filename):
        log.normal("播放MP3 " + filename)
        try:
            if os.path.isfile(filename):
                if os.path.getsize(filename):
                    path_now = os.path.dirname(os.path.abspath(__file__))
                    if "nt" == os.name:
                        # windows
                        player = os.path.join(path_now, "player",
                                              "mpg123-win32.exe")
                    else:
                        # mac linux
                        player = os.path.join(path_now, "player", "mpg123-mac")

                    os.system("%s %s" % (player, filename))

                else:
                    log.warning("播放MP3错误,文件不存在:" + filename)
            else:
                log.warning("播放MP3错误,文件不存在:" + filename)
        except Exception as e:
            log.exp("播放MP3发生异常。", e)
예제 #12
0
    def start():
        # 扫描目录
        log.normal("开始扫描数据库中未完成的命令...")
        try:
            conn = ""
            while True:
                try:
                    conn = connector.connect(host=mysql_con.HOST,
                                             user=mysql_con.USERNAME,
                                             password=mysql_con.PASSWORD,
                                             port=mysql_con.PORT,
                                             database=mysql_con.DATABASE,
                                             charset=mysql_con.CHARSET)
                    cursor = conn.cursor()
                    cursor.execute("SELECT * FROM command WHERE status=%s ORDER BY posttime",
                                   ('0', ))

                    # 获取所有记录
                    results = cursor.fetchall()
                    for row in results:
                        # 处理
                        CommandScan.trans(row[0], row[1])

                    cursor.close()

                    time.sleep(1)

                except Exception as e:
                    log.exp("扫描音频文件发生异常: ", e)

                finally:
                    if "" != conn:
                        conn.close()

        except Exception as e:
            log.exp("扫描数据库未完成命令", e)
예제 #13
0
    def get_access_token():
        if "" != Voice.access_token_cache:
            log.normal("从缓存获取baidu_access_token成功")
            return Voice.access_token_cache
        # access_token 保存文件
        access_token_filename = "cache/token/baidu_access_token"
        # 计算时间差,21天换一次
        modifiedtime = time.localtime(os.stat(access_token_filename).st_mtime)
        y = time.strftime('%Y', modifiedtime)
        m = time.strftime('%m', modifiedtime)
        d = time.strftime('%d', modifiedtime)

        try:
            if 21 > (datetime.now() - datetime(int(y), int(m), int(d))).days:
                with open(access_token_filename, "r") as file:
                    Voice.access_token_cache = file.read()
                    log.normal("从文件获取baidu_access_token成功")
                    return Voice.access_token_cache

        except BaseException as e:
            log.exp("获取baidu_access_token发生异常。", e)
            return False

        # 请求地址
        grant_type = "client_credentials"  # 固定值
        client_id = "dnHpAdOFm2jxG0rmnfDbxSsT"  # api key
        client_secret = "c5046dee23e31cf9b542953425f7821e"  # secret key
        request_url_token = "https://openapi.baidu.com/oauth/2.0/token?grant_type=" + grant_type\
                            + "&client_id=" + client_id \
                            + "&client_secret=" + client_secret

        try:
            with request.urlopen(request_url_token) as f:
                data = f.read()
                if 200 != f.status:
                    # 获取错误,返回false
                    log.warning("获取baidu_access_token失败,网络错误")
                    return False
                data = json.loads(data.decode('utf-8'))
                log.normal("获取baidu_access_token成功")

                # 保存到文件
                with open(access_token_filename, "w") as file:
                    file.write(data["access_token"])

                Voice.access_token_cache = data["access_token"]

                return Voice.access_token_cache

        except Exception as e:
            log.exp("获取baidu_access_token发生异常。", e)
            return False