見出し画像

pythonで長い音声・動画からの文字起こしを実装する

短い音声ファイルでの音声からの文字起こしはできましたので,本稿では長い音声・動画での文字起こし(できるだけ無料で)に実装したいです.

有料枠設定にしていますが,下記のサイトで他の記事もみれます.youtubeの投げ銭的な物として,お考えください.

事前準備

ここではSpeechRecognitionというモジュールを用いります.googleのAPIを間接的に利用します.
Speech-to-Text 公式API(opens new window)

pip install SpeechRecognition
# Successfully installed SpeechRecognition-3.8.1

音声のファイル変換

サンプルコードでは読み込む拡張子が「.wav」となっているため,mp3 -> wavに変換します.

ファイル変換はpython上でffmpegを実行します.

import subprocess

subprocess.run(['ffmpeg', '-i', 'aps-smp.mp3', 'aps-smp.wav'], encoding='utf-8', stdout=subprocess.PIPE)


長い音声のテキスト変換

SpeechRecognitionは最大で1分程度の音声ファイルしか変換できません.

そこで,30秒単位で音声・動画を分割して逐次的に文字起こしを実施し,その後一括で文字起こししたテキストを統合・整理します.

import os
import glob
import shutil
import subprocess
import speech_recognition as sr

# 音声ファイルの分割
import wave
import math
import struct
from scipy import fromstring, int16# mp4から音声ファイルへの変換
def mp4_to_wav(mp4f):
 wavf = mp4f.replace('.mp4', '.wav')
 subprocess.run(['ffmpeg', '-i', mp4f, wavf], 
                 encoding='utf-8', stdout=subprocess.PIPE)
 return wavf
# 音声ファイルの分割(デフォルト30秒)
def cut_wav(wavf,time=30):
 # timeの単位は[sec]
 # ファイルを読み出し
 wr = wave.open(wavf, 'r')
 # waveファイルが持つ性質を取得
 ch = wr.getnchannels()
 width = wr.getsampwidth()
 fr = wr.getframerate()
 fn = wr.getnframes()
 total_time = 1.0 * fn / fr
 integer = math.floor(total_time) # 小数点以下切り捨て
 t = int(time)  # 秒数[sec]
 frames = int(ch * fr * t)
 num_cut = int(integer//t)
 # waveの実データを取得し、数値化
 data = wr.readframes(wr.getnframes())
 wr.close()
 X = fromstring(data, dtype=int16)
 
 # wavファイルを削除
 os.remove(wavf)
 
 outf_list = []
 for i in range(num_cut):
     # 出力データを生成
     output_dir = 'output/cut_wav/'
     os.makedirs(output_dir,exist_ok=True)
     outf = output_dir + str(i).zfill(3) + '.wav'
     start_cut = i*frames
     end_cut = i*frames + frames
     Y = X[start_cut:end_cut]
     outd = struct.pack("h" * len(Y), *Y)
     # 書き出し
     ww = wave.open(outf, 'w')
     ww.setnchannels(ch)
     ww.setsampwidth(width)
     ww.setframerate(fr)
     ww.writeframes(outd)
     ww.close()
     
     # リストに追加
     outf_list.append(outf)
 
 return outf_list
# 複数ファイルの音声のテキスト変換
def cut_wavs_str(outf_list):
 output_text = ''
 # 複数処理
 print('音声のテキスト変換')
 for fwav in outf_list:
     print(fwav)
     r = sr.Recognizer()
     
     # 音声->テキスト
     with sr.AudioFile(fwav) as source:
         audio = r.record(source)
     text = r.recognize_google(audio, language='ja-JP')
     
     # 各ファイルの出力結果の結合
     output_text = output_text + text + '\n'
     # wavファイルを削除
     os.remove(fwav)
     
 return output_text

# mp4からwavへの変換から音声のテキスト変換まで
def mp4_to_text(mp4f):
 # 出力ディレクトリ
 shutil.rmtree('output/cut_wav/')
 os.makedirs('output/cut_wav/', exist_ok=True)
 
 # 音声ファイルへの変換
 wav_file = mp4_to_wav(mp4f)
 
 # 音声ファイルの分割(デフォルト30秒)
 cut_wavs = cut_wav(wav_file)
 
 # 複数ファイルの音声のテキスト変換
 out_text = cut_wavs_str(cut_wavs)
 
 # テキストファイルへの入力
 mp4f_name = os.path.basename(mp4f)
 txt_file = 'output/' + mp4f_name.replace('.mp4', '.txt')
 print('テキスト出力')
 print(txt_file)
 f = open(txt_file, 'w')
 f.write(out_text)
 f.close()
# 変換の実行
mp4_to_text('******.mp4')


参考サイト

ここから先は

0字

¥ 100

この記事が気に入ったらサポートをしてみませんか?