🛠️ Moonlight Developer Docs
Integruj nasze odtwarzacze muzyczne z własną stroną
🚀 Quick Start Guide
1. Podstawowa integracja
Dodaj nasze pliki do swojej strony i stwórz odtwarzacz w kilku linijkach:
<!-- Dodaj style CSS -->
<link rel="stylesheet" href="https://howtodraw.pl/css/moonlight-music-player-light.css">
<!-- Kontener dla playera -->
<div id="music-player"></div>
<!-- Dodaj skrypt -->
<script src="https://howtodraw.pl/js/MoonlightMusicPlayerLight.js"></script>
<script>
// Utwórz odtwarzacz
const player = new MoonlightMusicPlayerLight('#music-player', {
height: 120,
showDownload: true,
showShare: true
});
// Załaduj utwór
player.loadTrack({
id: 123,
title: "Nazwa utworu",
artist: "Nazwa artysty",
audioUrl: "https://howtodraw.pl/api/music/tracks/123/stream",
waveform: [0.2, 0.5, 0.8, 0.3, 0.7, ...], // opcjonalne
moonlightUrl: "https://howtodraw.pl/music/tracks/123" // link powrotu
});
</script>
✅ Gotowe! Twoja strona ma teraz pełnofunkcjonalny odtwarzacz muzyczny z Moonlight.
🎵 Moonlight Music Player Light
🎬 Live Demo
⚙️ Opcje konfiguracji
| Opcja | Typ | Domyślna | Opis |
|---|---|---|---|
| height | number | 120 | Wysokość playera w pikselach |
| showDownload | boolean | true | Pokazuj przycisk pobierania |
| showShare | boolean | true | Pokazuj przycisk udostępniania |
| showVolumeControl | boolean | true | Pokazuj kontrolę głośności |
| compactMode | boolean | false | Tryb kompaktowy dla małych przestrzeni |
| autoPlay | boolean | false | Automatyczne odtwaranie po załadowaniu |
📋 Format danych utworu
const trackData = {
id: 123, // ID utworu (wymagane)
title: "Nazwa utworu", // Tytuł (wymagane)
artist: "Nazwa artysty", // Artysta (wymagane)
audioUrl: "https://...", // URL do pliku audio (wymagane)
// Opcjonalne:
waveform: [0.2, 0.5, ...], // Dane waveform (array liczb 0-1)
duration: 180, // Długość w sekundach
coverUrl: "https://...", // URL okładki
moonlightUrl: "https://...", // Link do strony na Moonlight
genre: "Electronic", // Gatunek muzyczny
description: "Opis..." // Opis utworu
};
🔗 System Embedowania
🌍 Cross-Origin Setup
Nasz system embedowania działa z dowolnych domen dzięki prawidłowej konfiguracji CORS:
✅ Dozwolone:
- • Wszystkie domeny i subdomeny
- • HTTP i HTTPS
- • Localhost (development)
- • IP addresses
- • Publiczne treści - bez ograniczeń
- • Prywatne treści - z kluczem dostępu
🔧 Nagłówki CORS:
Access-Control-Allow-Methods: GET
Access-Control-Allow-Headers: *
💡 Tip: Player automatycznie dodaje przycisk "🌙 Visit on Moonlight" który przekierowuje na oryginalną stronę utworu na naszej platformie.
🔒 System Uprawnień Embedowania
- • Publiczne - każdy może embedować bez klucza
- • Prywatne - wymagany klucz dostępu od autora
- • Wyłączone - embedowanie niemożliwe
- • Klucze dostępu są 32-znakowe i widoczne tylko dla autorów
📖 Czytnik komiksu na Twojej stronie
Komiks można czytać bezpośrednio u Ciebie — jeden tag <script>
i element, w którym czytnik się osadzi. Widget dokłada własne style, więc nie ma czego
dołączać poza tym jednym plikiem. Ramki (iframe)
nie użyjesz — Moonlight wysyła frame-ancestors 'self',
więc czytnik działa przez JS i CORS.
<div id="moonlight-comic-1"></div>
<script src="https://howtodraw.pl/js/MoonlightComicReaderLight.js"></script>
<script>
new MoonlightComicReaderLight('#moonlight-comic-1', {
comicId: 1,
baseUrl: 'https://howtodraw.pl',
mode: 'auto', // 'auto' | 'webtoon' | 'classic'
height: 720,
theme: 'dark', // 'dark' | 'light'
lang: 'pl', // 'pl' | 'en'
embedKey: '' // tylko dla osadzenia prywatnego
});
</script>
✅ Co robi czytnik:
- • Lista rozdziałów z oznaczeniem płatnych
- • Tryb przewijany (webtoon) i stronicowany
- • Sterowanie strzałkami w trybie stronicowanym
- • Leniwe wczytywanie stron
- • Podgląd i przejście do zakupu przy płatnym rozdziale
- • Zapamiętanie zakupu po powrocie na Twoją stronę
⚠️ Warto wiedzieć:
- • Autor musi mieć włączone osadzanie w ustawieniach komiksu
- • Widoczne są rozdziały opublikowane i publiczne
- • Strony z animowaną sceną otwierają się na Moonlight
- • Odsłony z embedu liczą się do statystyk autora
🎯 Generator Kodu Embed
🔌 API Endpoints
GET Pobierz dane utworu
Zwraca wszystkie dane potrzebne do załadowania utworu w playerze.
{
"track": {
"id": 123,
"title": "Nazwa utworu",
"artist": "Nazwa artysty",
"audioUrl": "https://howtodraw.pl/storage/music/track-123.mp3",
"waveform": [0.2, 0.5, 0.8, ...],
"duration": 180,
"coverUrl": "https://howtodraw.pl/storage/covers/123.jpg",
"moonlightUrl": "https://howtodraw.pl/music/tracks/123"
}
}
GET Stream audio
Bezpośredni stream pliku audio z odpowiednimi nagłówkami CORS.
✅ Automatycznie obsługiwane: Range requests, cache headers, CORS, content-type detection
GET Pobierz dane komiksu
Zwraca dane opisowe opublikowanego komiksu: tytuł, autora, opis, okładkę, liczbę
rozdziałów i link powrotny na Moonlight. Prywatne osadzenie wymaga parametru
?key=... z kluczem z ustawień komiksu.
{
"comic": {
"id": 1,
"title": "Tytuł komiksu",
"author": "Autor",
"description": "Opis...",
"coverUrl": "https://howtodraw.pl/storage/comics/1/cover/cover.jpg",
"moonlightUrl": "https://howtodraw.pl/comics/1",
"chapterCount": 12,
"status": "ongoing",
"readingMode": "webtoon"
}
}
ℹ️ Zakres: ten endpoint podaje same metadane. Strony rozdziału serwują dwa endpointy niżej, z których korzysta czytnik do osadzenia. Gotowy kod znajdziesz w ustawieniach swojego komiksu, w sekcji „Osadzanie na innych stronach”.
GET Lista rozdziałów komiksu
Rozdziały opublikowane i publiczne. Rozdziały płatne oraz w oknie przedpremiery też
są na liście — z opisem blokady w polu lock
(reason: paid
lub premium) — ale ich stron ten endpoint nie
wydaje. Parametr ?lang= zawęża do jednej wersji
językowej, ?key= otwiera osadzenie prywatne.
GET Strony rozdziału
Dostęp rozstrzyga ta sama bramka, przez którą przechodzi czytnik na Moonlight, więc osadzony czytelnik nigdy nie zobaczy więcej niż czytelnik na naszej stronie. Rozdział zablokowany zwraca podgląd pierwszych stron oraz adres zakupu.
{
"chapter": { "id": 42, "number": 7, "title": "...", "pageCount": 18, "readingMode": "webtoon" },
"access": {
"granted": false,
"previewPages": 3,
"lock": { "locked": true, "reason": "paid", "coinPrice": 50 },
"purchaseUrl": "https://howtodraw.pl/embed/purchase/comic_chapter/42?return_to=..."
},
"pages": [ { "number": 1, "type": "image", "url": "https://.../page-1.jpg" } ]
}
🔑 Po zakupie: czytelnik wraca na Twoją stronę z parametrem
moonlight_token. Dołącz go jako
?token= do żądania stron, a rozdział
otworzy się już bez blokady. Token jest podpisany, dotyczy jednego rozdziału
i jest ważny 30 dni. Nasz czytnik
robi to za Ciebie.
📖 Przykłady użycia
🌐 WordPress Plugin
// functions.php
function moonlight_music_player_shortcode($atts) {
$atts = shortcode_atts([
'track_id' => '',
'height' => '120'
], $atts);
return '
<div id="moonlight-' . $atts['track_id'] . '"></div>
<script>
new MoonlightMusicPlayerLight("#moonlight-' . $atts['track_id'] . '", {
height: ' . $atts['height'] . '
}).loadTrackById(' . $atts['track_id'] . ');
</script>';
}
add_shortcode('moonlight_music', 'moonlight_music_player_shortcode');
Użycie: [moonlight_music track_id="123" height="120"]
⚛️ React Component
import { useEffect, useRef } from 'react';
function MoonlightPlayer({ trackId, height = 120 }) {
const playerRef = useRef();
useEffect(() => {
const player = new MoonlightMusicPlayerLight(
playerRef.current,
{ height }
);
player.loadTrackById(trackId);
return () => player.destroy();
}, [trackId]);
return <div ref={playerRef} />;
}
📚 Książki i Komiksy z Płatnościami
💰 System Płatności dla Embedded Content
Moonlight obsługuje premium rozdziały które wymagają zapłaty w wewnętrznej walucie (Moondust 🌙). Stworzyliśmy dedykowany flow dla embedded content z automatycznym powrotem na Twoją stronę.
🎯 Jak to działa:
- User klika premium rozdział na Twojej stronie
- Przekierowanie na Moonlight z context preservation
- Automatyczny flow: login → kup Moondust → odblokuj
- Powrót na Twoją stronę z access tokenem
💎 System Monet:
- • 10 Moondust = 1 PLN
- • Płatności przez Stripe
- • Automatyczne odliczanie z balansu
- • Jednorazowa płatność = dozgonny dostęp
⚡ Streamlined User Experience
Nasz system zachowuje kontekst przez cały proces płatności. User nie gubi się w przekierowaniach i automatycznie wraca na Twoją stronę po zakończeniu transakcji.
🔗 Embedding Premium Content
📖 Rozdział Książki
<!-- Link do premium rozdziału -->
<a href="https://howtodraw.pl/embed/purchase/book_chapter/123?return_to=https%3A%2F%2Ftwoja-strona.pl%2Fksiazka%2Frozdzia%C5%82-5&embed_key=optional_private_key"
class="premium-chapter-link">
🔐 Przeczytaj Rozdział 5 (Premium)
</a>
<!-- Lub jako button -->
<button onclick="window.location.href='https://howtodraw.pl/embed/purchase/book_chapter/123?return_to=...'">
Odblokuj za 50 Moondust
</button>
🎨 Rozdział Komiksu
<!-- Link do premium rozdziału komiksu -->
<a href="https://howtodraw.pl/embed/purchase/comic_chapter/456?return_to=https%3A%2F%2Ftwoja-strona.pl%2Fkomiks%2Frozdzia%C5%82-10"
class="premium-chapter-link">
🔐 Przeczytaj Rozdział 10 (Premium)
</a>
🔄 Obsługa Powrotu
// JavaScript - obsługa powrotu po zakupie
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('access_granted') === '1') {
const chapterId = urlParams.get('chapter_id');
const moonlightToken = urlParams.get('moonlight_token');
// User pomyślnie odblokował rozdział
showChapterContent(chapterId);
// Opcjonalnie: zapisz token dla przyszłych requestów
localStorage.setItem(`chapter_${chapterId}_token`, moonlightToken);
}
🛡️ Prawa do treści, którą osadzasz
Każda praca certyfikowana na Moonlight niesie swoje warunki użycia w samym pliku — w metadanych i w numerze wplecionym w piksele. Dzięki temu deklaracja jedzie razem z obrazem, także wtedy, gdy plik trafi do Ciebie z drugiej ręki. Poniżej trzy pytania, które zadaje integracja, i punkty końcowe, które na nie odpowiadają.
1. Czy ta praca ma certyfikat?
Punkt publiczny, bez klucza. Numer bierzesz z metadanych pliku albo z odczytanego znaku wodnego.
GET https://howtodraw.pl/api/v1/certificates/CERT-2026-XXXXXX
GET https://howtodraw.pl/api/v1/certificates/by-watermark/{numer}
2. Na jakich warunkach wolno jej użyć?
Warunki wracają w postaci nadającej się do maszynowego sprawdzenia — łącznie z tym, czy autor zgadza się na trenowanie modeli na swojej pracy.
GET https://howtodraw.pl/api/v1/certificates/CERT-2026-XXXXXX/license
3. Czy plik, który mam, to naprawdę TA praca?
Numer wskazuje kandydata, nie dowodzi tożsamości pliku. Potwierdzenie należy do porównania samej treści — wysyłasz obraz, dostajesz odpowiedź.
POST https://howtodraw.pl/api/v1/certificates/verify
Content-Type: multipart/form-data
file=@praca.png
Zasada, która oszczędzi Ci błędu: nigdy nie blokuj ani nie przepuszczaj treści na podstawie samego odczytanego numeru. Odczyt bywa przekłamany, a wyszukiwanie z tolerancją zwraca wielu kandydatów. Numer zawęża pole, treść rozstrzyga.
Pełna specyfikacja standardu
Opis warstw ochrony, pola metadanych, przestrzeń nazw XMP, liczby odporności i wzorce integracji dla firm — w czternastu językach.
Potrzebujesz pomocy? 🤝
Nasz zespół pomoże Ci z integracją i odpowie na wszystkie pytania