11-01 視頻文稿提取系統


導語

人工智能

​ 隨着人工智能的快速發展,各種智能化的需求也是層出不窮,像小米的小愛同學,iphone的siri,都可以將用戶說出來的話轉換成具體的操作執行。

​ 現在有這樣一個需求,將一段視頻轉換為文字存入文件當中,想想我們都玩了這么久的python了,而python作為人工智能的首選語言,肯定要使用python來實現這個需求,接下來就來看看如何實現它。

需求分析

語音識別現在我們需要將一段視頻轉換為文字

安裝工具

pip install ffmpy3

pip install baidu-aip

pip install pydub

實現思路

1、提取文字

按照需求嗎,我們的的最終目的就是要獲取視頻中的文字,在一段視頻當中包含文字信息的其實不是視頻文件而是音頻文件,所以我們需要解決的問題就是如何進行語音識別。

如果說由我們自己編寫從視頻中提取文字的邏輯代碼,肯定是非常費勁的,但是關於語音識別部分的功能,騰訊/百度/科大訊飛/等大廠都提供了自己的API,各位是可以憑借自己的喜好選擇。以下示例都是使用的百度的API。

首先第一步,我們需要知道百度的語音識別功能怎么使用,對視頻文件有什么需求。以下就是百度python SDK的文檔頁面:

百度api

在這個文檔中,對百度語音識別API所支持的音頻格式進行了明確,概況起來主要有三點要求:

  • 參數:16k 采樣率、16bit 位深、單聲道;
  • 格式:pcm(不壓縮)、wav(不壓縮,pcm編碼)、amr(壓縮格式);
  • 其他:完整語音文件,時長不超過60s。
from aip import AipSpeech

""" 你的 APPID AK SK """
APP_ID = '你的 App ID'
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'

client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

# 讀取文件
def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()

# 識別本地文件
client.asr(get_file_content('audio.pcm'), 'pcm', 16000, {
    'dev_pid': 1536,
})

2、提取音頻

音頻轉文字的需求我們通過百度的借口解決了,接着要解決的就是把目標視頻文件轉換為百度API所支持的音頻(對應格式,參數)。

將視頻文件的音頻轉換為對應格式的編碼,在百度中也有說明:

ffmpeg

我們可以通過f fmpeg對視頻文件進行轉碼,轉換成音頻:

ffmpeg -y  -i 16k.wav  -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm

上面這條語句的作用是把wav文件轉換為16k、16bits位深的單聲道pcm文件,其中16k.wav是輸入文件、16k.pcm是輸出文件,兩者之間的內容是輸出文件的參數設置。

在音頻提取過程中還要對音頻的采樣率、聲道數、碼率進行設置,同時指定輸出音頻格式。除此之外,由於百度API最多只支持60秒長度的音頻,而我們需要轉換的視頻長度通常要遠高於這個時長,所以還需要使用pydub對音頻文件進行切割,然后分段進行文字轉換。所以從視頻到音頻的大概流程應該是這樣的:

轉換流程

明確完思路之后,接下來就可以一步一步具體實現視頻轉文字的功能了。

代碼實現

1、視頻轉音頻

在python中使用ffmpeg需要借助於ffmpy3這個庫,語法格式也要做稍許調整。來看下面這段代碼,他的作用是把一段視頻轉換為wav文件:

  • 其中inputfile是待轉換的視頻文件,其參數為空;
  • outputfile是輸出文件路徑,其參數中對采樣率、聲道數以及文件格式等進行了指定;
  • global_options是全局參數,-y的作用是允許覆蓋已有文件;
# 視頻轉wav音頻
def video_to_wav(file):
    input_file = file
    file_type = file.split(".")[-1]
    print(file_type)
    output_file = input_file.replace(file_type, "wav")
    ff = FFmpeg(inputs={input_file: None},
                global_options=['-y'],
                outputs={output_file: '-vn -ar 16000 -ac 1 -ab 192 -f wav'})
    print(ff.cmd)
    ff.run()
    return output_file

2、音頻切割

獲取完一整段長音頻還要進行切割操作。音頻切割的關鍵是找准每一段的起始和結束的時間節點,所以首先我們要獲取整個音頻文件的總長度,然后以60秒為間隔進行切分,並計算每一段音頻開始秒數和結束秒數,然后切割提取。實現這個功能的代碼如下:

# 音頻切割,每段不長於60秒
def wav_split(file):
    main_wav_path = file
    path = os.path.dirname(file) + '/'
    sound_len = int(float(mediainfo(main_wav_path)['duration']))
    sound = AudioSegment.from_wav(main_wav_path)
    part_file_list = list()
    if sound_len > 60:
        n = sound_len // 60
        if n * 60 < sound_len:
            n += 1
    for i in range(n):
        start_time = i * 60 * 1000 + 1
        end_time = (i + 1) * 60 * 1000
        if end_time > sound_len * 1000:
            end_time = sound_len * 1000
        word = sound[start_time:end_time]
        part_file_name = '{}part_sound_{}.wav'.format(path, i)
        word.export(part_file_name, format='wav')
        part_file_list.append(part_file_name)
    return part_file_list

注:通過以上方法進行切割,可能會存在某一個讀音被切分在相鄰兩段音頻中的情況,從而在音頻到文字的轉換階段造成誤差。

3、音頻轉文字

現在進入本文的核心環節——文字提取,如果要自己寫這個功能的話估計費盡心思也寫不出來,但是如果使用各種語音識別API就簡單多了,使用百度語音識別API對一段音頻(小於60秒)進行文字提取的代碼如下,其中的APP_ID、API_KEY和SECRET_KEY需要到百度AI開放平台中注冊后才能獲取。

# 百度語音轉文字
def baidu_asr(file):
    def get_file_content(file):
        with open(file, 'rb')as fp:
            return fp.read()

    """ 你的 APPID AK SK """
    APP_ID = '11714929'
    API_KEY = '0bYRRoICqG8AGOGHmHOCMhXi'
    SECRET_KEY = 'WApZjExgg1tl9e1Rtl6xxpxNqDvieVVR'
    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    result = client.asr(get_file_content(file), 'wav', 16000, {
        'dev_pid': 1537,
    })
    return result

上面這段代碼中,首先建立一個語音識別對象client,然后調用asr方法完成文字的提取,'dev_pid'參數用來指定音頻中的語言類型,1537對應的是純中文普通話。目前支持的語言類型有以下幾種:

支持語言類型

4、總結

通過上面三個步驟,從視頻到文字的轉換流程就基本實現了,之后只需要把從每段音頻中提取的文字合並到一起輸出就可以。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM