Personal Project Roadmap

ReadAloud ロードマップ MVP1→MVP8

Macを持たない環境で、iPhoneアプリとWindowsアプリを両輪で育てた10ヶ月分ではなく約2週間の記録(2026-07-04〜2026-07-22)

8本MVP
v0.9.0iOS
v2.0Windows
¥0〜費用
18日開発期間
Timeline

MVP1〜MVP8:積み上げの記録

コピペ読み上げから始まり、共有・URL記事・PDF・Word・Siri・OCR・Windows版へと、入力経路と読み上げエンジンを一つずつ広げてきた歩み。

1

MVP1|コピペ読み上げ

完了 2026-07-04 ・ v0.2.0
これで何ができる:文章をコピーして貼り付けるだけで、その場で音声で聞けるようになった。
読み方辞書 文タップジャンプ Apple Watch連携 ロック画面操作 Azure AI Speech(無料枠F0) OS標準へ自動フォールバック
設計のポイント:Azureが使えない状況でも聞けるよう、OS標準TTSへの自動フォールバックを最初から組み込んだ。
2

MVP2|Share Extension

完了 2026-07-05 ・ v0.3.2
これで何ができる:ブラウザや他アプリの「共有」ボタンから文章を送るだけで、ReadAloudの受信一覧に溜まり、そのまま聞けるようになった。
Share Extension App Groups Inbox方式 再生中バー
つまずきと解決:無料Apple ID+AltStoreの環境ではApp Groupsが素直に動かない。App Group IDを embedded.mobileprovision から実行時に解決する方式で突破した。
3

MVP3|URL本文抽出

完了 2026-07-06 ・ v0.4.0
これで何ができる:記事のURLを渡すだけで、広告やメニューを除いた本文だけを抜き出して聞けるようになった。
SwiftSoup p要素スコアリング(Readability系) 文字コード自動判定
つまずきと解決:note・X(旧Twitter)・一般記事で検証したところX非対応の壁に。og:descriptionフォールバックと「非対応です」の明示案内を追加して対応。
Sub Update v0.4.1 — 速度プリセット 0.25x〜4x。Azureは prosody × 再生レートの掛け算で4倍速を実現。
Sub Update v0.4.4(2026-07-07) — 再生中に「戻る」を押すと永久に固まるフリーズを根本修正。真因は「ナビバー大タイトル × TextEditor のレイアウト無限ループ」で、実機ハングレポート(.ips)を取得して初めて確定した。
4

MVP4|PDF読み上げ

完了 2026-07-07 ・ v0.5.0
これで何ができる:手元のPDFファイルをそのまま選ぶだけで読み上げられるようになった。
PDFKit テキスト抽出 fileImporter
5

MVP5|Word(.docx)読み上げ

完了 2026-07-08 ・ v0.6.0
これで何ができる:Wordファイル(.docx)もそのまま読み上げられるようになった。
ZIPFoundation word/document.xml展開 XMLParserで段落抽出
つまずきと解決:見出しと本文をどう区別するかが課題に。折返し幅より短い行+見出しパターンで段落を分離し、読点で終わる行はそのまま繋げるロジック(PDF側の見出し分離と共通化)で解決。
6

MVP6|Siri / App Intents

完了 2026-07-08実装 → 2026-07-09 v0.7.0で実機動作確認
これで何ができる:「Siriさん、この文章読んで」と声だけで読み上げを始められるようになった。
App Intents ReadTextIntent ReadClipboardIntent ReadLatestSharedIntent
つまずきと解決:Siri経由では複雑なデータを渡しにくい。App Group UserDefaultsに「1件だけ」置く使い捨てスロット方式でシンプルに解決。
Sub Update v0.7.0 — 「保存した文章」ライブラリ化。コピペ/共有/URL記事/PDF/Wordを1件1JSONで保存し、ソース別アイコンで見分けられるように。
Sub Update v0.7.1(2026-07-09) — 実機フィードバック5件に対応。折返し復元ロジックの共通化(TextReflow)、注・出典マーカー([1]・※2など)の読み飛ばし、読む対象を選ぶプレビューUI、キーボード周りのフリーズ感対策、ホーム全体のScrollView化。
7

MVP7|OCR読み取り

実機確認待ち 2026-07-11 ・ v0.8.0(実装+CIビルド成功)
これで何ができる:紙の書類や写真を撮影・選択するだけで、文字を読み取って読み上げられるようになる(実機確認待ち)。
Vision(VNRecognizeTextRequest) 端末内処理・追加パッケージ不要 ja / en対応 カメラ撮影 写真ライブラリ(最大10枚)
Sub Update v0.9.0(2026-07-13、実装+push済み) — スキャンPDFの自動OCRに対応。ページ単位のハイブリッド方式(テキスト層が20字未満のページだけ画像化してOCR)で処理を軽く保ちつつ対応。入口を「ファイル・写真から読み上げ」1ボタン+3択に統合し、OCR中の進捗表示と中止ボタンも用意。
8

MVP8|Windows版の誕生と、その声の世代交代

完了 2026-07-08 〜 2026-07-22
これで何ができる:iPhoneだけでなくパソコンでも、選んだ文章をホットキー一つで、自然な声で読み上げられるようになった。
Step A | Windows版アプリ新規作成
完了 2026-07-08 ・ win v1.0

PowerShell + WinForms + System.Speech(SAPI)によるゼロ依存GUI。インストール不要。貼り付け/クリップボード読込/.txt・.docx読込/グローバルホットキー Ctrl+Alt+R でどのアプリの選択文でも即読み上げ/読み上げ語のハイライト+追従スクロール/速さスライダー/声は自動判定(日本語=Haruka、英語=Zira)。

PowerShell WinForms System.Speech(SAPI) グローバルホットキー
つまずきと解決:.ps1がPowerShell 5.1にANSIと誤読され文字化け → UTF-8 BOM必須で解決。以降、新規.batファイルは純ASCIIのみで統一。
Step B | AivisSpeech化
実装完了・実音の確認待ち 2026-07-22実装 ・ win v2.0

読み上げエンジンをSAPI(Haruka)からAivisSpeech Engine(ローカルHTTP・完全無料・外部送信ゼロ・localhost:10101)へ世代交代。SAPIはフォールバック兼英語声として残存。話者は「まお」「コハク」(各スタイル選択可)。日本語→Aivis/英語→SAPI Zira/Aivis不達時→SAPI Harukaへ自動フォールバック。

AivisSpeech Engine(localhost:10101) WPF MediaPlayer WinFormsタイマーで終了検知 speedScale 0.5〜2.0 1チャンク先読み(runspace) 文単位ハイライト
実測(このPC・CPUのみ):合成速度は RTF ≒ 0.7(音声10秒ぶんの合成に約7秒)。150字ずつ切ると最初の音まで20秒かかってしまうため、チャンク上限を28字→70字→150字のランプ式に変更。実測で最初の音まで1.55秒、以降は再生しながら次を先読みするので途切れない。
つまずきと解決①:PowerShell 5.1 の Invoke-RestMethod は charset 指定のない応答を ISO-8859-1 として読むため、AudioQuery の日本語が壊れ、そのまま送り返すとエンジンが 500 を返す。→ 応答をバイト列で受け取り自前で UTF-8 デコードして解決。
つまずきと解決②:SAPI の SpeakProgressSpeakCompleted を PowerShell から登録すると、読み上げ中にプロセスが終了コード2で強制終了する(try/catch 不可・イベントは一度も発火しない)。v1.0 のコードでも再現=既存の不具合。→ SAPI も Aivis と同じチャンクキューにし、State の100msポーリングで進める方式へ統一。副産物としてハイライトが両エンジンで文単位に揃った。
Architecture

入力から音声出力までのパイプライン

入力経路が増えても、内部では共通のデータ形式に正規化してから読み上げエンジンへ渡す4層構造。

① 入力
📋 コピペ
📤 共有
🔗 URL
📄 PDF
📝 Word
📷 OCR
🎙️ Siri
② 正規化
🧩 ReadingItem / ExtractedArticle
③ 読み上げエンジン
🔊 OS標準
☁️ Azure(F0無料枠)
🗣️ AivisSpeech(ローカル)
④ 出力
🖍️ ハイライト
⏱️ 速度
📖 読み方辞書
Platform Matrix

iOS版 × Windows版 対比表

同じ「長文を聞く」目的でも、実現している機能とタイミングはプラットフォームごとに異なる。

機能 iOS版 Windows版
テキスト貼り付け/コピペ読み上げ
MVP1 v0.2.0

MVP8-a win v1.0
他アプリからの共有(Share Extension)
MVP2 v0.3.2
記録なし
URL記事の本文抽出
MVP3 v0.4.0
記録なし
PDF読み上げ
MVP4 v0.5.0
記録なし
Word(.docx)読み上げ
MVP5 v0.6.0

MVP8-a win v1.0
Siri / 音声での起動 Siri・App Intents
MVP6 v0.7.0
グローバルホットキー Ctrl+Alt+R
MVP8-a win v1.0
OCR画像読み取り 実機確認待ち
MVP7 v0.8.0
記録なし
スキャンPDF自動OCR
v0.9.0
記録なし
保存した文章のライブラリ化
v0.7.0
記録なし
読み上げエンジン OS標準 + Azure AI Speech(F0無料枠、自動フォールバック) SAPI(Haruka/Zira) → AivisSpeech(まお/コハク、ローカル0円)
MVP8-a → MVP8-b win v2.0
ハイライト表示 文タップジャンプ
MVP1
読み上げ語ハイライト+追従スクロール → 文単位表示に変更
MVP8-a → win v2.0
速度調整 0.25x〜4x(Azureはprosody×再生レート)
v0.4.1
速さスライダー → speedScale 0.5〜2.0
MVP8-a → win v2.0
読み方辞書 日本語音声のときだけ適用 日本語音声のときだけ適用
Lessons Learned

ハマりから得た教訓

2週間の開発で繰り返し効いてきた、次のプロジェクトにも持ち越すべき学び。

🩺

UIフリーズは推測せずハングレポートを取る

v0.4.4の「戻る」で永久フリーズする不具合は、実機ハングレポート(.ips)を取得して初めて「ナビバー大タイトル × TextEditorのレイアウト無限ループ」という真因にたどり着けた。当てずっぽうの修正より先に証拠を取る。

🔤

.batは純ASCII/.ps1はUTF-8 BOM必須

Windows PowerShell 5.1は.ps1をBOMなしだとANSIと誤読し日本語が文字化けする。以降.ps1はUTF-8 BOM必須、新規.batファイルは純ASCIIのみで統一するルールにした。

🔇

SoundPlayerは停止できない罠

System.Media.SoundPlayerは再生の途中停止ができず、止めようとするとプロセスごと落ちる。win v2.0ではWAVを一時ファイル化しWPF MediaPlayerで再生、WinFormsタイマーで終了を検知する設計に切り替えた。

🔐

無料Apple ID×AltStoreでのApp Groups

無料Apple IDとAltStoreの組み合わせではApp Group IDが固定されない。embedded.mobileprovisionから実行時に解決する方式で、Share ExtensionとApp本体のデータ共有を成立させた。

🗣️

読み方辞書は言語依存で効かせる

カタカナ読みの辞書を英語音声にそのまま当てると発音が崩れる。「日本語音声のときだけ適用」に修正し、iOS・Windows両方に反映した。

💥

「新機能で壊れた」と決めつけない

v2.0で英語読み上げ中にプロセスが強制終了したとき、v1.0のコードを取り出して同じ手順を流したら同じように落ちた。新しく書いた部分ではなく、SAPIのイベント登録という前からあった箇所が原因だった。犯人を推定する前に、旧版で再現するかを試す。

🈁

文字化けは「見た目」より先に壊れる

PowerShell 5.1はcharset指定のないJSON応答をISO-8859-1として読む。壊れた日本語をそのまま送り返した結果が「500 Internal Server Error」で、エラーメッセージだけ見ても文字コードが原因とは分からない。日本語を通すHTTPは、必ずバイト列で受けて自分でUTF-8デコードする。

⚖️

声優クローンは禁止、コストも見極める

方針としてOS標準TTS+正規サービスのみを採用。Azure Dragon HDはJapan East非対応・F0無料枠対象外・prosody非対応で見送り、ElevenLabsは1冊あたり約¥4,500で見送り、Windows版はローカル0円のAivisSpeechを採用した。