iArt.ai
AI 모션 그래픽 소프트웨어, 누구나 사용할 수 있는 After Effects 대안, 텍스트 프롬프트로 몇 분 안에 애니메이션·설명 영상 제작
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기Burn down YouTube subscription feed in chronological order.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A purely client-side, single-page web app that turns your YouTube subscription feed into a chronological queue that plays in succession.README 전문 보기 ↗Live app: https://branets-dasha.github.io/youtube-queue-app/
A purely client-side, single-page web app that turns your YouTube subscription feed into a chronological queue that plays in succession.
Features:
Built by Claude. This app was designed and built end to end by Claude (Anthropic's Claude Code, Opus) — from the initial architecture through every feature, refactor, and bug fix — working at its owner's direction. The whole codebase is Claude's work.
Anyone can use this app hosted at https://branets-dasha.github.io/youtube-queue-app/ or host it wherever they please.
No backend. No framework. No build step. No bundler. Plain HTML, CSS, and ES modules.
The only external network resources are:
https://accounts.google.com/gsi/client).https://www.googleapis.com/youtube/v3), for loading subscriptions and enabling "like" button.https://www.youtube.com/iframe_api), for the on-page player.To use the app you need to provide your own Google OAuth Client ID (see below). Your OAuth access token lives in memory only — it is never written to localStorage or IndexedDB. There is no client secret and no API key anywhere; the OAuth token authorizes every call.
The OAuth scope is https://www.googleapis.com/auth/youtube.force-ssl ("see, edit, and permanently delete your YouTube videos, ratings, comments and captions"). Such a permissive scope is needed to enable the "like" button. All the other operations the app does using YouTube Data API are read-only.
The app runs entirely in your browser. It fetches your data using the YouTube Data API. The API needs to know which app (client) is contacting it — to count request quotas and other things. I personally use a test Client ID that does not have the capacity to support many users, so each user brings their own Client ID from their own free Google Cloud project. The setup is a bit complicated, but you only need to do it once.
https://www.googleapis.com/auth/youtube.force-ssl — it covers reading your subscriptions/uploads and liking videos from the player.Application type: Web application.
Under Authorized JavaScript origins, add exactly:
https://branets-dasha.github.io
You do not need to set an Authorized redirect URI for the token model.
1234567890-abcdefg.apps.googleusercontent.com).The embedded video player is a cross-origin YouTube iframe — it's a window into youtube.com from the app page. If tracking prevention is enabled (in modern browsers it's often on by default), the browser will not send cookies belonging to youtube.com to that iframe. It means that the player will not recognize your YouTube login, and will run signed-out, showing ads even if you have YouTube Premium.
Disable tracking prevention for the app's page to connect the player to your YouTube account. This step is optional — playback works without it. It only affects account-connected / Premium (ad-free) playback. Note that connecting the player does not make your watches count toward a video's public view count — see Limitations. To connect the player, allow YouTube's third-party cookies for the app:
https://branets-dasha.github.io — via the site-info / shield icon in the address bar, or Settings → Privacy, search, and services → Tracking prevention → Exceptions. Alternatively, allow-list [*.]youtube.com under cookies.[*.]youtube.com.This is separate from signing into the app. Signing in with Google OAuth only authorizes the Data API (your subscriptions, marking, likes) — it does not sign the player in. Whether the player recognizes your account and Premium depends entirely on whether your browser lets the youtube.com iframe use its cookies as a third party.
Each YouTube Data API call spends quota units associated with your Client. The default daily quota is 10,000 units. If you hit it you'll see a friendly "daily quota reached" message; it resets at midnight Pacific time.
The app is deliberately quota-frugal. It uses the following methods:
subscriptions.list — gets a list of subscribed channels. 1 unit per page (page size is 50 results max).playlistItems.list — gets channel videos. 1 unit per page, requested per channel, paging stops once it reaches the cutoff point (for "Refresh all") or the point of the last saved video + 6h buffer (for "Fetch new"). Upload playlist ids are derived cheaply by replacing the leading UC of a channel id with UU (no extra call); the rare non-UC channel costs one additional channels.list request. Adding a playlist to the stash pages through it too (1 unit per 50 videos), plus one playlists.list for its title.videos.list?part=contentDetails,status,snippet — backfills video durations, descriptions and embeddability, and on "Refresh all" confirms that a video its channel's listing no longer returned is really gone before deleting it. Batched ≤ 50 ids per call, 1 unit each.videos.rate (the Like button) — roughly 50 units per like/unlike.localStorage:
yqa_client_id — your OAuth Client ID.yqa_start_cutoff — the floor (deletion/fetch boundary).yqa_cutoff — the live handled-prefix cutoff marker.yqa_channels — channel id → { title, avatarUrl } map for avatars.yqa_channel_prefs — channel id → { ignored?, speed? } from the Channels page (absent when nothing is set).yqa_playback_speed — the current player speed.yqa_default_speed — the "Default speed" setting (absent when off).yqa_hide_marked — the "Hide skipped" toggle.yqa, keyed by videoId, in two object stores — videos and stash. IndexedDB is required — if it can't be opened the app stops with an error.To reset, use Change Client ID / Change cutoff in the toolbar, or clear the site's storage in your browser dev tools.
isShort flag, so the "Shorts" badge can be wrong for edge cases.\ to put focus inside the frame on purpose: YouTube's own keys then work at once (c toggles captions), and Tab reaches its settings menu — caption language, audio track, quality. Shift+Tab brings you back from any of its controls; straight after \, press Tab once first (Tab forward is a long walk through the related-videos drawer). The app's shortcuts are off while you're inside.There is no build step — it's static HTML, CSS, and ES modules — but OAuth via Google Identity Services will not work if you open index.html directly as a file:// URL. You must serve the folder over http://localhost.
Pick one (run from inside this project directory):
# Python 3
python -m http.server 5173
# or Node
npx serve -l 5173
# or
npx http-server -p 5173
Then open:
http://localhost:5173
For local development, register your localhost origin instead of the hosted one: in your OAuth client's Authorized JavaScript origins, add http://localhost:5173 (or whichever port you serve on — localhost is a valid OAuth origin). Make sure the port matches. You can register both the localhost origin and the https://branets-dasha.github.io origin on the same Client ID.
| File | Purpose |
|---|---|
index.html | DOM skeleton + loads GIS, the IFrame API (via player.js), and js/subscriptions-page.js |
stash.html | DOM skeleton for the stash page; loads GIS, the IFrame API (via player.js), and js/stash-page.js |
channels.html | Standalone channel-list page (per-channel prefs); loads js/channels-page.js |
styles.css | Light/dark, responsive two-pane styling; player container query |
README.md | This file |
js/config.js | Constants (API base, OAuth scope, storage keys, IndexedDB names, limits) |
js/store.js | Persistence: IndexedDB video CRUD + localStorage for id/cutoff/settings/channels |
js/migrations.js | All data migrations, in one place (records, channel prefs, localStorage keys) |
js/migrations.test.mjs | Node unit tests for js/migrations.js (run: node js/migrations.test.mjs) |
js/auth.js | GIS token client: init, request/refresh/revoke, in-memory token |
js/api.js | YouTube fetch: subscriptions, uploads, videos.list details, videos.rate; errors |
js/queue.js | PURE queue logic (no browser globals; Node-importable & unit-testable) |
js/queue.test.mjs | Node unit tests for js/queue.js (run: node js/queue.test.mjs) |
js/player.js | YouTube IFrame Player API wrapper (load/play, speed, seek, resume, fullscreen) |
js/ui.js | XSS-safe DOM building (cards, player meta) and state screens |
js/toast.js | Top-right toast notifications (progress / success / error / info) |
js/page-chrome.js | Chrome shared by every page: tab lock, fatal-storage screens, curtain, iframe focus guard |
js/subscriptions-page.js | Wiring: auth → fetch → store → queue → ui/player, event binding, shortcuts |
js/stash-page.js | Stash page wiring: add by link, store → queue → ui/player, event binding, shortcuts |
js/queue.js references no browser globals, so it is imported directly by the test file. Run the suite from the repo root:
node js/queue.test.mjs
node js/migrations.test.mjs
js/channels-page.js | Channels page wiring: channel rows + ignore/speed prefs (no auth, no API) |