- manifest share_target (POST multipart: title/text/url + audio/video files) and eight shortcuts (Search, Queue, Saved, Downloads, History, Library, Notes, Settings). /?view=<page> now actually opens that page — the old shortcuts pointed at it but nothing read it. - sw.js receives the share: files are parked in the ytp-share-inbox cache (not a versioned shell cache, so deploys never evict it) and the app is opened; links/text go to /?shared=. A server POST /share-target fallback covers the first visit before a worker is in control (links only). - The app plays a YouTube link found anywhere in the shared text (watch, youtu.be, shorts, live, embed, music; keeps t=), otherwise searches the text. /?shared=<link> also works from an iOS Shortcut (iOS has no share target). - Shared files upload with progress to PUT /api/uploads/shared and join a "Shared uploads" playlist; network failures stay in the inbox for the next open, refusals are dropped with the reason. - The public route is bounded: audio/video only (ffprobe-validated, error text without server paths), 500 MB per file, 2 GB and 20 a day per device, 50 GB for all shared uploads, one at a time per device (all env-tunable). Shared uploads are unlisted: reachable by id, never in anyone else's search. uploads gains owner + listed columns (idempotent ALTER).
167 lines
3.5 KiB
JSON
167 lines
3.5 KiB
JSON
{
|
|
"name": "YT Player",
|
|
"short_name": "YTPlayer",
|
|
"description": "Ad-free YouTube player — search, play, and keep playlists offline. No login, no tracking.",
|
|
"display": "standalone",
|
|
"orientation": "any",
|
|
"start_url": "/",
|
|
"scope": "/",
|
|
"theme_color": "#1a1311",
|
|
"background_color": "#1a1311",
|
|
"categories": [
|
|
"music",
|
|
"entertainment"
|
|
],
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png",
|
|
"purpose": "any maskable"
|
|
},
|
|
{
|
|
"src": "/icons/icon-512.png",
|
|
"sizes": "512x512",
|
|
"type": "image/png",
|
|
"purpose": "any maskable"
|
|
}
|
|
],
|
|
"screenshots": [],
|
|
"shortcuts": [
|
|
{
|
|
"name": "Search",
|
|
"short_name": "Search",
|
|
"url": "/?view=search",
|
|
"description": "Search YouTube",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Queue",
|
|
"short_name": "Queue",
|
|
"url": "/?view=queue",
|
|
"description": "What plays next",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Saved",
|
|
"short_name": "Saved",
|
|
"url": "/?view=saved",
|
|
"description": "Videos saved for offline",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Downloads",
|
|
"short_name": "Downloads",
|
|
"url": "/?view=downloads",
|
|
"description": "Saves in progress and paused",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "History",
|
|
"short_name": "History",
|
|
"url": "/?view=history",
|
|
"description": "Recently watched videos",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Library",
|
|
"short_name": "Library",
|
|
"url": "/?view=library",
|
|
"description": "Your playlists",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Lyrics & notes",
|
|
"short_name": "Notes",
|
|
"url": "/?view=notes",
|
|
"description": "Lyrics, chapters and notes",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"name": "Settings",
|
|
"short_name": "Settings",
|
|
"url": "/?view=settings",
|
|
"description": "App settings",
|
|
"icons": [
|
|
{
|
|
"src": "/icons/icon-192.png",
|
|
"sizes": "192x192",
|
|
"type": "image/png"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"share_target": {
|
|
"action": "/share-target",
|
|
"method": "POST",
|
|
"enctype": "multipart/form-data",
|
|
"params": {
|
|
"title": "title",
|
|
"text": "text",
|
|
"url": "url",
|
|
"files": [
|
|
{
|
|
"name": "media",
|
|
"accept": [
|
|
"audio/*",
|
|
"video/*",
|
|
".mp3",
|
|
".m4a",
|
|
".aac",
|
|
".wav",
|
|
".flac",
|
|
".ogg",
|
|
".opus",
|
|
".mp4",
|
|
".mov",
|
|
".webm",
|
|
".mkv"
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|