README.md (5067 bytes)
1 # SubRead read-along for KOReader 2 3 A KOReader plugin that makes the book follow an audiobook narration. 4 5 [SubRead](https://subread.space) makes a subtitle file (`.srt`) for an 6 audiobook. The cue text is the text of the ebook itself. The cue times are the 7 times when the narrator reads each line. KOReader has no audio player, so you 8 play the audiobook in another app, on your phone or on the same device. This 9 plugin runs a clock with that player, turns the pages of the book for you, and 10 marks the line that the narrator reads. 11 12 ## Install 13 14 1. Copy the whole `subread.koplugin` folder into the `plugins` folder of your 15 KOReader installation: 16 17 ``` 18 koreader/plugins/subread.koplugin/ 19 ``` 20 21 2. Restart KOReader. 22 3. Open a book. The plugin is in the reader menu, under **Tools → 23 SubRead read-along**. 24 25 ## Make the subtitle file 26 27 1. Go to <https://subread.space> (there is also an Android app). 28 2. Give it the audiobook and the ebook. 29 3. Save the `.srt` file it makes. 30 31 Put the file beside the book file and give it the same name: 32 33 ``` 34 Dracula.epub 35 Dracula.srt <- found by itself 36 Dracula.en.srt <- also found by itself 37 ``` 38 39 If the file is somewhere else, open **Tools → SubRead read-along** and tap the 40 first line to select it with the file browser. The plugin remembers the choice 41 for that book. 42 43 ## Use it 44 45 1. Start the audiobook in your audio player. 46 2. In KOReader, open **Tools → SubRead read-along → Start read-along**. 47 3. The clock starts at the time of the first cue on the page you are reading, 48 or at the position you had last time. 49 4. Use **Sync to this page**, or select the words the narrator is reading and 50 choose **SubRead: sync here**, to set the clock exactly. 51 52 ### Controls 53 54 The controls dialog shows the clock, whether it runs, and the cue that is on. 55 56 | Control | What it does | 57 |---|---| 58 | Prev. cue / Next cue | Back or forward one cue | 59 | `-10 s` / `+10 s` | Back or forward ten seconds | 60 | Start / Pause | Starts or stops the clock | 61 | Stop | Stops the clock and takes the mark off | 62 | Sync to this page | Sets the clock to the first cue on the page | 63 | Go to time… | Sets the clock to a position you type | 64 | Speed | 0.5 to 3.0, for a player that runs fast | 65 | Offset | Seconds to add to the subtitle times. Use a positive value when the audio file starts with an intro that is not in the book. | 66 | What time is this page? | Shows the time of the first cue on the page, so you can seek your audio player there | 67 68 Select text in the book and use **SubRead: sync here** to set the clock to the 69 cue that holds those words. 70 71 The clock position, the speed and the offset are kept for each book. 72 73 ### Gestures and keys 74 75 The plugin adds three actions to the gesture manager and the key bindings: 76 77 * SubRead: controls 78 * SubRead: start or pause 79 * SubRead: sync to this page 80 81 ## How it finds the place 82 83 The plugin does not read the whole book for every cue. It takes the first few 84 words of the cue and searches forward from the page you are on, the same 85 search that KOReader's own full text search uses. A hit before the last found 86 place is dropped, so the follow can only move forward. Found places are kept 87 for the session. 88 89 When a cue is not found, the plugin keeps the last place and waits a few cues 90 before it searches again. The wait doubles with each miss. This keeps the cost 91 low when a stretch of the book is missing from the subtitle file. 92 93 After a jump that you asked for, the place can be behind the page you are on. 94 The plugin then reads the whole book once, and uses the place of the nearest 95 cue it already found as the lower limit. 96 97 A cue whose text starts with `*` has no place in the book. The plugin leaves 98 the view alone for such a cue. 99 100 ## E-ink 101 102 The screen is only redrawn when the cue changes. A timer tick on its own never 103 redraws anything. A mark that moves inside the same page uses the light `ui` 104 refresh. A page turn uses the `partial` refresh. 105 106 The mark is the same selection that KOReader draws for a full text search hit. 107 crengine draws it, so it costs no extra widget and it is never written into 108 your highlights. 109 110 ## Limits 111 112 * Only EPUB, FB2, TXT and HTML books work. PDF and DjVu have no xpointer, so 113 the place cannot be followed. The plugin says so and does nothing. 114 * The white space of the cue text and of the book text can differ. The search 115 folds white space, so this is not a problem. 116 * Ruby text (furigana, `<rt>`) is not in the cue text. The plugin searches for 117 a short piece of the cue, so a line with ruby usually still matches. A line 118 that does not match is skipped and the last place stays. 119 * "What time is this page?" needs a next page, so it does not work on the last 120 page of the book. 121 * The plugin cannot control your audio player. It only follows the clock. 122 123 ## Tests 124 125 The logic that does not need KOReader is in `subread/`. The tests are in 126 `spec/`. 127 128 With busted: 129 130 ``` 131 busted 132 ``` 133 134 Without a Lua interpreter with busted: 135 136 ``` 137 lua spec/run.lua 138 ``` 139 140 ## License 141 142 AGPL-3.0-or-later. See `LICENSE`. KOReader is AGPL-3.0, and this plugin is 143 loaded into it.