Kindleをオーディオ化するスクリプトが公開されていたが、Macでしか動かなさそうだったので、その部分をWindows+Pythonで実現した。
Kindleを聴きたい
Audibleのヘビーユーザだ。英語版のサービスしかなかった頃から使っていて、100冊以上すでに本を持っている。
僕は車での通勤時間が長い(週に10時間以上)ので、オーディオブックはありがたい。 車で聴く場合、しっかり集中して聴くわけではないので、ある程度知っている物語のほうが理解しやすい。
ただ、日本語版は使ったことはあるけれど今は契約していない。 英語版と比べて、ラインアップが少ないし、本が高いのでなんだか手が伸びない。 日本語版のサービス開始当初は、定額で聴き放題だったのでお得感が強かった。そこから月会費制ではあるものの、月一冊だけおまけについてくるという仕組みに変わった。 そうすると、かなり高くなった印象がして、やめてしまった。
自分でオーディをソースを作るために、新聞のニュースを話させるスクリプトを書いてみたりしたり、いろいろと試してきた。 それでも、小説やビジネス書をまるごと音声化できるとうれしいなあという気はずっとしてきた。
そんなときに、ふと、Androidのニュースに出てきたのがdaimatzさんの試みだった。 どうやら、Kindleの画面を全ページスクリーンショットして、音声化するというものらしい。
ぜひやりたい!
説明を読んでみると、全ページスクリーンショットを撮って、縦書きの画像をGoogle Cloudを使って音声化する。 肝心の全ページスクリーンショットの部分がMac(OSX)限定なのがちょっとした障害だ。
でも、画像さえ準備できたら、なんとかなりそうだ。
画像を準備する部分は自力でなんとかしてみようか。
ちなみに、今の音声合成ってどんな感じなんだろう。自然なんだろうか? Youtubeの「ゆっくり」的な話し方だと、わかることはわかるけど、耳に残って夢に出てきそうだ。 ああいうレベルなら、がんばって画像準備の部分を実装してもすぐに使わなくなるのは目に見えている。 もっと自然なのがいい。
MicrosoftのText to Speechなら、自然な響きの音声でアプリに命を吹き込むことができるらしい。 ここでサンプルを試すことができた。かなり自然で、これならテキストを流し込んで快適に聴けるレベルだ。
問題は、縦書きテキストの画像からテキストを抽出することができるのか?
こちらは、この方法を紹介してくれたサイトの説明を見る限り、かなり精度がよさそうだ。
試行錯誤
自前で実装にトライ
ちょっとがんばるモチベーションが湧いてきたので、まずはdaimatzさんのプログラムを動かしてみることにする。
Google Cloudをインストールしようと試みるところで、いきなりつまづいた。 インストーラがエラーで止まってしまう。
インストーラが動かないというどうにもならない。とりあえず断念して、画像のテキスト化、テキストの音声化を行う別の道を探る。
まずは、音声サンプルを試したMicrosoftの方で実現できないかとテキストの音声化のサンプルをいじってみる。 短いテキストを流し込んで音声化するのは簡単だったが、長文はうまく読めるのかよくわからない。ドキュメントも理解できない。
なんだか、基本的な用語が分からなくて、書いてあることが全然頭に入ってこない。
OCRの方はさらにわからない。
スクリーンショット→テキスト化
困った状況になったけれど、諦めたくない。
仕方ないので、いろんなプログラムとかサービスを組み合わせて、自力で同じことを実現する道を探ってみる。
必要なことは次の3点だ。
- Kindleをページ送りしてスクリーンショットを撮る
- スクリーンショットをOCRにかけてテキストにする
- テキストを読み上げてMP3にする。
仮にdaimatzさんのスクリプトが動くなら、2と3はできる。 1はWindowsではできない。 使わずに放置しているMacBookをこのために引っ張り出すか?と迷ったけれど、それも面倒だ。
2と3については、もうしばらくぐぐることにして、ページめくりに手を付けた。
daimatzさんのプログラムでは、Mac(OSX)版のAutomatorを使って、Kindleのページを捲りながらスク リーンショットを撮っている。そして、ページの最後の判定はimagemagickの機能を使っているようだ。
Windowsでアプリケーションを操作するためには、Power Automate Desktopを使う。 スクリーンショットとページ送り、ページに連番をつけるところまでは簡単だった。
Power Automateは、MacのAutomatorと同じようなツールだ。ちょっと使ってみた感じで、Automatorのほうが使いやすい気がする。 UIのせいなのかな。いろんなことができそうな気がするけど、使い込みたくならない。 この点は、Microsoft製品はどれもそんなイメージがある。使い込めばけっこう使えるようなんだけど、愛着がわかない。
なぜだろうか?
スクリーンショットは撮れた。画像をテキスト化する部分はどうか?
スクリーンショットが撮れたのでそのままOCRして、保存してはどうだろうか。 Power AutomateにはOCR機能があるが、縦書きは対応できなさそうだ。 AutomateのOCRで使われているTesseractというツールは開発が続けられていて、縦書きにも 対応したバージョンがあるらしい。
これをいじってみる。 うまくいけば、Power Automateに組み込めるかもしれない。
日本語リソースをインストールして、OCRにかけてみると、ちゃんと認識する!
例えば、こんな感じでfilelist.txtにスクリーンショットのファイル名のリストを作って、tesseractを呼べば、一気にOCRしてくれる。
(filelist.txtがなぜかUTF-16と認識されて、文字コード変換しないと使えなかった。僕の環境に依存しているのかもしれない。)
ls -Name >filelist.txt \(path)\tesseract.exe -c page_separator='' filelist.txt output -l jpn_vert
図や表が含まれると、それを無理にOCRしようとして支離滅裂なものとなるのは残念だった。
もう一点、文字間にスペースがいちいち入っている。英単語の分かち書きのようなイメージなのか。 もちろんそういうスペースを削除するのはエディタやスクリプトを書けばいいので、気にしない。 必要なら、段落以外の改行を削除したりするなどして、できあがったテキストをクリーニングすることはそう難しくない。
さてこれで、全ページのスクリーンショットを撮る機能と、縦書きの画像をOCRする機能は別々ながらも実現できることがわかった。
次は、肝心の最後のページまで来たら終了という部分にとりかかる。 daimatzさんが説明している通り、imagemagickを使えばよいはずだ。
compare -metric AE newpic.jpg oldpic.jpg res.png
こうすれば、newpicとoldpicの比較結果がstderrに出力される。同じ画像なら0になる。
だが、Power Automateではうまく結果を得ることができなかった。
これこそ、僕の環境依存なのだが、変なメッセージが前に入ってしまって結果を評価できない。
The system cannot find the path specified. (システムがパスを見つけられなかったです)
コマンドはちゃんと動くので、環境変数か何かの設定がおかしいみたいだ。
困った。
だいたいここまで来て、もう疲れたので、Power Automateを放り出してしまった。 こういうGUIで設定していくものよりも、ちゃんとプログラムを書くものの方が性に合っているし、将来的にスキルとなる可能性が高い。 そんな気がした。
Python版を試す
GUIはやめるとして、Windowsの操作はPythonではできないのかな?と思い、調べてみると、pyautoguiというツールが使えそうだった。
フルスクリーン表示したKindleをトップに持ってきて、ページ送り、スクリーンショット、最後のページに来たら終了というところまでできた。
最初のバージョンはここまでが自動だった。このあと、できたjpegファイルを一括して選択してNuance Power PDFに送り込むと、PDFファイルが一つできる。
PDFができたら、Google Cloudに送ればよい。
ここで改めて、Google Cloudのインストールに取り組んで見る。
インストーラを使う方法で試行錯誤したが、結局だめ。
サイトになにか情報がないかと見ていると、ZIPファイルを見つけた。こちらを試すと、なんとインストールができた!
というわけで、daimatzさんのスクリプトが使えるようになった。 スクリーンショットを撮る部分は不要というか、使えないので、Python版の自前のスクリプトを使った。
そして、できた! 認識率もかなり高くて、自然に聴ける!
これでAudible化されていない書籍もどんどん聴くことができる。 ありがたい。
とりあえず完成版のスクリプト
だいたいできたけど、jpgのpdf化の部分も自動化してしまえそうだ。
それ用のライブラリ(img2pdf)を見つけた。
以下でbooksource.pdfにスクリーンショットをpdf化したものができあがる。 できあがったpdfをGoogle Cloudのバケットに貼り付けてしばらく待てば、mp3ができる。
使用しているツールは、Pythonとimagemagickだけだ。Pythonのライブラリは、pyautogui, img2pdfをインストールすれば動くはず。それと、スクリプトと同じ場所に、dummy.jpgという適当なjpegファイルをおいておく。 このファイルは、最初の比較用なのでなんでもいい。ただ、Kindleのスクリーンショットではないほうが良いと思う。
声の高さとか速さを自由に変えられるMicrosoftのサービスが未だに魅力的だけれど、とりあえず今はこれで満足だ。
# coding: UTF-8 import pyautogui as pa import subprocess, time import img2pdf kindle = "<フルパス>Kindle.exe" subprocess.run(kindle) res = b'2000' ct=0 newpic = 'dummy.jpg' screenshots = [] while res != b'0': ct = ct+1 prevpic = newpic pa.keyDown('left') time.sleep(1) if ct > 0: screenshots.append(prevpic) newpic= 'ss'+ "{:04d}".format(ct) +'.jpg' screenshot = pa.screenshot() screenshot.save(newpic) res = subprocess.run("compare -metric AE " + prevpic + " "+ newpic + " res1.png", stderr=subprocess.PIPE).stderr with open("booksource.pdf","wb") as f: f.write(img2pdf.convert(screenshots[1:]))