Приветствую. Недавно я увидел 1TB в статистике книг Audiobookshelf и решил отпраздновать это, рассказав людям как крут Audiobookshelf.

Моя статистика Audiobookshelf
Моя статистика Audiobookshelf

Что такое Audiobookshelf?

Audiobookshelf - приложение, которое ставится на свой компьютер, сервер аудиокниг. Это каталог ваших аудиокниг. Логично, чтобы сервер был доступен в сети интернет.

Главная страница Audiobookshelf
Главная страница Audiobookshelf

Зачем вообще аудиокниги, когда есть нормальные, текстовые?

Если есть возможность, то лично я предпочитаю книги именно читать. В таком случае получается только книга и я. В случае аудиокниги появляется ещё прослойка в виде озвучивающего человека. И этот человек далеко не всегда имеет хорошую дикцию, правильные ударения. Ну или в принципе по интонации может быть не похож на голос в голове, которй хотелось бы под данную конкретную книгу.

Но не всё так просто. Глаза могут быть заняты или усталые. Как минимум, читать не получится за рулём. А вот аудиокнига - без проблем. Я слушаю аудиокниги по дороге на работу вне зависимости от того, как добираюсь туда: на трамвае, велосипеде, машине или даже пешком. Кроме непосредственно глаз может быть занято что-нибудь другое. Например, во время физического труда, ремонта, спорта, садоводства, картошко-копательства или другой монотонной работы. Знакомый 3D-художник слушает аудиокниги прямо во время работы, ему это не мешает. В общем, для именно аудиокниг тоже есть своя ниша.

А зачем мне вообще Audiobookshelf, если любой плеер читает mp3?

Если есть желание прослушать 1-2 книги, то какое-то специфическое программное обеспечение действительно не нужно. Проблемы начинаются, когда книг становится больше. И хочется видеть какую-то структуру, иметь красивое отображение, быстрый поиск и т.д.

Изначально я скачивал несколько аудиокниг на телефон, слушал их, удалял и скачивал следующую пару книг. Это не всегда удобно. Как минимум, я часто слушаю книги в дороге, нормальный интернет есть не всегда - соответственно, нужно готовиться заранее. И не факт, что нужная аудиокнига будет в наличии, или её будет легко найти.

В случае с большой библиотекой книг этап подготовки происходит заранее. Да, книги всё ещё нужно где-то купить, скачать, возможно переконвертировать под более удобный формат и битрейт. Но когда делаю это целой пачкой, то получается намного быстрее. И я всегда знаю, что моя любимая серия книг, в подходящей именно мне озвучке, лежит тихонько у меня на сервере и в любой момент может быть переслушана.

Отрицательные моменты тоже есть. Аудиокниги объёмные. У меня в 1ТБ влезло всего 2000 книг. Если покупать VPS, то это дорого. Я свои книги храню на домашнем NAS, который использует мой же интернет. И плачу дополнительно только за статический IP адрес. Поскольку слушателей у меня не много, то такая схема справляется хорошо.

Настройка Audiobookshelf

Итак, Audiobookshelf уже установлен на сервер, какие-то книги в его папочку положены, что делать дальше? Просто по умолчанию магии и красоты не будет - далеко не во всех книгах проставлены правильные теги, не всегда есть обложка, нет единого стандарта наименования и т.д.

Стандарт наименования - мой ключ к успешному использованию Audiobookshelf. Как именно именовать папки, чётко описано в документации. Только вот без конкретного примера не совсем понятно как этим пользоваться. Прикладываю свой пример.

Пример структуры папок

Audiobookshelf пример структуры папок
Audiobookshelf пример структуры папок

В корне папки Audiobookshelf находятся авторы в формате "Имя Фамилия" (например, "Дмитрий Храбров"). У каждого автора могут быть отдельные книги, или книги в цикле. На скриншоте выше, "Люцерус", "Сточные воды" и "Тимофей" - циклы. А вот "Легенда" - одиночная книга.

В фигурных скобках указывается имя озвучивающего. Так же в формате "Имя Фамилия". Это опциональная информация. Например, автор озвучки цикла "Сточные воды" - не известен. А вот "Тимофей" озвучивал Максим Зингаев. Но я очень стараюсь сохранять эту информацию и всегда её указывать. Как минимум, именно поэтому я вижу что "Легенда" - именно одиночная книга. Ну и ещё потому, что в ней нет подпапок.

У "Люцеруса" так же не указан автор озвучки, зато указан год, и использован несколько иной формат для указания, какая именно из книг является первой в цикле. "01" или "001" так же будет воспринято как первый номер, что особенно удобно при большом количестве книг. Год - может быть как публикации бумажной книги, так и озвучки. Для себя я так и не определился, у меня в библиотеке есть и то и то. Что, по факту, делает данное поле почти бесполезным.

У книги "Легенда" несколько озвучивающих - они указаны через запятую. Кстати, с авторами можно делать так же.

Настройка сканера

Чтобы определение структуры хорошо работало, нужно выставить структуру папок как наивысший приоритет для сканера книг библиотеки Audiobookshelf:

Audiobookshelf настройка сканера книг
Audiobookshelf настройка сканера книг

Конечно, хотелось бы чтобы Audiobookshelf магически сразу читал всю информацию из метаданных аудиофайлов. Только проблема в том, что очень редко они заполнены хорошо. Намного надёжнее иметь их под своим контролем. Именно поэтому файловая система имеет приоритет.

Обложки

Ещё одной особенностью именно аудиокниг является то, что он исторически используют квадратную обложку. Потому, что родной формат для них - CD. Советую привести все обложки к одному формату - тогда отображение будет красивым. Для себя я сделал вывод, что чем больше пикселей в картинке - тем лучше. Современные экраны даже телефонов очень качественные. И смотреть на красивую сочную картинку банально приятнее.

Если ваш друг Василий в подарок на день рождения начитал вашу любимую книгу, то может оказаться, что данная книга без обложки. В таком случае можно посмотреть в других официальных источниках, где данная книга уже продаётся официально:

LitRes Аудиокниги
LitRes Аудиокниги

Иногда квадратность обложки является проблемой, особенно для книг, которые никогда официально не выходили в аудиоформате. Но к таким книгам обычно есть обычная прямоугольная обложка. Я пользуюсь расширением Image cropper.

Обрезка изображения в Google Chrome
Обрезка изображения в Google Chrome

Я пробовал варианты с локальным редактированием с помощью GIMP / Paint.NET, пробовал сделать веб-скрипт для автоматической обрезки. Но самым удобным оказался именно вариант с расширением для браузера. Так как непосредственно саму обложку её нужно найти.

И, кстати, у того же поиска по картинкам от гугла есть замечательные фильтры. А именно, указать что в результатах хотим видеть именно квадратные (не прямоугольные) картинки большого размера:

Поиск больших картинок в Google
Поиск больших картинок в Google

И далее полученные результаты уже удобно скармливать в Image cropper, прямо из окна браузера.

Обложки - уровень "автоматизация", OPDS

Попытка номер раз - скачивание обложек с Флибусты или другого OPDS-каталога. Обычно там обложки прямоугольные, так что сразу же прикручиваем обрезку до квадрата: abs-opds

Обрезка скриншота в abs-opds
Обрезка скриншота в abs-opds

В реальности abs-opds я почти не использую. Редко удаётся угадать, где конкретно обрезать. И не всегда обложки лучшего качества. Гораздо проще загуглить. Или предоставлять ссылку на обложку напрямую в Audiobookshelf.

Обложки - автоматизируем гугление

Довольно часто гугл мне выдавал в принципе отличные результаты - он находил именно квадратную обложку именно аудиокниги, которую я ищу. Сразу же возникла идея эти результаты парсить и напрямую отдавать в Audiobookshelf минуя окно поисковика. С помощью ChatGPT и какой-то матери был получен код, приведенный ниже. Только в образовательных целях! Так как парсинг результатов нарушает пользовательское соглашение.

Полный PHP код Гугл-провайдера метаданных для Audiobookshelf
<?php
header('Content-Type: application/json');

$raw_do = $_GET['do'];
$do = str_replace('/search?', '', $raw_do);
parse_str($do, $search);

$count  = isset($_GET['count'])  ? (int)$_GET['count']: 6;
$prefix = isset($_GET['prefix']) ? $_GET['prefix'].' ': '';
$lang   = isset($_GET['lang'])   ? $_GET['lang']: '';
$query  = isset($_GET['query'])  ? $_GET['query']  : $search['query'];
$author = isset($_GET['author']) ? $_GET['author'] : $search['author'];

switch ($lang)
{
    case 'ru': $prefix = 'аудиокнига '; break;
    case 'en': $prefix = 'audiobook '; break;
}

if (!$author || !$query) {
    http_response_code(400);
    echo json_encode(['error' => 'Missing author or query']);
    exit;
}

$searchTerm = urlencode("$prefix $author $query");
$url = "https://www.google.com/search?tbm=isch&q={$searchTerm}&tbs=isz:l,iar:s";

$options = [
    'http' => [
        'method' => "GET",
        'header' =>
            "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36\r\n" .
            "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8\r\n" .
            "Accept-Language: en-US,en;q=0.9\r\n" .
            "Referer: https://www.google.com/\r\n" .
            "Connection: keep-alive\r\n"
    ]
];
$context = stream_context_create($options);

$html = @file_get_contents($url, false, $context);

if (!$html) {
    http_response_code(500);
    echo json_encode(['error' => 'Failed to fetch Google Images']);
    exit;
}

// Extract image URLs
preg_match_all('/"((https?:\/\/[^"]+\.(jpg|jpeg|png|gif|webp)))"/i', $html, $matches);

$imageUrls = [];
foreach ($matches[1] as $url) {
    if (stripos($url, 'gstatic.com') !== false) continue;
    if (stripos($url, 'encrypted-tbn0.gstatic.com') !== false) continue;
    $imageUrls[] = $url;
    if (count($imageUrls) >= $count) break;
}

$results = [];
foreach ($imageUrls as $url) {
    $results[] = [
        'title' => $query,
        'authors' => [$author],
        'cover' => $url,
        'description' => null,
        'publishedYear' => null,
        'genres' => [],
        'tags' => [],
        'publisher' => null,
        'isbn' => null,
        'language' => null,
        'explicit' => false
    ];
}

echo json_encode(['matches'=> $results], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
?>

Код использовать по аналогии с abs-opds.

Audiobookshelf поиск обложки в гугл
Audiobookshelf поиск обложки в гугл

Авторы

Я часто пользуюсь вкладкой "Авторы" в Audiobookshelf. Поэтому каждому автору проставлено фото, найденное в интернете. Или изображение, ассоциирующееся с этим автором. Это хорошо работает не только непосредственно на вкладке всех авторов, но и в поиске:

Audiobookshelf Авторы
Audiobookshelf Авторы

Редактирование книги

Каждую книгу есть смысл отредактировать, чтобы внести ещё больше информации.

Audiobookshelf Настройки книги
Audiobookshelf Настройки книги

В настройках книги очень рекомендую кнопку "Быстрый поиск". Часто она заполнит и жанры, и описание, и год публикации. Жанр очень полезен, т.к. позже по нему можно фильтровать книги. Описание мне просто приятно видеть, чтобы знать чего ожидать от данной книги.

Коллекции м плейлисты

Ещё одной интересной функциональностью Audiobookshelf являются коллекции. Вполне можно собрать коллекции: "100 лучших книг всех времён и народов", "Лучшие ЛитРПГ по версии ИгроМании", "Фэнтези по рекомендации Васяна", "Прослушать позже" и т.д.

Audiobookshelf Коллекции
Audiobookshelf Коллекции

Коллекции доступны всем пользователям Audiobookshelf. Плейлисты каждый пользователь имеет свои.

Библиотеки и языки

Audiobookshelf поддерживает 2 типа библиотек: книги и подкасты.

Audiobookshelf Библиотеки
Audiobookshelf Библиотеки

Однако, можно создать несколько библиотек одинакового типа. Каждая из них будет иметь свой каталог с данными, настройки, сканер и т.д. Если имеете большие библиотеки на нескольких языках - имеет смысл разделить их в разные библиотеки.

Мне же больше нравится, когда все книги находятся в одном месте. А язык я просто указываю двухбуквенным кодом при редактировании книги.

Оффлайн использование

Многие официальные мобильные клиенты поддерживает скачивание книг на своё устройство для прослушивания книг без доступа к сети. Например, в самолёте или роуминге.

Audiobookshelf Android без подключения к серверу
Audiobookshelf Android без подключения к серверу

На некоторых телефонах официальный клиент Audiobookshelf не любит скачивать книги в фоне. Приходилось постоянно держать экран включенным и смотреть как ползёт прогрессбар скачивания.

Озвучка текстовых книг

Иногда хочется послушать книгу, которую читал давным давно. И далеко не для всех книг есть аудио-версия. В таком случае, книгу можно озвучить самостоятельно программами типа Балаболка.

Хотелось чего-нибудь локального, модного, молодёжного, на нейронных сетях. Но обычно оно требует сложной настройки и мощный компьютер. Так родилась Читалка книг в голос - GitHub, 4PDA. Спасибо автору можно сказать здесь в комментариях ;-)

Читалка книг в голос
Читалка книг в голос

Читалка книг в голос у меня крутится на том же локальном NAS, за ночь может озвучить одну-две книги. Или можно использовать версию для компьютера - тогда одна книга озвучивается часа за 4, с полной загрузкой процессора.

Альтернативные клиенты

Audiobookshelf - программное обеспечение с открытым кодом, сервер. К нему могут подключаться неофициальные клиенты. Список клиентов есть в официальном FAQ Audiobookshelf.

Особенно хочу обратить внимание на Lissen, история создания которого есть здесь на хабре: Lissen: как я красивый плеер для аудиокниг писал .

Прослушивание книги в Lissen
Прослушивание книги в Lissen

Чего мне не хватает

Я перешёл на Audiobookshelf со Smart Audiobooks Player - это классный вариант для локального проигрывания книг с телефона:

Прослушивание книги в Smart Audiobook Player
Прослушивание книги в Smart Audiobook Player

Мне не хватает в мобильном клиенте Audiobookshelf:

  1. Предусиление громкости. Это актуально для аудиокниг плохого качества, записанных на тапок. Сейчас мне приходится предобрабатывать такие книги и очищать на компьютере, только потом скармливая их Audiobookshelf. Постобработки звука нет.

  2. Автоматического проигрывания следующей книги в серии. Это актуально при езде на велосипеде, мотоцикле и других ситуациях когда заняты руки. Аналогично не работает подхват следующего выпуска подкаста.

Но эти проблемы не слишком мешают жить. И т.к. код открыт - есть надежда, что эти функции когда-нибудь будут реализованы.

Заключение

Я меньше полугода пользуюсь Audiobookshelf, но уже слабо представляю свою жизнь без него. Просто напросто закрываются столько мелких вопросиков и проблем про аудиокниги, о которых даже не задумываешься. А в Audiobookshelf оно уже решено. В общем, очень советую попробовать.