Я слушаю аудиокниги с 2014 года. За это время я перепробовал много разных сервисов: и с моделью “по подписке”, и те, что продают каждую конкретную книгу.


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


У него был и есть потрясающе красивый неофициальный iOS-клиент, которым я пользовался какое-то время. Осенью 2024 года Google наконец показала Pixel 9 и я решил, что пора попробовать Android


С большим сожалением я обнаружил, что мне сложно использовать официальное мобильное приложение для Audiobookshelf, других тогда не было, а возвращаться к популярным стриминговым площадкам мне не хотелось.


Так родилась идея написать Lissen — красивый, минималистичный и удобный клиент для Audiobookshelf.


Сегодня я расскажу про разработку, релиз и опыт использования приложения, которое я писал для себя.


Идея приложения


Оригинальный клиент Audiobookshelf поддерживал каталогизацию, закладки, несколько типов контента, но при этом им было сложно пользоваться из-за перегруженных экранов и неинтуитивной для Android-приложения вёрстки.


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


  • Приложение поддерживает только аудиокниги и не поддерживает никаких других типов контента.
  • У приложения интерфейс настолько чистый, что его не заметно при повседневном использовании.
  • Приложение сразу должно поддерживать офлайн-кеширование книг, чтобы им можно было пользоваться без интернета.
  • В приложении нет рекламы или платных функций, код будет доступен под какой-то максимально свободной лицензией.

Также я очень хотел сократ��ть количество переходов, которые должен сделать пользователь для того, чтобы начать слушать книжку.


Меня откровенно бесил UI подобных приложений, где из каталога я попадал сначала на экран с описанием книги, и только потом переходил к плееру. Это работало для магазина аудиокниг, но в случае с собственным сервером я уже заранее выбрал книги, которые хочу слушать.


После пары дней проектирования на салфетках два основных экрана приложения начали выглядеть приблизительно так:



Получается, что для успешного первого релиза приложение должно покрывать конкретный кейс, который больше всего мне был нужен:


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

Технологический стек


Такой объём разработки показался мне более-менее реальным, и я начал выяснять, как вообще в 2024 году пишут подобные штуки.


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


  • Для воспроизведения аудио по сети Google рекомендует использовать Media3.
  • UI Android-экранов тот же Google предлагает строить с помощью Jetpack Compose вместо устаревших XML-файликов с разметкой.
  • Для хранения метаданных о книгах и поддержки оффлайна лучше всего подойдёт Room, под капотом которого лежит понятный SQLite с поддержкой запросов.
  • Работу с сетью я реализую на Retrofit, потому что просто к нему привык в предыдущих своих мобильных приложениях. И вообще я консерватор.

То есть мой клиент Audiobookshelf — это более-менее стандартный медиаплеер с возможностью обращаться к файлам по уже существующему API и складывать их в локальный кеш вместе с метаданными, чтобы использовать приложение без сети.


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


Архитектура приложения


Когда я анализировал похожие приложения для других платформ, я видел, что многие из них поддерживают не только Audiobookshelf. Большая часть приложений, такие как Plappa и ShelfPlayer, давали возможность подключаться ещё и к Jellyfin или Emby, или воспроизводить локальные файлы, сохранённые в памяти телефона.


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


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


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



Я решил, что этот модульный подход приложения мне подходит, и скоро у меня была готова интеграция, кое-как прикрученная к UI приложения, чтобы было на чём её тестировать.


Проблемы модульности


Основное ограничение такого подхода — принципиальная изолированность каналов. Не только большая часть приложения ничего не знает об источниках данных, но и сами они ничего не знают друг о друге.


Я столкнулся с последствиями этой изолированности, когда попытался реализовать оффлайн-воспроизведение кешированных книг в виде отдельного независимого канала данных.
Если пользователь начинал слушать книжку в оффлайне, а затем подключался к серверу и перезапускал воспроизведение, важно было перейти к последнему месту — и не важно, что там помнит сервер.


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


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



Второй проблемой при интеграции клиента с Audiobookshelf API стала сложная структура ответа.


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


Я понимаю задумку разработчиков API: это способ дать пользователю возможность произвольно нарезать книжку на главы, никак не взаимодействуя с самим медиаконтентом. Это логично и удобно, но осознание пришло слишком поздно и стоило мне двух вечеров исправлений.


Я использовал для воспроизведения Media3, киллер-фича которого заключалась в возможности просто засунуть в него всю очередь воспроизведения и больше не думать о связности элементов. Фреймворк сам реализует и перемотку, и догрузку контента из сети, так что мне нужно было только правильно отображать воспроизводимый элемент, вытаскивая его порядковый номер прямо из медиаплеера.


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


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


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


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


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


Первая версия приложения


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


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


При этом я не имел ни малейшего представления, как в 2024 году правильно организовать MVVM Android-приложения, какие части системного фреймворка использовать и чем мне уберечь мои экраны от убийства об операционку.


Большую часть этого сервисного кода я написал вместе с нейросетками. OpenAI как раз к тому времени выкатил свою новенькую O1, которая заменила мне StackOverflow и гугление ответов на мои глупые вопросы.


В итоге структура кода приложения мало отличалась от той, которую рекомендует Google в своих гайдах. Jetpack-компоненты взаимодействовали с вьюмодельками, которые обращались к репозиториям, а те — делали запросы к выбранному медиаканалу через Retrofit. Всё как в большинстве стриминговых приложений, с той лишь разницей, что адрес сервера нужно было сохранить отдельно.


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


В какой-то момент я смог сказать, что приложение стало напоминать нечто рабочее.



Такой режим, правда, меня изрядно вымотал. Мне повезло, что последние строчки кода я дописал как раз к началу угасания энтузиазма.


Иконка приложения


Сверстать экраны приложения так, чтобы оно выглядело чисто и лаконично, мне помогли гайды от Гугла, нейросети и похожие приложения от других авторов. Сложнее было придумать, как назвать клиент и нарисовать для него какую-нибудь иконку — причём хотелось связать их общей идеей, которая помогла бы сделать приложение узнаваемым.


Отрисовка иконки заняла у меня чуть ли не половину времени от всей разработки. Приложение ассоциировалось с уютом и комфортом, и я хотел сначала нарисовать кота в наушниках, но так и не придумал к нему достойную идею.


Тогда я поговорил с нейросеткой о том, чем можно заменить кота, и машина, перемножив пару сотен матриц, оригинально предложила мне лису. Практически сразу я понял, что могу назвать приложение Lissen. Смотрите сами:


  • Романо- и германоязычная аудитория увидит схожесть со словом Listen и свяжет это с аудиокнижками или хотя бы просто с “аудио”.
  • Славяноязычные пользователи, скорее всего, заметят какую-никакую связь части названия с рыжей лисьей мордой.

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


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



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


Пререлиз


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


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


25 октября я написал в нём пост, где оставил ссылку на APK-файл на GitHub и предложил попробовать альтернативный клиент.



Большая часть ночи прошла в ответах, а к утру ста��о понятно, что Lissen не просто вежливо приняли.


Очевидно было, что приложение нашло свою целевую аудиторию из технически подкованных пользователей.


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


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


Всё это привело меня к трём важным выводам:


  • Я написал что-то полезное, и это можно развивать в надежде получить больше пользователей.
  • Никакой поддержки альтернативных серверов вроде Emby приложению не требуется. Вместо этого лучше сосредоточиться на типах контента, которые Audiobookshelf поддерживает, а моё приложение — ещё нет.
  • Мне срочно нужно поддержать тёмную тему.

Детские проблемы


Когда выходные закончились и радость от успешного релиза начала сходить на нет, пришло время разобрать фидбек типа “всё очень круто, но ничего не работает”. Обнаружились три основных проблемы:


Часть пользователей не использовала SSL для доступа к своим домашним серверам, подключалась по IP-адресу. Android-приложения по умолчанию запрещают такие подключения, и требовалось явно разрешить это, чтобы дать таким пользователям рабочее приложение.


Первая версия приложения поддерживала только аудиокниги. Это было моё осознанное решение, чтобы поскорее выпустить первый релиз, но я забыл ограничить типы библиотек, которые доступны для выбора. В итоге пользователи могли запросить неподдерживаемый контент — и приложение падало с грохотом.


Поддержку эпизодов я писал в последний момент и не успел внимательно её оттестировать. Иногда навигация приложения не справлялась, и пользователя выбрасывало в другую часть книги при попытке вернуться на 10 секунд назад.


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


ACRA


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


Lissen был и остаётся полностью свободным, поэтому тянуть в приложение Google-аналитику, которая собирает в том числе нужные мне стектрейсы, не хотелось. Очередной диалог с нейронкой привёл меня к ACRA — небольшой библиотечке, которая может репортить креши на отдельный бэкенд.


У меня крутилась арендованная ещё в седой древности виртуалка, поэтому поднять там ещё один джарник с бэкендом и настроить новое доменное имя оказалось несложно.


Спустя несколько дней у меня был список частых причин падения. Как оказалось, самая частая из них — нестабильность самого Media3, которая починилась значительно позже, с обновлением платформы Android.


Скриншотов тех самых багов у меня не осталось, поэтому придется показывать что есть


Скриншотов тех самых багов у меня не осталось


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


Github Issues


Общение с ними я поддерживал всё на том же Reddit, плавно переводя их на GitHub проекта, чтобы в результате общения оставались какие-то артефакты и можно было построить нормальный релизный цикл.


При этом я решил, что относительно просьб и предложений я займу следующую позицию:


  • Я автор, и я владею видением по развитию приложения. Только я решаю, какие запросы окажутся выполненными, а какие не соответствуют генеральной линии и будут отброшены.
  • Хотелось бы, чтобы пользователи рассказывали о проблемах и опыте использования больше и чаще, чем предлагали готовые решения.
  • Отказы — это нормально. Если пользователь говорит, что я глух к просьбам и не делаю того, чего он просит — часто он хочет какое-то другое приложение, а не Lissen.

Это суровая модель поведения, но в итоге она позволила мне удержать Lissen от скатывания в bloatware и искать решения проблем вместе с пользователями.


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


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


Другим популярным запросом стали подкасты.


Реализовать их поддержку оказалось просто: я ожидал, что многие пользователи захотят поддержку этого типа контента. Поэтому заранее знал, реализую их как отдельный медиа-канал на механизме, который позволял бы приложению интегрироваться с другими серверами типа Plex и Emby.


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


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


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


Я считал, что делаю эту фичу для других пользователей, как и таймер, но пока тестировал интеграцию в разработке — втянулся и теперь постоянно слушаю какие-то выпуски по дороге и в поездах.


Магазины приложений


Примерно к этому моменту я решил, что приложение достаточно зрелое, чтобы распространять его не только через посты на Reddit и свой гитхаб, но и через разные аппсторы.


До этого у меня уже был опыт публикации приложения в Google Play в 2016, но с тех пор многое изменилось.


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


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


Рассудив, что с Гуглом у меня обязательно будут проблемы, я решил, что заодно опубликую Lissen в тех альтернативных магазинах приложений, которые это позволят.


Первым в этом списке стал F-Droid. Это стор свободных приложений, который смог очень хорошо организовать процесс добавления новых пакетов. Я сделал мерж-реквест в репозиторий с метаданными, прошёл ревью, немного поругавшись с мейнтейнерами, и стал ожидать. Через пару дней приложение стало возможно установить из каталога, а обновлялось оно самостоятельно, используя механизм релизов гитхаба.


К сожалению, никаких данных о количестве установок магазин не даёт, поэтому я до сих пор не знаю, насколько это популярный способ для распространения Lissen, и считаю его резервным каналом доставки обновлений.


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


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


Как я и ожидал, большой популярности это приложению не принесло: на 30 марта 2025 года приложение из RuStore установило 108 человек, поэтому я поддерживаю актуальность Lissen там скорее на всякий случай.


Также я пытался опубликовать приложение в AppGallery, но быстро свернул лавочку. Для размещения пакета магазин требовал добавить в зависимости библиотеку с телеметрией, что либо выводило Lissen из категории свободного ПО, либо требовало от меня поддерживать отдельную версию.


И, наконец, Google Play, который, как мне показалось, сейчас ориентирован скорее на корпоративных разработчиков и большие студии, чем на инди и опенсорс.


Первая попытка пройти премодерацию закончилась тем, что у меня попросили предоставить демо-сервер — как и в случае с RuStore.


Второй отказ я получил потому, что модератор вместо https://demo.lissenapp.org пытался подключиться к ...listenapp.org/, который, конечно же, был недоступен.


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


Я был настойчив в своём желании добиться от Google принятия моего приложения, потому что понимал, что при всех его проблемах Google Play — это для многих единственный способ получить приложение на своём телефоне. Забегая вперёд, на сегодняшний день этот канал принёс мне почти 2000 установок и более 800 активных устройств.



Локализация


Согласно той же статистике от Google Play, Lissen был популярен прежде всего в США, Британии, Австралии и Канаде. Это англоговорящие страны, поэтому меня устраивало наличие локализации приложения только на русский и английский, а планов поддерживать другие языки не было.


Такие планы нашлись зато у моих пользователей. В середине декабря пользователь с ником thehijacker завёл мне на гитхаб issue с просьбой позволить ему добавить в приложение поддержку его родного словенского языка.


Так Lissen обзавёлся собственной страничкой Weblate, интегрированной с git-проектом, и, спустя пару дней, получил локализацию на словенский язык:



Эта идея многим пришлась по душе: спустя несколько месяцев приложение поддерживает уже 11 языков, включая такую экзотику как тамильский и китайский.



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


Редизайн


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


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


Релизный цикл был короток, и у меня часто не хватало времени продумать, как очередная фича будет выглядеть в контексте всего приложения. Часто я вообще брал первое UI/UX-решение, казавшееся мне разумным, и в итоге Lissen начал терять ту чистоту интерфейса, ради которой создавался.


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


Например, вот так изменилась страница настроек приложения



Это решило сразу две проблемы:


Во-первых, у пользователя появилось право ожидать от одинаковых элементов одинакового поведения.


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


Это не стало полноценной дизайн-системой, но всё же в мерж-реквестах с исправлениями от контрибьюторов я стал замечать, что UI-компоненты переиспользовались правильно, как будто сами собой, без моих замечаний на ревью.


Идентификация личности


Я создал свой аккаунт разработчика Google Play для того, чтобы опубликовать там свою курсовую в 2016 году. После этого, он большую часть времени не использовался, а все новые политики Google каким-то образом обходили меня стороной.


Из-за этого я ожидал проблем с работой приложения в Google Play, и рано или поздно они должны были проявиться.


В конце декабря 2024 года Google прислал мне письмо с просьбой подтвердить личность как разработчика, угрожая в случае отказа удалить мои приложения и заблокировать учётку.


Я попробовал прислать им фотографии моего паспорта и сканы банковских выписок, в каждой из которых были указаны одни и те же имя и адрес.


По разным причинам Google раз за разом отвергал эти документы, и спустя неделю попыток я решил, что с меня хватит, и улетел отмечать новогодние праздники в Сеул.


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


В случае, если и в этот раз мои документы были бы отвергнуты по любой причине, я собирался прикрутить к приложению простенькую модалку, где объяснил бы ситуацию и просил бы пользователей переустановить приложение из F-Droid, чтобы получать свежие обновления. Это сократило бы охват, но всё равно выглядело бы лучше, чем просто пропавшее без особых причин приложение из Google Play без указаний, где его теперь искать.


К счастью, очередная банковская выписка попала на стол к модератору в нужный момент, и этот план не пригодился. Но я до сих пор держу его в голове на случай новых проблем.



Донаты


Я не планировал монетизировать приложение, о чём много раз писал и на гитхабе, и на Reddit. Тем не менее, отказываться от добровольных пожертвований не стал и после третьей по счёту просьбы добавил такую возможность.


Поскольку основная аудитория Lissen на тот момент состояла из американцев, британцев и канадцев, я зарегистрировал аккаунт на Stripe и завёл страничку на ko-fi, добавив ссылку на неё на страничку с настройками приложения.


За всё время существования этой странички я получил 20 пожертвований на разные суммы — и этого хватило, чтобы на несколько лет окупить работу демо-сервера, необходимого для модерации приложения в RuStore и Google Play.



Я не собираюсь зарабатывать на Lissen, но тонкий ручеёк донатов каждый раз поднимает мою мотивацию уделять время этому проекту. Донаты — это скорее источник дофамина, чем способ заработка, так что я рад любым пожертвованиям, но никогда не буду на них настаивать.


Lissen сегодня


К 30 марта 2025 года Lissen превратился из попытки наскоро заменить официальный клиент Audiobookshelf в полноценное самостоятельное приложение, локализованное на 10 языков и с более чем тысячей пользователей.


Приложение доступно для скачивания в крупных сторах, а на страничке клиентов для Audiobookshelf есть упоминание Lissen.


Я очень рад, что могу выпускать и поддерживать полезное приложение, и ещё больше рад, что потратил это время не зря. За полгода существования приложения я переслушал достаточно книг и подкастов, чтобы считать затею успешной.


Про свободное ПО


Lissen — не первый мой опенсорсный сайд-проект, и, наблюдая за тем, как он и все остальные мои приложения, телеграм-боты и сайты в интернете развиваются, живут и умирают, я могу собрать несколько общих черт для каждого из них:


— Для опенсорса очень важно комьюнити, и многое зависит от первого впечатления. С Lissen мне повезло сразу найти лояльное и дружелюбное сообщество, что дало мне возможность довести приложение до пригодного к использованию состояния. Другие проекты, которым повезло меньше, как правило, умирали, так и не получив приличной известности.


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


— Бесплатное ПО требует такой же, если не большей, чем коммерческая разработка, вовлечённости в работу. По сути своей, решение “не брать денег за продукт” принадлежит авторам, но не даёт никаких скидок от ожиданий пользователя.


— Большие корпорации, которые чинят проблемы маленьким инди-проектам, редко делают это со зла или от умысла. Большая часть неприятных ситуаций происходит из-за огромного размера компаний типа Google или Amazon и неумения их работать с не-корпоратами. С этим нужно просто смириться и чаще трогать траву.


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


Разумеется, Lissen — это опенсорсный продукт, который останется бесплатным и свободным для всех, кто желает им пользоваться. Я благодарен авторам локализаций, модераторам Weblate и пользователям, которые донатят, присылают мерж-реквесты с правками, предлагают клёвые идеи и участвуют в их обсуждении.


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