Python入門トップページ


目次

  1. 仮想環境を構築し,watchdog をインストールする
  2. Watchdog でフォルダを監視する
  3. 新しいファイルを検知する
  4. 検知した新しいファイルを待ち行列フォルダに移動する
  5. 文字起こし処理用のワーカープログラムのひな形を作成する
  6. ワーカープログラムを常駐化する
  7. フォルダ監視とワーカープログラムでパイプライン処理する
  8. 処理用フォルダを設置してそこで処理を行う
  9. ファイルサイズの変化を監視する
  10. サイズの大きなファイルのコピーに対応する
  11. タイムスタンプを表示する
  12. Subprocess で外部コマンドを起動する
  13. WhisperX の設定を行う
  14. ワーカープログラムで音声データからの文字起こしを実行する
  15. 文字起こし結果を完了用フォルダに移動する
  16. ログを保存し例外を処理する
  17. サブフォルダに結果を格納する
  18. Ollama をインストールする
  19. Python から Ollama にプロンプトを送る
  20. Ollama 処理を関数化する
  21. 文字起こしデータから議事録を作成する
  22. サイズの大きなテキストファイルにも対応する
  23. ワーカープログラムで文字起こし結果から議事録を生成する
  24. 議事録をマークダウンファイルに出力する
  25. 文字コードを強制的に指定する

フォルダ監視により,音声ファイルから文字起こしと議事録生成を自動化しよう

文字起こしデータから議事録を作成する

既に音声から文字起こしした結果のデータがあるので,そのファイルを読み込んで ollama にプロンプトを送る方法を示します.具体的には次のとおり,15~16行目でテキストデータを読み込み,変数 transcript に格納します.18行目でプロンプトを作成します.24行目で ask_ollama 関数にプロンプトを渡し,変数 minutes に結果を格納して表示します.

ollama.py
import subprocess

def ask_ollama(prompt):

    result = subprocess.run(
        ["ollama", "run", "qwen3:8b", prompt],
        capture_output=True,
        text=True,
        encoding="utf-8"
    )

    return result.stdout


with open("sample/voice-sample01.txt", encoding="utf-8") as f:
    transcript = f.read()

# with open("sample/voice-sample99.txt", encoding="utf-8") as f: # 巨大なテキストファイル
#     transcript = f.read()

prompt = f"""
次の文字起こし結果から議事録を作成してください。

{transcript}
"""

minutes = ask_ollama(prompt)
print(minutes)

文字起こしデータは任意のテキストファイルでよいですが,今回は次のテキストデータを sample フォルダにファイル名 voice-sample01.txt で保存しておきました.なお,voice-sample01.txtはファイルサイズが30MBを超える巨大なテキストファイルです.

sample/voice-sample01.txt
[SPEAKER_00]: 日銀の上田総裁はきょう都内で講演し、中東情勢が不透明な状況が続いたとしても、利上げを行う可能性があるとの考えを示しました。日銀は今月15日から2日間、金融政策決定会合を開きます。会合を前に都内で講演した日銀の上田総裁は、
[SPEAKER_00]: 仮に中東情勢が不透明な状況が続くとしても、利上げに踏み切る可能性があるとの考えを示しました。

上のプログラムを実行します.voice-sample01.txt は短いテキストデータですが,議事録が生成されたことが分かります.ただし,日銀総裁の氏名は文字起こしには含まれておらず,議事録には正しくない適当な名前(上田康夫氏,正しくは植田和男氏)が利用されていることに注意してください.また,結果はマークダウン形式で生成されています.

(py313watchdog) PS C:\Users\rinsaka\Documents\python\watchdog> python ollama.py ⏎
Thinking...
Okay, I need to create a meeting minutes based on the provided transcription. Let me start by understanding the content.

The speaker mentions that the Bank of Japan's Governor Ueda gave a lecture in Tokyo today, stating that even if the Middle East situation remains uncertain, there's a possibility of raising interest rates. The Bank of Japan is holding a monetary policy decision meeting from the 15th to the 16th. Before the meeting, Governor Ueda gave this lecture, indicating the possibility of a rate hike despite the ongoing uncertainty in the Middle East.

First, I should structure the minutes with standard sections: date, time, location, attendees, agenda items, and discussion points. However, the original text doesn't mention attendees or specific agenda items beyond the meeting and the lecture. So maybe I can focus on the key points mentioned.

I need to note the key information: Governor Ueda's lecture, the context of the Middle East situation, the possibility of interest rate hikes, and the upcoming monetary policy meeting dates. Also, the fact that the lecture was held in Tokyo on the same day as the meeting.

I should check for any additional details. The original text mentions that the Bank of Japan is holding the meeting from the 15th to the 16th, so the meeting is two days. The lecture was given in Tokyo on the same day as the meeting, which is the 15th? Wait, the original says the meeting is from the 15th to the 16th, and the lecture was given today, which would be the 15th. So the lecture was on the day before the meeting starts.

I should make sure the date is correctly noted. The user might have provided the transcription without exact dates, so I'll use the information given. The minutes should be concise, capturing the main points without extra details. Also, the user might want the minutes in Japanese, as the original text is in Japanese. Let me confirm the language. The user provided the transcription in Japanese, so the minutes should be in Japanese as well.

Wait, the user's instruction is in Japanese, but the response should be in the same language as the query. The user wrote the query in Japanese, so the response should be in Japanese. However, the initial instruction was in Japanese, but the assistant's response needs to be in Japanese. Wait, the user wrote the query in Japanese, so the answer should be in Japanese. But the user's message includes the transcription in Japanese, and the request is to create the minutes. So the minutes should be in Japanese.

I need to make sure the minutes are structured properly. Let me outline the sections:

1. 会議の概要(日時、場所、出席者など)
2. 議題と議論の内容
3. 重要な決定や発言

But since the original text doesn't have specific attendees or detailed agenda items, maybe focus on the key points mentioned: Governor Ueda's lecture, the Middle East situation, the possibility of rate hike, and the upcoming meeting dates.

I should also mention that the lecture was given in Tokyo on the same day as the meeting, which is the 15th. The meeting is from the 15th to the 16th. So the lecture was on the day before the meeting starts.

Putting it all together, the minutes should state that Governor Ueda gave a lecture in Tokyo today, indicating the possibility of a rate hike despite Middle East uncertainties, and that the Bank of Japan is holding a monetary policy meeting from the 15th to the 16th.

I need to make sure the dates are accurate. The original says the meeting is from the 15th to the 16th, and the lecture was given today, which would be the 15th. So the lecture was on the 15th, and the meeting starts on the 15th. That might be a bit confusing, but the original text says the meeting is from the 15th to the 16th, and the lecture was given today, which is the day before the meeting. Wait, no. If the meeting is from the 15th to the 16th, that's two days. The lecture was given today, which would be the 15th, the day the meeting starts. So the lecture was on the same day as the meeting starts.

I think that's the correct interpretation. So the minutes should reflect that.

Now, translating that into Japanese minutes format, using appropriate terms like「議事録」,「日時」,「場所」,「出席者」,「議題」,「発言」, etc. Since the original doesn't mention specific attendees, maybe leave that section blank or note that it's a public lecture.

Also, the key point is Governor Ueda's statement about the possibility of raising rates despite Middle East tensions. The minutes should capture that the Governor indicated this possibility in his lecture before the meeting.

I think that's all. Let me structure the minutes accordingly.
...done thinking.

**議事録**
**日時**:2023年10月15日(日曜日)
**場所**:東京都内で行われた講演会

**出席者**:日本銀行総裁 上田康夫氏(講演者)、関係者

**議題**:
1. **中東情勢と金融政策の方向性**
   - 上田総裁は、中東情勢の不透明な状況が続く中でも、日本銀行が利上げに踏み切る可能性があると示唆しました。
   - これに先立って行われた講演では、経済的・金融的なリスクを踏まえながら、物価上昇や経済成長の継続的な見通しを重視する姿勢が強調されました。

2. **金融政策決定会合の準備**
   - 日銀は10月15日から2日間、金融政策決定会合を開催します。
   - 会合の前日に行われた講演は、今後の政策判断の背景となる重要な指針となるとされています。

**発言要約**:
- 上田総裁は、「中東情勢の影響が長期化する可能性があるにもかかわらず、日本経済の健全な成長と物価安定の観点から、利上げの検討は避けられない」と述べました。
- また、金融政策の柔軟な調整が求められるとの認識を示し、市場の動向や国際情勢の変化に即応する姿勢を強調しました。

**備考**:
- 講演は東京都内で行われ、金融政策決定会合の前日であったため、政策判断の参考となる重要な情報として注目されています。

---
*(※ 日付は仮定に基づく)*


(py313watchdog) PS C:\Users\rinsaka\Documents\python\watchdog>

一方で,30MBを超える巨大なテキストデータで文字起こし処理をしようとすると失敗します.具体的にには上のコードの15,16行目をコメントアウトし,18,19行目を有効にした上で,大きなファイルを準備して実行してください.

(py313watchdog) PS C:\Users\rinsaka\Documents\python\watchdog> python ollama.py ⏎
Traceback (most recent call last):
  File "C:\Users\rinsaka\Documents\python\watchdog\ollama.py", line 28, in <module>
    minutes = ask_ollama(prompt)
  File "C:\Users\rinsaka\Documents\python\watchdog\ollama.py", line 5, in ask_ollama
    result = subprocess.run(
        ["ollama", "run", "qwen3:8b", prompt],
    ...<2 lines>...
        encoding="utf-8"
    )
  File "C:\Users\rinsaka\anaconda3\envs\py313watchdog\Lib\subprocess.py", line 555, in run
    with Popen(*popenargs, **kwargs) as process:
         ~~~~~^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\rinsaka\anaconda3\envs\py313watchdog\Lib\subprocess.py", line 1040, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        pass_fds, cwd, env,
                        ^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
                        gid, gids, uid, umask,
                        ^^^^^^^^^^^^^^^^^^^^^^
                        start_new_session, process_group)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\rinsaka\anaconda3\envs\py313watchdog\Lib\subprocess.py", line 1555, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                       ~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
                             # no special security
                             ^^^^^^^^^^^^^^^^^^^^^
    ...<4 lines>...
                             cwd,
                             ^^^^
                             startupinfo)
                             ^^^^^^^^^^^^
FileNotFoundError: [WinError 206] ファイル名または拡張子が長すぎます。
(py313watchdog) PS C:\Users\rinsaka\Documents\python\watchdog>

このエラーはコマンドが長くなりすぎることが原因です.次のページではこうした問題に対処します.

目次に戻る