Собрался я однажды написать приложение, чтобы отбирать музыку для себя и слушать дома/на улице/тренировках и.т.д. И чтобы все это работало в потоке, с минимальным моим участием. Придумал архитектуру, набросал прототип и в итоге столкнулся с одной “небольшой проблемой”.
А непонятно откуда брать сами файлы песен. К этому моменту вконтакте уже закрыла api, на крупных музыкальных порталах тоже все глухо, даже песни отдаются кусками, чтобы не парсили. Оставались только какие-то отдельные сайты-однодневки с тонной рекламы и всякого мусора, всякие сомнительные программы-грабберы и прочие “грязные” варианты. В общем, ни одного действительного хорошего решения. Можно, конечно, купить подписку на какую-нибудь яндекс музыку или подобное. Но опять же, там нигде нет открытого публичного api и у тебя нет доступа к музыке программно. Несколько крупных компаний, по сути, ограничили остальным доступ к музыке. Почему так произошло вообще? Копнув глубже, стало понятно, что основная проблема в авторских правах. Текущее решение в виде подписок устраивает многих коммерческих авторов музыкальных произведений и эти самые компании. При этом некоммерческая и условно-коммерческая музыка тоже попадают в общий список. Ты либо платишь за все, либо не слушаешь вообще ничего.
И я начал думать что с этим всем делать. Как можно организовать свободное распространение музыки? Что бы я делал, если бы сам занимался созданием музыки и хотел бы зарабатывать на этом? Понравилось бы мне, если бы мои песни начали распространять пиратским образом? Какое вообще есть альтернативное решение?
В итоге сложились две основные проблемы, которые нужно решать:
- Организация свободного распространения музыки удобными для большинства людей методами, в том числе программными.
- Предложение альтернатив создателям музыки для заработка
Глобальное децентрализованное хранилище музыки
Изначально я попробовал найти уже существующие решения и создать все на базе этого. После некоторого времени поисков, первым приглянулся ipfs. Я начал реализацию своей идеи, но через некоторое время обнаружил несколько критичных проблем в этом решении:
- Ipfs — хранилище для всего и вся. Тут и изображения и музыка и видео и все что угодно. В общем-то большая такая планетарная «помойка». Поэтому когда ты запускаешь свой узел, то сразу получаешь огромную нагрузку. Машина просто корчится от боли.
- Какой-то недоделанный механизм сборки «мусора». Не знаю как с этим сейчас, но в тот момент, если ты в конфиге прописывал, что хочешь ограничить хранилище десятью гигабайтами данных, то это не значило ничего. Хранилище разрасталось, игнорируя многие параметры конфигурации. В итоге, нужно было иметь огромный запас жесткого диска, пока ipfs сообразит как сбросить ненужное.
- На момент использования библиотеки (не знаю как с этим сейчас), у клиента не были реализованы таймауты. Посылаешь запрос на получение файла, и если его нет, то просто висишь. Конечно, люди придумали всякие обходные пути, которые отчасти решали проблему, но это было костыли. Такие вещи должны быть из коробки.
Еще было много мелких проблем, впечатление сложилось тогда однозначное: это нельзя использовать для проекта. Я продолжил поиски хранилища, изучал разные варианты, но так и не нашел ничего подходящего.
В итоге, решил, что стоит попробовать написать децентрализованное хранилище самому. Пускай оно не будет претендовать на роль межпланетного, но будет решать конкретно поставленную задачу.
Так и получились spreadable, storacle, metastocle, museria, museria-global.
spreadable — это основной, самый нижний слой, который позволяет объединять узлы в сеть. В нем заложен алгоритм, который я пока реализовал частично из расчета где-то на 10000 серверов. Полная версия алгоритма намного сложнее в реализации и потребовала бы еще несколько дополнительных месяцев (может и больше).
Подробно я spreadable в этой статье не буду описывать, лучше напишу отдельную как-нибудь. Тут лишь отмечу некоторые особенности:
- Работает через http/https.
- Можно создавать отдельную сеть под конкретную задачу, что существенно снизит нагрузку на каждый отдельный проект, чем если бы они все были в одной сети.
- Изначально продуман механизм с таймаутами и другими мелочами. И это работает для всех методов и в клиенте и в узле. Можно гибко управлять параметрами из своего приложения.
- Библиотека написана на nodejs. Проблемы с производительностью стека компенсируются децентрализованной природой. Нагрузку можно «размазать», увеличением количества узлов. Взамен много плюсов: огромное сообщество, простота и удобство работы, изоморфный клиент, отсутствие внешних зависимостей и.т.д.
storacle — это слой, наследующийся от spreadable, который позволяет хранить в сети файлы. Каждый файл имеет свой хэш по содержимому, по которому его позже и можно получить. Файлы не делятся на блоки, а хранятся целиком.
metastocle — слой, наследующийся от spreadable, который позволяет хранить в сети данные, но не файлы. Интерфейс похож на nosql базы данных. Можно, например, добавить файл в storacle, получить его хэш и записать в metastocle с привязкой к чему-либо.
museria — наследуется от storacle и metastocle. Этот слой непосредственно отвечает за хранение музыки. Хранилище работает только с mp3 файлами и id3 тэгами.
В качестве «ключа» к песне используется ее полное название в виде Исполнитель (TPE1) — Название (TIT2). Например:
- Brimstone — The Burden
- Hi-rez — Lost My Way (feat. Emilio Rojas, Dani Devinci)
Максимально подробно узнать как формируются названия песен можно тут. Надо смотреть функцию utils.beautifySongTitle().
Совпадением по ключам считается определенный в настройках узла процент. Например, значение 0.85 означает, что если функция сравнения ключей(названий песен) обнаружила схожесть более 85%, то это одна и та же песня.
Алгоритм определения схожести там же, в функции utils.getSongSimilarity().
Cover к песне, для последующего получения, также прикрепляться через тэги (APIC). В утилитах(utils) есть все необходимые методы для получения и обработки тэгов.
Пример работы с хранилищем через клиент можно посмотреть в readme.
Все вышеперечисленные слои являются самодостаточными и могут быть использованы отдельно как более низкие слои для других проектов. Например, уже сейчас есть мысль сделать слой для хранения книг.
museria-global — это уже сконфигурированный гит-репозиторий для запуска собственного узла в глобальной сети музыки. Клонируете, npm i && npm start и по сути все. Можно настроить более детально, запустить в докере и.т.д. Подробная информация есть в на гитхабе.
Когда репозиторий обновляется, нужно обновить и свой узел. Если меняется мажорный или минорный номер версии, то это действие обязательно, иначе старые узлы будут игнорироваться сетью.
Работать с песнями можно вручную и программно. Каждый узел запускает сервер для различных задач. В том числе, при посещении дефолтного эндпоинта, вы получите интерфейс для работы с музыкой. Например, можно зайти на корневой узел (ссылка может быть не актуальна позже, входные узлы можно получить также в телеграмме, либо посмотреть обновления на гитхабе).
Так вы можете искать и загружать песни в хранилище. Загрузка песен может проходить в двух режимах: обычный и модерируемый. Второй режим означает, что работу ведет человек, а не программа. И если вы ставите эту галочку при добавлении, то нужно будет решить капчу. Песни можно добавлять с приоритетами -1, 0 или 1. Приоритет 1 можно ставить только в модерируемом режиме. Приоритеты нужны, чтобы хранилище эффективнее принимало решение, что делать когда вы пытаетесь заменить уже существующую песню новой. Чем больше приоритет, тем больше шансов, что вы перезапишете существующий файл. Это помогает бороться со спамом и увеличивает качество загружаемых песен.
Если вы начнете добавлять песни в хранилище, старайтесь прикреплять и изображения (cover), хоть это поле и не обязательное. В 99% случаев первые же картинки в гугле по названиям песен это каверы альбомов.
Как технически происходит добавление файлов, в двух словах:
- Клиент получает адрес свободного узла, который на некоторое время станет координатором.
- Триггерится функция добавления песни (человеком или кодом), происходит запрос на добавление на эндпоинт координатора.
- Координатор вычисляет, сколько дубликатов нужно сохранить (конфигурируемый параметр).
- Ищутся наиболее подходящие узлы для сохранения.
- Файл, непосредственно, уходит на эти узлы.
Как технически происходит получение файлов:
- Клиент получает адрес свободного узла, который на некоторое время станет координатором.
- Триггерится функция получения песни (человеком или кодом), происходит запрос на получение на эндпоинт координатора.
- Координатор проверяет наличие ссылки в кэше. Если такая есть и она рабочая, то сразу возвращается клиенту, иначе опрашиваются узлы на предмет наличия.
- Происходит получение файла по ссылке, если таковая нашлась.
Альтернативы для создателей музыки
Меня всегда интересовал вопрос, как вообще можно оценить объективно стоимость многих творческих произведений? Почему, например, человек выставляет свой музыкальной альбом за 10$? Или за 20$ или за 100$. Где алгоритм? Когда, например, мы говорим о каком-то физическом продукте, или даже многих видах услуг, то мы можем как минимум посчитать себестоимость и исходить из этого.
Окей, допустим 10$ поставили. Очень уж ли это эффективно? Допустим я послушал альбом где-нибудь или песню оттуда и решил отблагодарить. Но по моим ощущениям и собственным возможностям 3$ — мой потолок. И как тут быть? Скорее всего я просто не сделаю ничего, как и большинство людей.
Выставляя какую-то фиксированную цену за творческий труд, ты просто ограничиваешь себя, не даешь бОльшому числу людей отправить тебе меньшие деньги, которые в сумме могут быть внушительнее, чем у тех кто купят по установленной тобой цене. Мне кажется творчество — это именно та сфера, где в первую очередь должны рулить донаты. Для этого нужно:
- Научить людей благодарить именно таким образом. Творцы сами должны это четко показывать, что хотели бы получать донаты, добавлять везде ссылки на разные способы оплаты и.т.д.
- Нужно больше механизмов для упрощения и усиления этих процессов. Например, создать некий глобальный сайт, куда можно донатить за творчество с помощью авторских ссылок.
Допустим, ссылка примерно такая:
http://someartistsdonationsite.site/category/artist?external-info
Если сузить до музыкантов, то:
http://someartistsdonationsite.com/music/miyagi?song=blabla
Исполнителю нужно верифицировать свой никнейм и прикрепиться за ним.
В клиент museria добавляем функцию генерации подобной ссылки, и все проекты использующие хранилище, могут расположить на своих сайты/приложениях кнопки для донатов с этими ссылками рядом с песнями. Пользователи имеют возможность очень быстро и просто сделать донат. Естественно, этот подход можно использовать в любом проекте и категории творчества, не только через хранилище.
Зачем, именно тебе, музыкальное хранилище, и как в этом можно участвовать
- Если ты работаешь над проектом, связанным с музыкой, либо планируешь такой создать, то ради этого все и было задумано. Ты можешь использовать museria для хранения и получения песен, увеличивая поток песен в сети. Если, при этом, у тебя есть возможности поднять и удерживать хотя бы один собственный узел, то это будет наилучшим вкладом в развитие сети.
- Возможно ты готов взять какую-то иную роль на себя: помочь с кодом, или заполнять и модерировать базу, распространять информацию о проекте своим знакомым и.т.д.
- Может быть тебе понравилась идея и ты готов помочь материально, чтобы это все жило и развивалось. Чем больше узлов, тем больше песен.
- Или тебе просто в какой-то момент понадобится найти и скачать песню. Ты сможешь сделать это очень просто, например, через телеграмм бота.
Проект сейчас на самой начальной стадии. Запущена тестовая сеть, узлы могут часто перезагружаться, требовать обновлений и.т.д. В случаи отсутствия критических проблем в течение оценочного периода, эта же сеть и трансформируется в основную.
Посмотреть информацию об узле извне: количество песен, свободного места и.т.д., можно по ссылке вида
http://node-address/status
или http://node-address/status?pretty
Мои контакты:
victoriously
Bandcamp?
IsOrtex Автор
Не совсем. Нужен лишь сайт для верификации творчеких псевдонимов и принятия донатов через генерируемые ссылки.