音頻轉文字分析

音頻轉文字分析

工作裏面需要用到音頻轉成文字做數據分析,自己就想着測試下看看,現在Python音頻轉文字的方法用很多種,其中比較常用的有:

1.調用百度AI,科大訊飛,google等api
2.自己做數據挖掘,利用神經網絡等算法訓練

因爲自己去做音頻轉化需要非常專業的音頻方面的知識,不是研究這方面的數據分析師是很難做出很好的算法,而百度和科大訊飛本身已經做的很好的了,本身也贈送了一定的免費使用時間,我這裏就使用他們的api做一下調用,分析下他們的轉化效果.
PS:我這裏的代碼是使用百度和科大訊飛的demo去寫的,感興趣的可以直接去官方查看,鏈接如下:
科大訊飛:https://www.xfyun.cn/
百度ai:https://ai.baidu.com/ai-doc/

轉化的文字在下面,這裏直接分析的結果:

  • 百度翻譯的內容完全看不懂啊…
  • 科大訊飛不愧是語音起家的,翻譯的結果確實比百度ai的要好一點,但是涉及專業的部分及語音問題仍然不夠好
  • 如果使用自己公司的數據庫,添加專業用詞,進行算法訓練,建立模型,可能會對實際的業務有更好的適用性,需要測試
  • 隱私內容已用xxxxx消敏
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import requests
import json
import sys
import base64
import hashlib
import hmac
import os
import time
import datetime
import re
import ssl
#百度api

IS_PY3 = sys.version_info.major == 3
if IS_PY3:
    from urllib.request import urlopen
    from urllib.request import Request
    from urllib.error import URLError
    from urllib.parse import urlencode
    timer = time.perf_counter
else:
    from urllib2 import urlopen
    from urllib2 import Request
    from urllib2 import URLError
    from urllib import urlencode
    if sys.platform == "win32":
        timer = time.clock
    else:
        # On most other platforms the best timer is time.time()
        timer = time.time

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

#填寫百度控制檯中相關開通了“音頻文件轉寫”接口的應用的的API_KEY及SECRET_KEY
API_KEY = 'xxxxx'   
SECRET_KEY = 'xxxxx'

"""  獲取請求TOKEN start 通過開通音頻文件轉寫接口的百度應用的API_KEY及SECRET_KEY獲取請求token"""

class DemoError(Exception):
    pass

TOKEN_URL = 'https://openapi.baidu.com/oauth/2.0/token'
# SCOPE = 'brain_bicc'  # 有此scope表示有asr能力,沒有請在網頁裏勾選 bicc
SCOPE = 'brain_asr_async'  # 有此scope表示有asr能力,沒有請在網頁裏勾選
# SCOPE = 'brain_enhanced_asr'  # 有此scope表示有asr能力,沒有請在網頁裏勾選

def fetch_token():
    params = {'grant_type': 'client_credentials',
              'client_id': API_KEY,
              'client_secret': SECRET_KEY}
    post_data = urlencode(params)
    if (IS_PY3):
        post_data = post_data.encode( 'utf-8')
    req = Request(TOKEN_URL, post_data)
    try:
        f = urlopen(req)
        result_str = f.read()
    except URLError as err:
        print('token http response http code : ' + str(err.code))
        result_str = err.read()
    if (IS_PY3):
        result_str =  result_str.decode()

#    print(result_str)
    result = json.loads(result_str)
#    print(result)
    if ('access_token' in result.keys() and 'scope' in result.keys()):
        if not SCOPE in result['scope'].split(' '):
            raise DemoError('scope is not correct')
#        print('SUCCESS WITH TOKEN: %s ; EXPIRES IN SECONDS: %s' % (result['access_token'], result['expires_in']))
        return result['access_token']
    else:
        raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')

"""  獲取鑑權結束,TOKEN end """

"""  發送查詢結果請求 """

#轉寫任務id列表,task_id是通過創建音頻轉寫任務時獲取到的,每個音頻任務對應的值
task_id_list = [
    "xxxxx"
    ]   


for task_id in task_id_list:


    url = 'https://aip.baidubce.com/rpc/2.0/aasr/v1/query'  #查詢音頻任務轉寫結果請求地址

    body = {
        "task_ids": [task_id],
    }

    token = {"access_token":fetch_token()}

    headers = {'content-type': "application/json"}

    response = requests.post(url,params=token,data = json.dumps(body), headers = headers)
# 科大訊飛
lfasr_host = 'http://raasr.xfyun.cn/api'

# 請求的接口名
api_prepare = '/prepare'
api_upload = '/upload'
api_merge = '/merge'
api_get_progress = '/getProgress'
api_get_result = '/getResult'
# 文件分片大小10M
file_piece_sice = 10485760

# ——————————————————轉寫可配置參數————————————————
# 參數可在官網界面(https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html)查看,根據需求可自行在gene_params方法裏添加修改
# 轉寫類型
lfasr_type = 0
# 是否開啓分詞
has_participle = 'false'
has_seperate = 'true'
# 多候選詞個數
max_alternatives = 0
# 子用戶標識
suid = ''


class SliceIdGenerator:
    """slice id生成器"""
    def __init__(self):
        self.__ch = 'aaaaaaaaa`'

    def getNextSliceId(self):
        ch = self.__ch
        j = len(ch) - 1
        while j >= 0:
            cj = ch[j]
            if cj != 'z':
                ch = ch[:j] + chr(ord(cj) + 1) + ch[j + 1:]
                break
            else:
                ch = ch[:j] + 'a' + ch[j + 1:]
                j = j - 1
        self.__ch = ch
        return self.__ch


class RequestApi(object):
    def __init__(self, appid, secret_key, upload_file_path):
        self.appid = appid
        self.secret_key = secret_key
        self.upload_file_path = upload_file_path

    # 根據不同的apiname生成不同的參數,本示例中未使用全部參數您可在官網(https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html)查看後選擇適合業務場景的進行更換
    def gene_params(self, apiname, taskid=None, slice_id=None):
        appid = self.appid
        secret_key = self.secret_key
        upload_file_path = self.upload_file_path
        ts = str(int(time.time()))
        m2 = hashlib.md5()
        m2.update((appid + ts).encode('utf-8'))
        md5 = m2.hexdigest()
        md5 = bytes(md5, encoding='utf-8')
        # 以secret_key爲key, 上面的md5爲msg, 使用hashlib.sha1加密結果爲signa
        signa = hmac.new(secret_key.encode('utf-8'), md5,
                         hashlib.sha1).digest()
        signa = base64.b64encode(signa)
        signa = str(signa, 'utf-8')
        file_len = os.path.getsize(upload_file_path)
        file_name = os.path.basename(upload_file_path)
        param_dict = {}

        if apiname == api_prepare:
            # slice_num是指分片數量,如果您使用的音頻都是較短音頻也可以不分片,直接將slice_num指定爲1即可
            slice_num = int(file_len / file_piece_sice) + (0 if (
                file_len % file_piece_sice == 0) else 1)
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['file_len'] = str(file_len)
            param_dict['file_name'] = file_name
            param_dict['slice_num'] = str(slice_num)
        elif apiname == api_upload:
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['task_id'] = taskid
            param_dict['slice_id'] = slice_id
        elif apiname == api_merge:
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['task_id'] = taskid
            param_dict['file_name'] = file_name
        elif apiname == api_get_progress or apiname == api_get_result:
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['task_id'] = taskid
        return param_dict

    # 請求和結果解析,結果中各個字段的含義可參考:https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html
    def gene_request(self, apiname, data, files=None, headers=None):
        response = requests.post(lfasr_host + apiname,
                                 data=data,
                                 files=files,
                                 headers=headers)
        result = json.loads(response.text)
        if result["ok"] == 0:
            print("{} success:".format(apiname) + str(result))
            return result
        else:
            print("{} error:".format(apiname) + str(result))
            exit(0)
            return result

    # 預處理
    def prepare_request(self):
        return self.gene_request(apiname=api_prepare,
                                 data=self.gene_params(api_prepare))

    # 上傳
    def upload_request(self, taskid, upload_file_path):
        file_object = open(upload_file_path, 'rb')
        try:
            index = 1
            sig = SliceIdGenerator()
            while True:
                content = file_object.read(file_piece_sice)
                if not content or len(content) == 0:
                    break
                files = {
                    "filename": self.gene_params(api_upload).get("slice_id"),
                    "content": content
                }
                response = self.gene_request(
                    api_upload,
                    data=self.gene_params(api_upload,
                                          taskid=taskid,
                                          slice_id=sig.getNextSliceId()),
                    files=files)
                if response.get('ok') != 0:
                    # 上傳分片失敗
                    print('upload slice fail, response: ' + str(response))
                    return False
                print('upload slice ' + str(index) + ' success')
                index += 1
        finally:
            'file index:' + str(file_object.tell())
            file_object.close()
        return True

    # 合併
    def merge_request(self, taskid):
        return self.gene_request(api_merge,
                                 data=self.gene_params(api_merge,
                                                       taskid=taskid))

    # 獲取進度
    def get_progress_request(self, taskid):
        return self.gene_request(api_get_progress,
                                 data=self.gene_params(api_get_progress,
                                                       taskid=taskid))

    # 獲取結果
    def get_result_request(self, taskid):
        return self.gene_request(api_get_result,
                                 data=self.gene_params(api_get_result,
                                                       taskid=taskid))

    def all_api_request(self):
        # 1. 預處理
        pre_result = self.prepare_request()
        taskid = pre_result["data"]
        # 2 . 分片上傳
        self.upload_request(taskid=taskid,
                            upload_file_path=self.upload_file_path)
        # 3 . 文件合併
        self.merge_request(taskid=taskid)
        # 4 . 獲取任務進度
        while True:
            # 每隔20秒獲取一次任務進度
            progress = self.get_progress_request(taskid)
            progress_dic = progress
            if progress_dic['err_no'] != 0 and progress_dic['err_no'] != 26605:
                print('task error: ' + progress_dic['failed'])
                return
            else:
                data = progress_dic['data']
                task_status = json.loads(data)
                if task_status['status'] == 9:
                    print('task ' + taskid + ' finished')
                    break
                print('The task ' + taskid +
                      ' is in processing, task status: ' + str(data))

            # 每次獲取進度間隔20S
            time.sleep(20)
APP_ID = "xxxxx"
SECRET_KEY = "xxxxx"
file_path = r"xxxxx"
api = RequestApi(appid=APP_ID, secret_key=SECRET_KEY, upload_file_path=file_path)
api.all_api_request()
# 注意:如果出現requests模塊報錯:"NoneType" object has no attribute 'read', 請嘗試將requests模塊更新到2.20.0或以上版本(本demo測試版本爲2.20.0)
# 輸入訊飛開放平臺的appid,secret_key和待轉寫的文件路徑
/prepare success:{'data': 'xxxxx ', 'err_no': 0, 'failed': None, 'ok': 0}
/upload success:{'data': None, 'err_no': 0, 'failed': None, 'ok': 0}
upload slice 1 success
/merge success:{'data': None, 'err_no': 0, 'failed': None, 'ok': 0}
/getProgress success:{'data': '{"status":2,"desc":"音頻合併完成"}', 'err_no': 0, 'failed': None, 'ok': 0}
The task xxxxx is in processing, task status: {"status":2,"desc":"音頻合併完成"}
/getProgress success:{'data': '{"status":3,"desc":"音頻轉寫中"}', 'err_no': 0, 'failed': None, 'ok': 0}
The task xxxxx is in processing, task status: {"status":3,"desc":"音頻轉寫中"}
/getProgress success:{'data': '{"status":9,"desc":"轉寫結果上傳完成"}', 'err_no': 0, 'failed': None, 'ok': 0}
task xxxxx finished
# 科大訊飛輸出結果,提取輸出文字
kx_result = api.get_result_request(taskid='xxxxx')
kx_result1 = json.loads(kx_result['data'])
kx_result2 = [i['onebest'] for i in kx_result1]
kx_result2
# 百度ai輸出結果,提取輸出文字
baiduai_result = json.dumps(response.json(), ensure_ascii=False)
baiduai_result1 = json.loads(baiduai_result)
baiduai_result2 =  baiduai_result1['tasks_info'][-1]['task_result']['result']
baiduai_result2

然後這個這個客服中心,請問是什麼?八零,嗯, 你好,我這邊買了那個xxxxx的那個設定了這個時間哦,跟你諮詢一下。那個啊,我現在就是把那個時間已經校長了423 11分,今天是星期五,然後呢,我是按照那個定時。就是我按照是那個唉。就是按照那個定時設定的,是從週一到週五早晨八點半,然後到晚上六點鐘早早晨八點半起,然後晚上六點鐘停。然後我就設定了然後電源電源線我也接上去了然後手動那時候的他們不是有那個活動嘛,對吧?手動手動開手動關都是好的,就是我再把他帶回到那個自動的時候,嗯,他們有沒有啓動吧?自動車沒啓動對。因爲現在是12點12點半了,中午12點半對吧?嗯,我做的那個時間,今天又是週五嘛,說的時間去了,這個時間段時間,現在的我這樣子,她沒有啓動。沒有啓動,對不對?我按那個手動自動那個在調那個開和關都可以。呃,十元是吧說着。怎麼了?讓他下哦。說那些啊!這個時間是比較長時間。之類的。我看好了。進入磁場。星期星期六,星期六,星期六。我我那個就是按照那個定時之後啊,他現在選擇的是一開,然後上面顯示的是,呃,週一週二週三週四週五。你先這個做好以後,然後等下等下等下要不要開學了?你喫什麼?我這樣說你們。弄好以後,然後。下面顯示auto嗎?哦,先上a寫字樓。建設是吧對。那時候說話也不知道了。你這個就是我,我是我這樣,我這樣說你不知道你能夠能夠理解它不是第一就是設定的,一開始一路開第一路關閉第一路關閉第一路上的時間,從時間從週一是週一,週二,週三,週四,週五,週日這樣的,那他是不是?就是說他就要檢測到今天是週一到週五之間的話,嗯,在這個點都會啓動和堅持是個概念嘛?就是你四個時間段當中會停止和關閉。那我是不是準備問題啊?那倒沒有,這麼看你是沒有充電嗎?充電要什麼充電方面,電池一直有的呀,對吧?對呀,然後現在上面的電源也插進去了呀。而且我手動手動的話,你那個左下角的那個自動一一行讓手動那個那個也是正常的呀。收到消息時,你先等一下,是xxxxx是吧?xxxxx其送到xxxxx先生。105 KO 5睇龍牛肉館壓羅羅羅羅斯雞肉像是高高興興的時候報核心是吧?你把他分分心就不感到心裏不?那現在這些是什麼東西呢?行了行了。繼續啊,對對對對對對。對對對對。就能20。要不要王者做了?嗯嗯,繼續的時候是吧?我漲死了。這個問題對不對啊?我去死,誰來管呀?嗯,關鍵所有的在線。沒有。官思索的說的是有,就是那一個。xxxxx。是不是?一起。就要6k了。走路過來。哦。嗯好不行。好不行。爲。爲。這是不認識,我認識。這鎖定。不用。真是。是的。真是。哦。說你。是不是?喫飯。你們是說的,所以。是啊!看到這個叫做把它撕開,就是跟着一個這個實驗才知道他在喫喫喫,他不用去。’

print(kx_result2)

‘您好,這裏xxxxx客服中心,請問什麼幫您? ‘, ‘呃你好,我這邊買的那個xxxxx的’, ‘那個設定的這個事情,我跟你諮詢一下。’, ‘那個行。’, ‘呃我現在就是把那個時間已經校準了,是xxxxx,今天是xxxxx,’, ‘然後呢我是按照那個定時’, ‘就是我按的是那個’, ‘就是按照那個定時設定的是從週一到週五早晨8:30,然後到’, ‘嗯晚上xxxxx起,然後晚上6:00 6:00停,’, ‘然後我就設定了然後xxxxx,我也接上去了。’, ‘然後手動的是好的,它上面不是有那個手動,嘛’, ‘對吧?’, ‘主動’, ‘手動開手動關都是好的。’, ‘就是’, ‘我再把它再歸到那個自動的時候,’, ‘呃他沒有沒有啓動,吧’, ‘自動車沒啓動,’, ‘因爲現在是xxxxx了,中午xxxxx了對吧?’, ‘嗯我做的那個時間今天就是週五嘛做的時間,就在這個時間段,’, ‘直接’, ‘現在他我這樣去他沒有啓動。’, ‘沒有啓動,’, ‘我按那個手動自動那個再調那個開和關都可以。’, ‘嗯史雲是吧?所指?’, ‘什麼?啊’, ‘好吧?’, ‘這個時間是比較’, ‘我沒有地方。’, ‘是的了。’, ‘那太好了。’, ‘呃’, ‘堅持啊’, ‘星期一星期二、星期三、星期四、星期五,’, ‘我我那個就是按照那個定時之後,啊’, ‘它現在顯示的是一開,然後上面顯示的是’, ‘呃週一週二週三週四週五’, ‘先這個測試好以後,然後’, ‘等一下說不定要不要開學了。’, ‘我這樣說你們’, ‘弄好以後,然後’, ‘上面顯示xxxxx嗎?’, ‘呃選項a選擇了a’, ‘寫冊是吧?’, ‘對。’, ‘憑什麼去外部了?’, ‘你這個就是我我是我這樣我這樣說您不知道您能不能夠理解他不是。’, ‘第一就是設定了一開對吧?’, ‘第一路開第一路關我第一路我上面時間從是從’, ‘週一週一週二週三週四週五都是這樣的。’, ‘那他是不是’, ‘就是說它就要檢測到今天是週一’, ‘到週五之間的話,’, ‘呃在這個點都會啓動和停止,’, ‘是這個概念嗎?’, ‘就是你是不是那個時間段都會停止和關閉?’, ‘那我是不是就沒有問題?’, ‘啊’, ‘嗯好,沒有這種卡你是沒有充電嗎?’, ‘充電要什麼充電它的電池一直有的。呀’, ‘記住了是吧?’, ‘對,啊然後現在上面的電源也接進去了。呀’, ‘而且我手動手動的話,你那個左下角的那個’, ‘自動一一橫槓手動,’, ‘那個那個也是正常的。’, ‘呀’, ‘稍等一下先生,您先等一下,是xxxxx是吧?’, ‘對。’, xxxxx, ‘現在稍等一下先生。’, ‘xxxxx。’, ‘估計農民用款呀農民用了,’, ‘是這一步。’, ‘最高興就是了報’, ‘核心內容。啊’, ‘你把它這個東西你不’, ‘感到心裏有數。’, ‘那那行。’, ‘這這就是人性的問題。’, ‘所以’, ‘就是’, ‘就是’, ‘噢對’, ‘噢對。’, ‘在那就好。’, ‘唉對。’, ‘嗯’, ‘嗯啊’, ‘啊’, ‘只要能轉賬了。’, ‘嗯’, ‘我就寫着說是吧?’, ‘因爲’, ‘可對。啊’, ‘我就是誰。’, ‘喂喂’, ‘嗯或者是說你賺錢,’, ‘唉就’, ‘不管是說的說的是喲就是哪一個,’, ‘啊’, ’ sorry,’, ‘是不是’, ‘啊’, ‘嗯’, ‘知道嗎?’, ‘做了不少。’, ‘對,還不清。’, ‘他們去。’, ‘喂’, ‘喂’, ‘真是的。’, ‘真的是否定。’, ‘對。嗯’, ‘嗯’, ‘平時’, ‘是的。’, ‘就是’, ‘噢’, ’ Sorry’, ‘是不是?啊’, ‘共xxxxx,’, ‘現在就是跳’, ‘xxxxx,’, ‘他就不是要到這個時間纔去了,’, ‘啊這些事事件還不如去。’

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章