Adobe Premiere ProでWhisperを使って自動で字幕を生成したい！【ExtendScript+Whisper CLI】

自分は旅行に行ったときに動画を撮影してます
それを編集したものを仲間内で公開しているのですが・・・

![q1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294925/5ebe12ba-a6f0-983e-f256-6c955e48e6aa.png)
音声を聞き取る→文字起こしする→字幕を配置する→タイミングを調整する→めんどくさい！

この字幕には以下の特徴があります

・縦書きである
・話者の発音のタイミングで行が追加されていく
・縁取り処理がされている
・影がついている
完全に某番組のシステム・・・

これを、AIをつかって自動できないかということを試してみました。

# そもそも

Adobe Premiere Proには自動文字起こし機能がついています
結構評判は良いみたいですが、ロケ系の動画ではどうなのか・・・

ということでこちらの性能を見てみましょう

![q32.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294925/84153a6d-63ec-a838-e26e-f2484c2de23f.gif)
ちなみに検証に使う動画は**せっかく沖縄旅行に行ったのに台風がきたときのやつ**を使います
<br/>

|答え|Adobe Premiere Pro自動文字起こし|
|---|---|
|終わりの沖縄が体験できる|終わりの沖縄が体験できる|
|これは終わりの沖縄です|好例は終わりの沖縄です|
|ニュースとかで見たことあるよ　こういう映像|ニュースとかで見たことある予告映像|
|え？　なんか沖縄で台風がみたいなときに|写真ばえっ何か沖縄で台風がみたいな旅|
|いや～終わってる沖縄体験できてうれしいな|いや終わってる沖縄を体験できてうれしいな|
|音楽だけが虚しく|音楽だけが目立つ|
|響いとるよ　虚しいよ音楽だけなってて　悔し～|グリズリー達や空しい、音楽だけやって|
|やばい風も強くなってきてます　これ|てくやすやばいかでも辛くなってきてます　これ|

う～～～ん
悪くはないんだけど、実用はできないくらいの性能・・・

しかも、この自動文字起こしで作成した字幕は縦書きテキストに変換できないんですよね


ということで本命のWhisperを使ってみる！
今回は Whisper CLIの方を使います

https://github.com/openai/whisper

```python
model = whisper.load_model("medium")
```
base, smallに比べて精度が高かったmediumを使用


|答え|Whisper-medium|Adobe Premiere Pro自動文字起こし|
|---|---|---|
|終わりの沖縄が体験できる|**終わりの沖縄が体験できる**|終わりの沖縄が体験できる|
|これは終わりの沖縄です|**これは終わりの沖縄です**|好例は終わりの沖縄です|
|ニュースとかで見たことあるよ　こういう映像|**ニュースとかで見たことあるよこういう映像**|ニュースとかで見たことある予告映像|
|え？　なんか沖縄で台風がみたいなときに|**なんか沖縄で台風がみたいな時に**|写真ばえっ何か沖縄で台風がみたいな旅|
|いや～終わってる沖縄体験できてうれしいな|**いやー終わってる沖縄体験できて嬉しいな**|いや終わってる沖縄を体験できてうれしいな|
|音楽だけが虚しく響いとるよ|**音楽だけが虚しく響いとるよ**|音楽だけが目立つ|
|虚しいよ音楽だけなってて　悔し～|**虚しい音楽だけ鳴ってて悔しい**|グリズリー達や空しい、音楽だけやって|
|やばい風も強くなってきてます　これ|**やばい風も強くなってきてますこれ**|てくやすやばいかでも辛くなってきてます　これ|

Whisperすごい！!

これは使ったほうが良いですね

と、いうことでPremiereから楽～にWhisperを実行できる機能を開発します


# できたもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294925/3e823ff4-fbc9-a25c-dc05-f38b3909b749.png)
Adobe Premiere Proの拡張機能を作ってみました

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294925/20e1994a-3ad1-1e43-b4bb-5ed1cc0e72b1.gif)
ボタンを押すと音声文字起こしされた字幕の.srtファイルと、
グラフィックされたテキストが入っている.xmlファイルが生成されます

どのような仕組みになっているかというと

run whisperを押す
↓
Media Encoderを起動する(hostscript.jsx)
↓
シーケンスをwavにエンコードする(hostscript.jsx)
↓
whisperを動作させるpythonコードを実行する(hostscript.jsx)
↓
wavを読み込んで自動文字起こし(whisper.pyw)
↓
文字起こしjsonを生成し、それをもとに.srtと.xmlを作る(whisper.pyw)

みたいな感じになっています。
srtファイルを読み込むとキャプションが追加され
xmlファイルを読み込むと一番最初の字幕スタイルのグラフィックが追加されます

# 中身

CEPという機能を使って開発しているのですが、正直よくわからんのでここでの解説はしないです（というかできないです・・・）
https://helpx.adobe.com/jp/audition/using/enabling-cep-extensions.html

hostscript.jsx
```jsx
/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global $, Folder*/


function run_whisper(){
    var seq = app.project.activeSequence;
    
    var fileName = "C:\\tmp\\seq.wav";
    var presetPath = "C:\\tmp\\wav.epr";

    var folderObj = new Folder("C:\\tmp");
    folderObj.create();

    var seq = app.project.activeSequence;

    seq.exportAsFinalCutProXML("C:\\tmp\\tmp.xml"); //現在のシーケンスをxml化する

    app.encoder.launchEncoder(); //Meida Encoderを起動する
    app.encoder.encodeSequence(seq, fileName, presetPath, 0); //レンダーキューを追加する
    app.encoder.startBatch(); //エンコードを開始する
    
    app.encoder.bind("onEncoderJobComplete", function(jobID, fPath) { //エンコードが終了したら実行する
        file_object = new File("C:\\Program Files\\Adobe\\Adobe Premiere Pro 2023\\CEP\\extensions\\ai.whisper.core\\pyw\\whisper_run.pyw");  
        file_object.execute(); //pythonスクリプトを実行する
    });
}
```

Premireの拡張機能はhostscript.jsxにコードを書いていきます。
pythonファイル.pywを実行することでpythonを走らせているのですが、これはwindowsしか対応していないみたいです。
また、意外とやれることが少なくて、テキスト(グラフィック)の追加とかはできないみたいです。

https://ppro-scripting.docsforadobe.dev/


じゃあどうやって縦書きの字幕を追加しているかというと、
.xmlファイルを無理やり書き換えて実現しています

```xml
<effect>
	<name>サンプル</name>
	<effectid>GraphicAndType</effectid>
	<effectcategory>graphic</effectcategory>
	<effecttype>filter</effecttype>
	<mediatype>video</mediatype>
	<pproBypass>false</pproBypass>
	<pproExpanded>true</pproExpanded>
	<parameter authoringApp="PremierePro">
		<parameterid>1</parameterid>
		<name>ソーステキスト</name>
		<hash>52e45cab-9ba1-e522-da2e-2e0500000238</hash>
		<value>IAIAAAAAAABEMyIRDAAAAAAABgAKAAQABgAAAGQAAAAAAF4ANgAQAAwAMAAsAAAAAAAAAAAAAAArACQAIwAcAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAABcABwBeAAAAAAAAATgAAADUAAAA8AAAAAAAAQAAACBBAADIQgAAAAG0AAAAAAAAAQAAkEQAAEtEAAAKAAwAAAAIAAQACgAAAAgAAAA8AAAAAgAAACwAAAAQAAAAAAAKAA4AAAAEAAgACgAAAAAAgD8AAAA/AAAKAAgAAAAAAAQACgAAAAAAAD8CAAAANAAAABAAAAAAAAoAEAAEAAgADAAKAAAADAAAAAAAgD8AAAA/OP///wAACgAMAAQAAAAIAAoAAAAIAAAAAAAAP0r///8APz8/QP///0T///9a////AAAAAAEAAAAEAAAAEAAAAE5pdGFsYWdvUnVpa2EtMDYAAAAAAQAAAAwAAAAIAA4ABAAIAAgAAACEAAAAPAAAAAAANgAcAAAAAAAAAAAAGAAXABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAIAAQANgAAAAIAAAAUAAAAGAAAAAAAwEAAAAABHAAAAOD///8EAAYABAAAAAAACgAIAAUABgAHAAoAAAAAAAAABAAEAAQAAAAMAAAA44K144Oz44OX44OrAAAAAA==</value>
	</parameter>
```
しかし、xmlファイルにはbase64化された謎の文字列しか入っていないので、これを書き換える必要があります。
ここらへんは長くなるので別記事で書きたい・・・！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294925/ad596bb6-ec5f-a2fc-f06f-c8ba6f46554f.png)
なので、最初にこういう字幕のスタイルを1つ用意しておく必要があります。
これをコピー→書き換えして配置しているわけですね。
なんで画面いっぱいに文字を敷き詰めているかも、後々別記事で・・・

# 追加したい機能

・作業ディレクトリを指定できるようにする(現在はC:/tmp固定)
・wav.eprを手動で配置する必要がある(.jsxの相対パスの指定の仕方がわからない)
・MacOS対応
・whisper実行中のダイアログみたいなやつを出せるようにする
・PythonとWhisperを自前で用意してもらうのがちょっと使い勝手悪い
```
0
00:00:00,000 --> 00:00:05,000
終わりの沖縄が体験できる

1
00:00:05,000 --> 00:00:10,000
これは終わりの沖縄です
```
・whisperのタイムスタンプが1秒単位になっているのを直したい(バグ？)
ちなみにsmallだとミリ秒単位で出るんですけど、途中から1秒単位になるのでバグっぽい



できればコード公開＆拡張機能の配布したい・・・ところですが
拙い部分が多すぎるので整理できたらGitでコードを公開しようかなと思っています！