youtube-video-downloader

byAbdullahi Momoh

Build a simple YouTube video downloader with this API https://reelixstreaming.onrender.com just like this curl curl -X GET 'https://reelixstreaming.onrender.com/youtube/streams?videoId=RLFxBQ8hOhI' -H 'Content-Type: application/json' -H 'x-api-key: hfy7jCdmtiLqXFcn18zdYU01vhKtaZ1xDG1QLAdx5mU2SMuINkzZMJqR9MD2p460' -d '{ "keyword": "Once upon a village" }', with these endpoints | Route | Notes | |-------|-------| | `GET /youtube/trending?page=&perPage=&filter=` | Home feed; `filter` is `now`, `music`, `gaming`, `movies`, `sports`, `news`, `shorts`, `live` | | `GET /youtube/search?keyword=&type=&page=&perPage=` | Same envelope as `GET /search` (`keyword`, `tabId`, `subjects`, `results`, `tabs`) | | `POST /youtube/search` | Same, explicit body | | `GET /youtube/search/suggest?query=` | Autocomplete | | `GET /youtube/details?videoId=` / `GET /youtube/videos/:videoId` | Same envelope as `GET /subjects/:id` (`subjectId`, `subject`). `videoId`/`id`/`url` all accepted | | `GET /youtube/random?query=&filter=` | Random video as subject detail | | `GET /youtube/trailer?videoId=` / `GET /youtube/videos/:videoId/trailer` | Attached trailer, else `"{title} official trailer"` search | | `GET /youtube/streams?videoId=&quality=&client=` / `GET /youtube/videos/:videoId/streams` | Direct download URLs from RapidAPI. Omit `quality` for every height (`streams.qualities`, `streams.url` is the best muxed MP4). Pass `quality=720p` (or a watch url) to return only that height | | `GET /youtube/videos/:videoId/play` | Alias of streams | | `GET /youtube/videos/:videoId/captions` | Caption tracks | | `GET /youtube/videos/:videoId/comments` | Comments | | `GET /youtube/videos/:videoId/transcript` | Transcript | | `GET /youtube/videos/:videoId/recommendations` | Related videos as a trending-shaped page | | `GET /youtube/playlists/:playlistId` | Playlist items | | `GET /youtube/channels/:channelId` | Channel | | `GET /youtube/hashtag/:tag` | Hashtag feed | | `GET /youtube/resolve?url=` | Resolve a watch/share URL |

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

Page 1 of 21

System Requirements Document for youtube-video-downloader

1. Introduction

Product intent. youtube-video-downloader is a simple, focused web utility that turns a YouTube link or keyword into a working video file. It is a thin, decisive instrument built on top of the Reelix Streaming API at https://reelixstreaming.onrender.com: the user browses a trending home feed or searches YouTube, opens a video's details, and retrieves the direct download stream URLs for that video — the best muxed MP4 or a specific height such as 720p — without leaving the app.

Audience. Media-savvy people, students, archivists, creators and commuters who want a fast, no-nonsense tool for pulling YouTube video and audio files down to a device. The product should feel like a sharp, confident product rather than a sketchy download site: one query, one result, one download.

Scope posture. The app is deliberately simple and focused on YouTube video downloading. All YouTube data and stream/download URL retrieval is owned by the external Reelix Streaming API; the app owns the browsing, selection, and download-retrieval experience.

Page 2 of 21

2. System Overview

youtube-video-downloader is a single-role, anonymous-access web application. The one active human actor — the Viewer / Downloader — uses the app to browse trending content, search YouTube, inspect a video's details, and obtain direct download stream URLs.

Current delivery. A custom first-party web UI (React) that calls the Reelix Streaming API for every YouTube operation. The app never scrapes YouTube itself and never stores video files; it surfaces the direct download URLs the API returns from RapidAPI.

Actors.

  • Viewer / Downloader (active human persona) — browses, searches, inspects, and downloads.
  • Reelix Streaming API (external provider actor) — owns all YouTube data retrieval and stream/download URL resolution.
  • RapidAPI (external provider actor) — the upstream source of the direct download stream URLs, reached through the Reelix Streaming API.

Accepted behavior. Trending home feed with eight filters; keyword search with tabs, type selection, pagination, and autocomplete; video details with trailer, captions, comments, transcript, and recommendations; focused stream retrieval with quality selection; playlist, channel, and hashtag browsing; and watch/share URL resolution.

Narrow exclusions. No accounts, no authentication, no server-side persistence of user data, no video hosting or re-encoding, no playlist creation or editing, no commenting or uploading, and no capabilities beyond the documented Reelix Streaming API endpoints.

Page 3 of 21

2a. Product Interpretation and Delivery Boundary

Delivery ownership. The product is delivered as a first-party custom web UI. The UI is the product's own surface; every YouTube fact it displays — trending items, search results, video details, captions, comments, transcripts, recommendations, playlist items, channel content, hashtag feeds, and download stream URLs — is fetched from the external Reelix Streaming API. The app does not own YouTube data; it owns the experience of finding and downloading.

Access ownership. All seven pages are anonymously reachable. The product has no accounts, no sign-in, and no per-user state. This is a deliberate consequence of the product's simplicity constraint: the app's job is to take one query and return one decisive result, and nothing in the accepted behavior requires durable per-user continuity. No identity establishment, verification, or account-management capability is part of this product.

Current vs. future. Everything described in this document is current. No future-horizon requirements were accepted.

Provider boundary. The Reelix Streaming API is authoritative for all YouTube data and for the direct download URLs it returns from RapidAPI. The app must not attempt to resolve streams itself, must not substitute another provider, and must not present download URLs as its own.

2b. Source Content Inventory

The reference directive for https://reelixstreaming.onrender.com declares uses: ["feature_reference", "domain_context"] and does not declare content_source. No content-source inventory is therefore included. The verified source observations confirm the URL could not be retrieved directly, so no factual entities, collections, or media references are asserted from it beyond the endpoint contract supplied by the user.

Page 4 of 21

2c. Page Content and Component Coverage

Landing

  • Information / state. Full-viewport black first screen. Dominant element: a single line of Anton uppercase display type — "PASTE A LINK. TAKE THE FILE." — set at clamp(56px, 11vw, 128px), flush left, occupying columns 1–10 and running off the right edge at desktop. To the right of the headline, a vertical stack of three metadata lines in muted #8A857C at 13px uppercase tracked: "4K · 1080p · 720p", "MP4 · WEBM · MP3", "NO ADS · NO QUEUE". Beneath the headline, a single full-width input band (#161616, 1px #2A2A2A rule) with a solid #FF3B1F "FETCH" rectangle pinned to its right end. Below the fold: a numbered filter rail (01 NOW / 02 MUSIC / 03 GAMING / 04 MOVIES / 05 SPORTS / 06 NEWS / 07 SHORTS / 08 LIVE) with the active number in #FF3B1F, and a full-bleed horizontal band of trending thumbnails.
  • Primary actions. Paste a YouTube URL or type a keyword into the input band and press FETCH; select a numbered filter to switch the trending feed; select a trending thumbnail to open its Video Details.
  • Supporting actions. Scroll the trending band; hover a thumbnail to restore its colour.
  • Domain entities. Trending feed page (page, perPage, filter), trending item (thumbnail, title, channel, duration, view count), filter value (now, music, gaming, movies, sports, news, shorts, live).
  • Component responsibilities. HeroHeadline renders the clipped-up Anton display line. FetchBand owns the URL/keyword input and the FETCH action, routing a URL to resolve and a keyword to Search. FilterRail renders the eight numbered filters and owns the active-filter state. TrendingBand renders the full-bleed marquee of trending thumbnails and pauses on hover. Thumbnail renders grayscale at rest and full colour on hover or selection.
  • States. Loading: the trending band shows a ruled placeholder band at the same height, no spinner. Empty: if the trending feed returns no items for the active filter, the band is replaced by a single ruled line reading "NOTHING IN THIS FILTER" in muted type. Success: the band scrolls continuously at 40s per loop; filter switches crossfade the feed in 180ms with no layout bounce. Error: if the trending request fails, the band is replaced by a ruled line reading "FEED UNAVAILABLE" with a rectangular RETRY control that re-issues the same request. Recovery: RETRY re-issues the request with the same page, perPage, and filter; the filter rail remains interactive throughout.

Search

  • Information / state. A search field at the top, an autocomplete suggestion list beneath it while typing, a tab row from the response tabs envelope, a result list of subjects/results, and pagination controls. Each result row is a full-bleed horizontal band: thumbnail left, title in Archivo 600, channel and metadata in muted #8A857C at 13px uppercase tracked.
  • Primary actions. Enter a keyword and submit; select a suggestion from autocomplete; select a tab; select a result to open its Video Details; paginate forward and back.
  • Supporting actions. Change the type selection; clear the keyword.
  • Domain entities. Search envelope (keyword, tabId, subjects, results, tabs), suggestion (query), result item, tab, page.
  • Component responsibilities. SearchField owns the keyword input and submits GET /youtube/search or POST /youtube/search. SuggestList calls GET /youtube/search/suggest?query= and renders suggestions. TabRow renders the response tabs and owns the active tabId. ResultBand renders each result as a full-bleed band. Pager owns page and perPage.
  • States. Loading: result bands render as ruled placeholders at the same height. Empty: a ruled line reading "NO RESULTS FOR <keyword>" in muted type. Success: result bands render with grayscale thumbnails; the active tab is underlined in #FF3B1F. Error: a ruled line reading "SEARCH FAILED" with a rectangular RETRY control that re-issues the same keyword, tab, and page. Recovery: RETRY preserves the keyword and tab; the search field remains editable.

Video Details

  • Information / state. The resolved video identity from the subjectId/subject envelope: title in Anton or Archivo 600, channel, duration, view count, and description. A trailer region, a caption-track list, a comment list, a transcript region, and a recommendations band shaped like the trending feed. A prominent entry point to Download.
  • Primary actions. Open Download for this video; play or open the trailer; select a caption track; read comments; read the transcript; select a recommendation to open its Video Details.
  • Supporting actions. Expand or collapse the transcript; paginate comments.
  • Domain entities. Subject detail (subjectId, subject), trailer, caption track, comment, transcript, recommendation item.
  • Component responsibilities. SubjectHeader renders the resolved identity. TrailerBlock calls GET /youtube/trailer?videoId= or GET /youtube/videos/:videoId/trailer and falls back to a "{title} official trailer" search. CaptionList calls GET /youtube/videos/:videoId/captions. CommentList calls GET /youtube/videos/:videoId/comments. TranscriptBlock calls GET /youtube/videos/:videoId/transcript. RecommendationBand calls GET /youtube/videos/:videoId/recommendations and renders a trending-shaped page. DownloadEntry routes to Download.
  • States. Loading: the header renders first; each subordinate region shows its own ruled placeholder. Empty: each region that returns nothing renders a ruled line in muted type — "NO CAPTIONS", "NO COMMENTS", "NO TRANSCRIPT", "NO RECOMMENDATIONS" — without collapsing the page. Success: all regions render; the trailer falls back to the title-based search when no attached trailer exists. Error: a failed region shows a ruled line with a rectangular RETRY control scoped to that region only; a failed identity resolution shows "VIDEO NOT FOUND" with a control back to Landing. Recovery: region-scoped RETRY re-issues only that region's request; the Download entry remains available whenever the identity resolved.
Page 5 of 21

Download

  • Information / state. A full-bleed horizontal band, not a card: thumbnail left, title in Archivo 600, then a ruled table of quality rows (for example 1080p / 720p / 480p / MP3), each with its own file size and a rectangular DOWNLOAD button. A flat 2px #FF3B1F progress bar with a tabular numeral counting percentage beside it.
  • Primary actions. Retrieve streams for the video; select a quality row; start a download from a row; use the best muxed MP4 when no quality is chosen.
  • Supporting actions. Re-retrieve streams; cancel an in-progress download.
  • Domain entities. Stream response (streams.qualities, streams.url), quality height, file size, download progress percentage.
  • Component responsibilities. StreamFetcher calls GET /youtube/streams?videoId=&quality=&client= or GET /youtube/videos/:videoId/streams; omitting quality returns every height, and passing quality=720p (or a watch url) returns only that height. QualityTable renders the ruled rows. DownloadButton is a solid #FF3B1F block with #0B0B0B text that fills solid on hover. ProgressBar renders the flat 2px #FF3B1F bar with the tabular numeral.
  • States. Loading: the quality table renders as ruled rows at the same height; no spinner. Empty: if the stream response contains no qualities, a ruled line reading "NO STREAMS AVAILABLE" in muted type. Success: quality rows render with file sizes; the best muxed MP4 is marked as the default row; starting a download fills the progress bar left-to-right with the numeral counting in tabular figures. Error: a failed stream retrieval shows a ruled line reading "STREAMS UNAVAILABLE" with a rectangular RETRY control; a failed download shows the row's DOWNLOAD button restored with a ruled error line. Recovery: RETRY re-issues the stream request for the same videoId; a failed download can be restarted from the same row.

Playlist

  • Information / state. The playlist's items as returned by GET /youtube/playlists/:playlistId, rendered as full-bleed horizontal bands with grayscale thumbnails, titles in Archivo 600, and metadata in muted #8A857C.
  • Primary actions. Select an item to open its Video Details; paginate the item list.
  • Supporting actions. Return to the referring page.
  • Domain entities. Playlist id, playlist item (thumbnail, title, channel, duration).
  • Component responsibilities. PlaylistHeader renders the playlist identity. PlaylistItemBand renders each item. Pager owns pagination.
  • States. Loading: item bands render as ruled placeholders. Empty: a ruled line reading "EMPTY PLAYLIST" in muted type. Success: item bands render with grayscale thumbnails. Error: a ruled line reading "PLAYLIST UNAVAILABLE" with a rectangular RETRY control. Recovery: RETRY re-issues the same playlist request.

Channel

  • Information / state. The channel's content as returned by GET /youtube/channels/:channelId: channel identity (name, avatar rendered circular at 28px and grayscale until hover) and the channel's videos as full-bleed bands.
  • Primary actions. Select a video to open its Video Details; paginate the channel's content.
  • Supporting actions. Return to the referring page.
  • Domain entities. Channel id, channel identity, channel video item.
  • Component responsibilities. ChannelHeader renders the channel identity. ChannelVideoBand renders each video. Pager owns pagination.
  • States. Loading: the header renders first; video bands render as ruled placeholders. Empty: a ruled line reading "NO VIDEOS ON THIS CHANNEL" in muted type. Success: video bands render with grayscale thumbnails. Error: a ruled line reading "CHANNEL UNAVAILABLE" with a rectangular RETRY control. Recovery: RETRY re-issues the same channel request.
Page 6 of 21

Hashtag

  • Information / state. The hashtag feed as returned by GET /youtube/hashtag/:tag, rendered as full-bleed horizontal bands with grayscale thumbnails, titles in Archivo 600, and metadata in muted #8A857C.
  • Primary actions. Select an item to open its Video Details; paginate the feed.
  • Supporting actions. Return to the referring page.
  • Domain entities. Hashtag tag, hashtag feed item.
  • Component responsibilities. HashtagHeader renders the tag. HashtagItemBand renders each item. Pager owns pagination.
  • States. Loading: item bands render as ruled placeholders. Empty: a ruled line reading "NOTHING FOR #<tag>" in muted type. Success: item bands render with grayscale thumbnails. Error: a ruled line reading "HASHTAG UNAVAILABLE" with a rectangular RETRY control. Recovery: RETRY re-issues the same hashtag request.
Page 7 of 21

3. Functional Requirements

FR-01 — Trending home feed. As a Viewer / Downloader I should see a trending home feed so that I can find something to download without searching.

  • Provenance: explicit.
  • Trigger/input: opening Landing, or selecting a numbered filter.
  • Observable result: the trending band renders items from GET /youtube/trending?page=&perPage=&filter=, where filter is one of now, music, gaming, movies, sports, news, shorts, live.
  • Access state: anonymous.
  • Failure/recovery: on failure, a ruled "FEED UNAVAILABLE" line with a RETRY control re-issues the same request.
  • Continuation: selecting an item opens its Video Details.

FR-02 — Filtered trending. As a Viewer / Downloader I should switch the trending feed between the eight filters so that I can browse a category I care about.

  • Provenance: explicit.
  • Trigger/input: selecting one of 01 NOW / 02 MUSIC / 03 GAMING / 04 MOVIES / 05 SPORTS / 06 NEWS / 07 SHORTS / 08 LIVE.
  • Observable result: the feed crossfades in 180ms with no layout bounce; the active number is set in #FF3B1F.
  • Access state: anonymous.
  • Failure/recovery: a failed filter request leaves the previous feed visible with a ruled error line and RETRY.
  • Continuation: the user continues browsing or selects an item.

FR-03 — Keyword search. As a Viewer / Downloader I should search YouTube by keyword so that I can find a specific video.

  • Provenance: explicit.
  • Trigger/input: submitting a keyword via GET /youtube/search?keyword=&type=&page=&perPage= or POST /youtube/search.
  • Observable result: the response envelope (keyword, tabId, subjects, results, tabs) renders as a tab row and result bands.
  • Access state: anonymous.
  • Failure/recovery: a ruled "SEARCH FAILED" line with RETRY re-issues the same keyword, tab, and page.
  • Continuation: selecting a result opens its Video Details.

FR-04 — Search tabs and type. As a Viewer / Downloader I should switch result tabs and the type selection so that I can narrow results.

  • Provenance: explicit.
  • Trigger/input: selecting a tab from the response tabs, or changing type.
  • Observable result: results re-render for the selected tab; the active tab is underlined in #FF3B1F.
  • Access state: anonymous.
  • Failure/recovery: a failed tab request keeps the previous results visible with a ruled error line and RETRY.
  • Continuation: the user continues browsing results.

FR-05 — Search pagination. As a Viewer / Downloader I should page through search results so that I can reach results beyond the first page.

  • Provenance: explicit.
  • Trigger/input: paginating with page and perPage.
  • Observable result: the next or previous page of results renders.
  • Access state: anonymous.
  • Failure/recovery: a failed page request keeps the current page visible with a ruled error line and RETRY.
  • Continuation: the user continues paging or selects a result.

FR-06 — Search autocomplete. As a Viewer / Downloader I should see autocomplete suggestions while typing so that I can search faster.

  • Provenance: explicit.
  • Trigger/input: typing into the search field, which calls GET /youtube/search/suggest?query=.
  • Observable result: a suggestion list renders beneath the field.
  • Access state: anonymous.
  • Failure/recovery: a failed suggestion request silently hides the list; the field remains usable.
  • Continuation: selecting a suggestion submits that query.

FR-07 — Video details. As a Viewer / Downloader I should open a video's details so that I can confirm it is the right video before downloading.

  • Provenance: explicit.
  • Trigger/input: selecting a video, or supplying videoId, id, or url to GET /youtube/details?videoId= or GET /youtube/videos/:videoId.
  • Observable result: the subjectId/subject envelope renders as the video identity.
  • Access state: anonymous.
  • Failure/recovery: a failed resolution shows "VIDEO NOT FOUND" with a control back to Landing.
  • Continuation: the user opens Download or explores the video's subordinate regions.

FR-08 — Random video. As a Viewer / Downloader I should be able to get a random video as subject detail so that I can discover something unexpected.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/random?query=&filter=.
  • Observable result: a random video renders as subject detail on Video Details.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows a ruled error line with RETRY.
  • Continuation: the user opens Download or explores the video's subordinate regions.

FR-09 — Trailer. As a Viewer / Downloader I should see a video's trailer so that I can preview it.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/trailer?videoId= or GET /youtube/videos/:videoId/trailer.
  • Observable result: the attached trailer renders; when no attached trailer exists, the API falls back to a "{title} official trailer" search and that result renders.
  • Access state: anonymous.
  • Failure/recovery: a failed trailer request shows a ruled "NO TRAILER" line without collapsing the page.
  • Continuation: the user continues to Download or another region.

FR-10 — Download streams. As a Viewer / Downloader I should retrieve direct download stream URLs so that I can download the video.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/streams?videoId=&quality=&client= or GET /youtube/videos/:videoId/streams, or the alias GET /youtube/videos/:videoId/play.
  • Observable result: omitting quality returns every height (streams.qualities, with streams.url the best muxed MP4); passing quality=720p (or a watch url) returns only that height. The direct download URLs are sourced from RapidAPI through the provided API.
  • Access state: anonymous.
  • Failure/recovery: a failed retrieval shows "STREAMS UNAVAILABLE" with RETRY re-issuing the same videoId.
  • Continuation: the user selects a quality row and starts a download.

FR-11 — Quality selection. As a Viewer / Downloader I should choose a specific quality so that I can control the file I get.

  • Provenance: explicit.
  • Trigger/input: selecting a quality row, or passing quality=720p (or a watch url) to the streams endpoint.
  • Observable result: only that height is returned and rendered as the selected row.
  • Access state: anonymous.
  • Failure/recovery: a failed quality request keeps the full quality table visible with a ruled error line and RETRY.
  • Continuation: the user starts the download.

FR-12 — Best muxed MP4 default. As a Viewer / Downloader I should be able to use the best muxed MP4 without choosing a quality so that downloading is one step.

  • Provenance: explicit.
  • Trigger/input: retrieving streams with quality omitted.
  • Observable result: streams.url is presented as the default row and is downloadable directly.
  • Access state: anonymous.
  • Failure/recovery: a failed retrieval shows "STREAMS UNAVAILABLE" with RETRY.
  • Continuation: the user starts the download.

FR-13 — Download progress. As a Viewer / Downloader I should see download progress as a number so that I know the download's state.

  • Provenance: explicit (creative direction).
  • Trigger/input: starting a download from a quality row.
  • Observable result: a flat 2px #FF3B1F progress bar fills left-to-right with a tabular numeral counting percentage beside it.
  • Access state: anonymous.
  • Failure/recovery: a failed download restores the row's DOWNLOAD button with a ruled error line; the download can be restarted from the same row.
  • Continuation: on completion the user can start another download or return to browsing.

FR-14 — Captions. As a Viewer / Downloader I should see a video's caption tracks so that I can inspect available subtitles.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/videos/:videoId/captions.
  • Observable result: the caption-track list renders on Video Details.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows a ruled "NO CAPTIONS" line without collapsing the page.
  • Continuation: the user continues to Download or another region.

FR-15 — Comments. As a Viewer / Downloader I should read a video's comments so that I can gauge the video.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/videos/:videoId/comments.
  • Observable result: the comment list renders on Video Details.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows a ruled "NO COMMENTS" line without collapsing the page.
  • Continuation: the user continues to Download or another region.

FR-16 — Transcript. As a Viewer / Downloader I should read a video's transcript so that I can scan its content.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/videos/:videoId/transcript.
  • Observable result: the transcript renders on Video Details and can be expanded or collapsed.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows a ruled "NO TRANSCRIPT" line without collapsing the page.
  • Continuation: the user continues to Download or another region.

FR-17 — Recommendations. As a Viewer / Downloader I should see related videos so that I can find more to download.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/videos/:videoId/recommendations.
  • Observable result: related videos render as a trending-shaped page on Video Details.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows a ruled "NO RECOMMENDATIONS" line without collapsing the page.
  • Continuation: selecting a recommendation opens its Video Details.

FR-18 — Playlist browsing. As a Viewer / Downloader I should browse a playlist's items so that I can download from it.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/playlists/:playlistId.
  • Observable result: the playlist's items render as full-bleed bands on Playlist.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows "PLAYLIST UNAVAILABLE" with RETRY.
  • Continuation: selecting an item opens its Video Details.

FR-19 — Channel browsing. As a Viewer / Downloader I should browse a channel's content so that I can download from it.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/channels/:channelId.
  • Observable result: the channel identity and its videos render on Channel.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows "CHANNEL UNAVAILABLE" with RETRY.
  • Continuation: selecting a video opens its Video Details.

FR-20 — Hashtag feed. As a Viewer / Downloader I should browse a hashtag feed so that I can find videos by tag.

  • Provenance: explicit.
  • Trigger/input: GET /youtube/hashtag/:tag.
  • Observable result: the hashtag feed renders as full-bleed bands on Hashtag.
  • Access state: anonymous.
  • Failure/recovery: a failed request shows "HASHTAG UNAVAILABLE" with RETRY.
  • Continuation: selecting an item opens its Video Details.

FR-21 — Resolve a watch/share URL. As a Viewer / Downloader I should paste a YouTube watch or share URL so that I can go straight to that video.

  • Provenance: explicit.
  • Trigger/input: pasting a URL into the Landing fetch band, which calls GET /youtube/resolve?url=.
  • Observable result: the resolved video opens on Video Details.
  • Access state: anonymous.
  • Failure/recovery: an unresolvable URL shows a ruled error line in the fetch band and leaves the input editable.
  • Continuation: the user opens Download for the resolved video.

FR-22 — API base and headers. As a Viewer / Downloader I should have every request reach the Reelix Streaming API correctly so that the app works.

  • Provenance: required_inference.
  • Trigger/input: any API call.
  • Observable result: the app calls https://reelixstreaming.onrender.com and includes the header x-api-key: hfy7jCdmtiLqXFcn18zdYU01vhKtaZ1xDG1QLAdx5mU2SMuINkzZMJqR9MD2p460 and Content-Type: application/json on every request.
  • Access state: anonymous.
  • Failure/recovery: a request rejected for a missing or invalid header surfaces the same ruled error line and RETRY as the owning region.
  • Continuation: the owning region's normal continuation.

FR-23 — RapidAPI stream sourcing. As a Viewer / Downloader I should receive download URLs that actually resolve so that my download works.

  • Provenance: required_inference.
  • Trigger/input: any stream retrieval.
  • Observable result: the direct download URLs presented are those sourced from RapidAPI through the provided API.
  • Access state: anonymous.
  • Failure/recovery: a stream response with no usable URL shows "NO STREAMS AVAILABLE".
  • Continuation: the user selects another quality row or retries.
Page 8 of 21

4. User Personas

Page 9 of 21

Viewer / Downloader

Product context. The Viewer / Downloader is the single active human role in youtube-video-downloader. They arrive with a specific intent — a video they want on their device — or with idle curiosity and a willingness to browse. They are media-savvy: they know what a muxed MP4 is, they know the difference between 1080p and 720p, and they have used download tools before. They are not looking for a media library, a subscription, or a social experience. They want the file.

Primary goal. Locate a YouTube video and obtain a working download link or stream URL without leaving the app.

Distinct accepted responsibilities.

  • Browsing the trending home feed and switching between the eight filters (now, music, gaming, movies, sports, news, shorts, live).
  • Searching YouTube by keyword, using autocomplete, switching result tabs, changing the type selection, and paging through results.
  • Opening a video's details and inspecting its trailer, caption tracks, comments, transcript, and recommendations.
  • Retrieving direct download stream URLs, choosing a specific quality such as 720p, or accepting the best muxed MP4.
  • Starting a download and reading its progress as a number.
  • Browsing a playlist, a channel, or a hashtag feed to find videos.
  • Pasting a YouTube watch or share URL to resolve it directly.

Relevant inputs and decisions. The keyword or pasted URL; the filter choice; the tab and type choice; the page; the quality row; whether to accept the best muxed MP4 or pick a height; whether to start a download now or keep browsing.

Interactions with other accepted participants. The Viewer / Downloader interacts only with the app's own UI. The Reelix Streaming API and RapidAPI are provider actors the app calls on the user's behalf; the user never interacts with them directly and never supplies the API key themselves.

Observable success. A working download link or stream URL for the video they wanted, obtained without leaving the app — the file lands on their device, or the direct URL is available to hand to a download manager.

What makes this role's work distinct. There is exactly one role, and its work is a single decisive arc: query, result, download. It is not an administrative role, not a content-creation role, and not a multi-participant role. The interface must serve that arc without ceremony.

Page 10 of 21

5. Core User Flows

Flow A — Browse trending and download the best muxed MP4

  1. The Viewer / Downloader opens Landing anonymously. The hero headline reveals by clipping upward from a baseline mask in 400ms.
  2. The trending band renders items from GET /youtube/trending?page=&perPage=&filter= for the default filter. Thumbnails render grayscale at rest.
  3. The user selects a numbered filter, for example 03 GAMING. The feed crossfades in 180ms with no layout bounce; the active number is set in #FF3B1F.
  4. The user hovers a thumbnail; it snaps to full colour. They select it.
  5. Video Details opens with the resolved subjectId/subject identity. The trailer, captions, comments, transcript, and recommendations regions each load independently.
  6. The user selects the Download entry.
  7. Download retrieves streams with quality omitted. The ruled quality table renders every height, and the best muxed MP4 (streams.url) is marked as the default row.
  8. The user selects the default row's DOWNLOAD button. The flat 2px #FF3B1F progress bar fills left-to-right with a tabular numeral counting percentage.
  9. Result: the file downloads to the device. Continuation: the user can start another download from the same table or return to Landing.

Failure/recovery: if step 7 fails, "STREAMS UNAVAILABLE" renders with a RETRY control that re-issues the same videoId. If step 8 fails, the row's DOWNLOAD button is restored with a ruled error line and the download can be restarted from the same row.

Page 11 of 21

Flow B — Search by keyword and download a chosen quality

  1. The Viewer / Downloader opens Landing anonymously and types a keyword into the fetch band.
  2. As they type, GET /youtube/search/suggest?query= returns suggestions rendered beneath the field. They may select one.
  3. They submit. Search calls GET /youtube/search?keyword=&type=&page=&perPage= (or POST /youtube/search) and renders the envelope's tabs as a tab row and its subjects/results as full-bleed bands.
  4. The user switches to a different tab and changes the type selection. Results re-render; the active tab is underlined in #FF3B1F.
  5. The user pages forward with page and perPage to reach a result beyond the first page.
  6. They select a result. Video Details opens with the resolved identity.
  7. They select the Download entry. Download retrieves streams with quality omitted and renders the full quality table.
  8. The user selects the 720p row. The app re-requests streams with quality=720p, and only that height is returned and rendered as the selected row.
  9. The user starts the download. The progress bar fills with the tabular numeral counting percentage.
  10. Result: the 720p file downloads to the device. Continuation: the user can pick another quality or return to Search.

Failure/recovery: if step 3 fails, "SEARCH FAILED" renders with RETRY preserving the keyword and tab. If step 8 fails, the full quality table stays visible with a ruled error line and RETRY.

Flow C — Paste a watch or share URL and resolve it

  1. The Viewer / Downloader opens Landing anonymously with a YouTube watch or share URL in hand.
  2. They paste the URL into the fetch band and press FETCH.
  3. The app calls GET /youtube/resolve?url=.
  4. Video Details opens with the resolved video's subjectId/subject identity.
  5. The user selects the Download entry and retrieves streams.
  6. Result: the resolved video's download URLs are available. Continuation: the user downloads or explores the video's regions.

Failure/recovery: if step 3 fails, a ruled error line renders in the fetch band and the input remains editable so the user can correct the URL.

Page 12 of 21

Flow D — Inspect a video's details before downloading

  1. The Viewer / Downloader opens Video Details from Landing, Search, Playlist, Channel, Hashtag, or a recommendation.
  2. The subjectId/subject identity renders first: title, channel, duration, view count, description.
  3. The trailer region calls GET /youtube/trailer?videoId= or GET /youtube/videos/:videoId/trailer. If no attached trailer exists, the API falls back to a "{title} official trailer" search and that result renders.
  4. The caption-track list calls GET /youtube/videos/:videoId/captions.
  5. The comment list calls GET /youtube/videos/:videoId/comments.
  6. The transcript calls GET /youtube/videos/:videoId/transcript and can be expanded or collapsed.
  7. The recommendations band calls GET /youtube/videos/:videoId/recommendations and renders a trending-shaped page.
  8. Result: the user has confirmed the video and seen its supporting material. Continuation: they select the Download entry, or select a recommendation to open its Video Details.

Failure/recovery: each region fails independently — "NO CAPTIONS", "NO COMMENTS", "NO TRANSCRIPT", "NO RECOMMENDATIONS" — with a region-scoped RETRY, and the page never collapses. If the identity itself fails to resolve, "VIDEO NOT FOUND" renders with a control back to Landing.

Flow E — Discover a random video

  1. The Viewer / Downloader, browsing without a specific target, triggers GET /youtube/random?query=&filter=.
  2. A random video renders as subject detail on Video Details.
  3. The user inspects the identity and its regions.
  4. Result: an unexpected video is presented. Continuation: the user opens Download or returns to browsing.

Failure/recovery: a failed request shows a ruled error line with RETRY.

Page 13 of 21

Flow F — Browse a playlist and download from it

  1. The Viewer / Downloader opens Playlist anonymously.
  2. GET /youtube/playlists/:playlistId returns the playlist's items, rendered as full-bleed bands with grayscale thumbnails.
  3. The user pages through the items.
  4. They select an item. Video Details opens.
  5. They select the Download entry and retrieve streams on Download.
  6. Result: the chosen item's download URLs are available. Continuation: the user downloads or returns to Playlist.

Failure/recovery: if step 2 fails, "PLAYLIST UNAVAILABLE" renders with RETRY re-issuing the same playlist request. If the playlist is empty, "EMPTY PLAYLIST" renders in muted type.

Flow G — Browse a channel and download from it

  1. The Viewer / Downloader opens Channel anonymously.
  2. GET /youtube/channels/:channelId returns the channel identity and its videos. The channel avatar renders circular at 28px, grayscale until hover.
  3. The user pages through the channel's content.
  4. They select a video. Video Details opens.
  5. They select the Download entry and retrieve streams on Download.
  6. Result: the chosen video's download URLs are available. Continuation: the user downloads or returns to Channel.

Failure/recovery: if step 2 fails, "CHANNEL UNAVAILABLE" renders with RETRY. If the channel has no videos, "NO VIDEOS ON THIS CHANNEL" renders in muted type.

Page 14 of 21

Flow H — Browse a hashtag feed and download from it

  1. The Viewer / Downloader opens Hashtag anonymously.
  2. GET /youtube/hashtag/:tag returns the hashtag feed, rendered as full-bleed bands with grayscale thumbnails.
  3. The user pages through the feed.
  4. They select an item. Video Details opens.
  5. They select the Download entry and retrieve streams on Download.
  6. Result: the chosen item's download URLs are available. Continuation: the user downloads or returns to Hashtag.

Failure/recovery: if step 2 fails, "HASHTAG UNAVAILABLE" renders with RETRY. If the feed is empty, "NOTHING FOR #<tag>" renders in muted type.

Page 15 of 21

6. Visuals Colors and Theme

Muse and headline. Tobias van Schneider — editorial minimalism with swagger. The headline gesture is a single line of enormous condensed uppercase type that names the action: "PASTE A LINK. TAKE THE FILE."

Mode. Dark mode only.

Colour tokens by role.

RoleHexUsage
Background#0B0B0BDominant ground, ~70% of the page
Surface#161616Raised panels only: search field, stream rows, modal
Hairline#2A2A2A1px rules separating surfaces from the ground
Text#F4F1EAAll display type and primary actions — the system's "ink"
Primary#F4F1EAPrimary text and non-accent actions
Accent#FF3B1FPrimary Download action, active filter number and tab underline, progress bar, focus ring — never a decorative fill
Muted#8A857CMetadata (duration, view count, file size) at small sizes

No blue, no indigo, no violet, no gradients of any kind. Colour is used in flat blocks only.

Typography.

RoleFamilyWeightSizeNotes
Display / headingsAnton400clamp(56px, 11vw, 128px) hero; clamp(40px, 5vw, 72px) sectionUppercase, tracking -0.01em, leading 0.86
Subheads / labelsArchivo60012–14pxUppercase, 0.18em letterspacing
BodyArchivo400/50016px mobile / 18px desktopLine-height 1.5, measure capped at 62ch
NumbersArchivo600—Tabular numerals for file sizes, durations, view counts, percentages

Type scale (1.5 modular): 128 / 88 / 56 / 40 / 28 / 20 / 16 / 13. Mobile hero 56px, tablet 88px, desktop 128px. Labels 13px uppercase tracked.

Shape language. Sharp corners everywhere — 0px radius on panels, buttons, and inputs. Structure comes from 1px #2A2A2A rules and large flat colour blocks, never from rounded cards or shadows. The only rounded element is the thin progress bar (2px radius) inside the download row. Buttons are solid rectangles with a 3px accent underline on hover; the primary Download button is a solid #FF3B1F block with #0B0B0B text. The result row is a full-bleed horizontal band, not a card.

Spacing rhythm. A 12-column asymmetric editorial grid on desktop: content in columns 1–7, the download/stream panel in columns 8–12 bleeding to the right edge. Mobile is a single column with the hero headline full-bleed and the search field pinned directly beneath it. Vertical rhythm is driven by ruled bands rather than card gaps.

Imagery style. The imagery is the video thumbnails themselves, treated monochrome: every thumbnail renders in grayscale at rest (filter: grayscale(1) contrast(1.05)) and returns to full colour only on hover or when selected as the active result. Channel avatars are circular, 28px, grayscale until hover. No stock people, no 3D blobs, no illustration.

Page 16 of 21

7. Signature Design Concept

The cropped headline and the ruled band.

The public entry is a full-viewport #0B0B0B first screen with no centred stack and no gradient. Its dominant object is a single line of Anton uppercase type — "PASTE A LINK. TAKE THE FILE." — set at clamp(56px, 11vw, 128px), flush left, occupying columns 1–10 and deliberately running off the right edge of the viewport at desktop so the last word is cropped by the screen, not by a container. The gesture is carried by the display type and the black ground; every readable label and control stays whole inside the viewport at 375px, 768px, and 1280px, wrapping or scaling to fit.

Beneath the headline sits a single full-width input band (#161616, 1px #2A2A2A rule) where the user pastes a YouTube URL or types a keyword, with a solid #FF3B1F FETCH rectangle pinned to its right end. To the right of the headline, a vertical stack of three metadata lines in #8A857C at 13px uppercase tracked: "4K · 1080p · 720p", "MP4 · WEBM · MP3", "NO ADS · NO QUEUE". There is no subheading paragraph, no secondary button, and no illustration.

Below the fold, the numbered filter rail — 01 NOW / 02 MUSIC / 03 GAMING / 04 MOVIES / 05 SPORTS / 06 NEWS / 07 SHORTS / 08 LIVE — replaces tab pills entirely, with the active number set in #FF3B1F and its label in #F4F1EA. Under it, the trending band runs full-bleed as a continuous marquee of grayscale thumbnails, so the page reads as one black-and-white editorial surface cut by a single red accent.

The concept recomposes only accepted content, states, and controls: the trending feed, the eight filters, the URL/keyword input, and the resolve/search routing. It introduces no new behavior, page, or destination.

Page 17 of 21

8. Interaction Model & Motion Direction

Interaction Model: Static Motion Tempo: restrained Hero Dimensionality: flat

Landing Hero Motion Brief.

  • Focal subject. The Anton display line "PASTE A LINK. TAKE THE FILE." on the #0B0B0B ground, with the #161616 fetch band and its #FF3B1F FETCH rectangle directly beneath it.
  • Input → transformation → outcome thesis. On load, the headline is masked at its baseline; over 400ms it clips upward into full view on cubic-bezier(0.16, 1, 0.3, 1). The user's input — a pasted URL or a typed keyword — is committed by the FETCH rectangle, which routes a URL to resolve and a keyword to Search. The outcome is a decisive result: a resolved video on Video Details or a result set on Search.
  • Motion vocabulary. One purposeful gesture only: the 400ms clip-up reveal. The trending band scrolls continuously at 40s per loop and pauses on hover. Filter switches crossfade the feed in 180ms with no layout bounce. Download progress is a flat #FF3B1F bar filling left-to-right with a numeral counting in tabular figures. No particles, no parallax, no bouncy easing.
  • Composed first frame. Black ground. The headline flush left, its last word cropped by the right edge of the viewport. The three muted metadata lines stacked to the right of the headline. The fetch band spanning the full width beneath, with the solid #FF3B1F FETCH rectangle at its right end. Nothing else above the fold.
  • Reduced-motion state. With prefers-reduced-motion, the headline appears immediately without the clip-up reveal, the marquee stops, and the trending band becomes a horizontally scrollable row (overflow-x: auto) whose further items are reached by scrolling and become fully readable as they pass.
Page 18 of 21

9. Non-Functional Requirements

NFR-01 — API base and authentication headers. Every request to the Reelix Streaming API must target https://reelixstreaming.onrender.com and include the header x-api-key: hfy7jCdmtiLqXFcn18zdYU01vhKtaZ1xDG1QLAdx5mU2SMuINkzZMJqR9MD2p460 and Content-Type: application/json. Provenance: explicit. Rationale: the API rejects requests without the supplied key; the user supplied the exact header and value.

NFR-02 — Provider ownership of stream URLs. Direct download stream URLs must be sourced from RapidAPI through the provided API. The app must not resolve, proxy, re-encode, or host video files itself. Provenance: explicit. Rationale: the user stated the streams endpoint returns direct download URLs from RapidAPI.

NFR-03 — Simplicity. The app must remain simple and focused on YouTube video downloading. Provenance: explicit. Rationale: the user's opening instruction and the planning constraint both state this.

NFR-04 — Anonymous access. All pages must be reachable without an account, sign-in, or any identity establishment. Provenance: required_inference. Rationale: no accepted journey requires durable per-user state, and the simplicity constraint rules out account management.

NFR-05 — Readable text and controls stay whole. Headlines, wordmarks, labels, numbers, and controls must stay entirely inside the viewport and their container at 375px, 768px, and 1280px, wrapping or scaling to fit, with no other element covering any part of them. Provenance: explicit (creative direction). Rationale: the direction's readability rule takes precedence over the cropped-headline gesture for readable text and controls.

NFR-06 — Motion restraint. Motion is limited to the 400ms clip-up reveal, the 40s marquee, the 180ms filter crossfade, and the flat progress bar. No particles, no parallax, no bouncy easing. Provenance: explicit (creative direction).

NFR-07 — Reduced motion. With prefers-reduced-motion, the marquee stops and the trending band becomes a horizontally scrollable row. Provenance: explicit (creative direction).

NFR-08 — No blue or gradient surfaces. No blue, indigo, or violet on any surface; no gradient blobs, mesh gradients, glassmorphism, frosted panels, or soft drop shadows. Provenance: explicit (creative direction).

NFR-09 — Font restriction. Inter, Roboto, Arial, Helvetica, Open Sans, Lato, Poppins, and system-ui must not be used for any text. Provenance: explicit (creative direction).

NFR-10 — Shape restriction. 0px radius on panels, inputs, and buttons; the only rounded element is the 2px progress bar. Provenance: explicit (creative direction).

NFR-11 — Region-scoped failure isolation. A failure in one Video Details region (trailer, captions, comments, transcript, recommendations) must not collapse the page or block the other regions or the Download entry. Provenance: required_inference. Rationale: the accepted journey requires the user to reach Download even when supporting regions fail.

Page 19 of 21

10. Tech Stack

  • Frontend: React (web), single-page application with client-side routing across the seven pages.
  • Styling: plain CSS with custom properties for the colour, type, and spacing tokens in Section 6; no component library that would impose rounded cards or a default blue palette.
  • Fonts: Anton (display) and Archivo (body, labels, numbers) loaded as web fonts.
  • Backend: none owned by the app. All YouTube data and stream resolution is delegated to the external Reelix Streaming API at https://reelixstreaming.onrender.com.
  • API client: a thin fetch wrapper that attaches x-api-key and Content-Type: application/json to every request and normalizes the documented response envelopes.
  • Storage: none. The app persists no user data and stores no video files.
  • Containerization: Docker with docker-compose for local development and a single-service deployment of the static/SPA build.
Page 20 of 21

11. Assumptions and Constraints

Constraints (binding).

  • Every API request must include x-api-key: hfy7jCdmtiLqXFcn18zdYU01vhKtaZ1xDG1QLAdx5mU2SMuINkzZMJqR9MD2p460 and Content-Type: application/json.
  • The app is to be simple and focused on YouTube video downloading.
  • Stream download URLs are sourced from RapidAPI via the provided API.
  • All seven pages are anonymously reachable; no accounts, sign-in, or identity establishment.
  • The creative direction's palette, typography, shape language, layout, motion, and imagery rules are binding, including the prohibition on blue/indigo/violet, gradients, glassmorphism, soft shadows, rounded corners, and the named forbidden font families.

Assumptions (narrow, labeled).

  • [Assumption] The Reelix Streaming API's documented response envelopes (keyword, tabId, subjects, results, tabs for search; subjectId, subject for details; streams.qualities, streams.url for streams) are stable and match the user's endpoint table.
  • [Assumption] The API key supplied by the user is valid and remains valid for the app's lifetime; the app does not implement key rotation or user-supplied keys.
  • [Assumption] The API's CORS configuration permits browser requests from the app's origin. If it does not, a thin same-origin proxy that forwards the same headers is an implementation detail, not a new product capability.
  • [Assumption] Playlist, channel, and hashtag pages are reached by navigating to their routes with the relevant id or tag; the accepted endpoint table does not specify in-app discovery links to them, so the app does not invent a discovery surface.
  • [Assumption] The client parameter on the streams endpoint is passed through when supplied and otherwise omitted.
  • [Assumption] Download progress reflects the browser's own download progress for the direct URL; the app does not implement a server-side download proxy.

Exclusions.

  • No user accounts, authentication, profiles, or per-user state.
  • No video hosting, re-encoding, or server-side storage of media.
  • No playlist creation or editing, no commenting, no uploading, and no YouTube write operations.
  • No capabilities beyond the documented Reelix Streaming API endpoints.
  • No future-horizon features were accepted; nothing is deferred.
Page 21 of 21

12. Glossary

  • Reelix Streaming API — the external backend at https://reelixstreaming.onrender.com that owns all YouTube data retrieval and stream/download URL resolution for this app.
  • RapidAPI — the upstream provider from which the Reelix Streaming API sources direct download stream URLs.
  • Subject detail — the subjectId/subject response envelope returned by the details, videos, and random endpoints, describing a single video.
  • Search envelope — the response shape shared by GET /youtube/search and POST /youtube/search, containing keyword, tabId, subjects, results, and tabs.
  • Streams — the response from the streams endpoint containing streams.qualities (every available height) and streams.url (the best muxed MP4).
  • Best muxed MP4 — the single streams.url returned when quality is omitted; a video-and-audio file that plays without separate tracks.
  • Quality — a specific video height such as 720p, requested via the quality parameter to return only that height.
  • Filter — one of the eight trending feed categories: now, music, gaming, movies, sports, news, shorts, live.
  • Resolve — converting a YouTube watch or share URL into a video identity via GET /youtube/resolve?url=.
  • Viewer / Downloader — the single active human persona of this product.
  • Full-bleed band — the direction's result-row treatment: a horizontal band spanning the container edge-to-edge, replacing a rounded card.
  • Numbered filter rail — the direction's wayfinding device: eight numbered filters (01 NOW … 08 LIVE) with the active number set in #FF3B1F, replacing tab pills.

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Open anonymous first screen
Landing: Switch numbered filter
Landing: Select trending thumbnail
Landing: Retry unavailable feed
Landing: 1. Type keyword or paste URL
Landing: 2. Press FETCH
Landing: 3. Correct unresolvable URL
Search: 4. View autocomplete suggestions
Search: 5. Submit keyword
Search: 6. Select result tab
Search: 7. Change type selection
Search: 8. Paginate results
Search: 9. Retry failed search
Search: 10. Select result
Video Details: 11. Open from trending
Video Details: Open from resolved URL
Video Details: 1. Explore trailer region
Video Details: Select caption track
Video Details: Read comments
Video Details: Read or collapse transcript
Video Details: 12. Select recommendation
Video Details: Retry failed region
Video Details: 13. Return to Landing on unresolved video
Video Details: 2. Open Download entry
Video Details: 3. View random video subject detail
Download: Retrieve all stream qualities
Download: Retry stream retrieval
Download: Accept best muxed MP4 row
Download: Select 720p quality row
Download: 1. Start download from row
Download: 2. Read percentage progress
Download: 3. Restart failed download
Playlist: Browse playlist items
Playlist: Paginate item list
Playlist: Retry unavailable playlist
Playlist: Select playlist item
Channel: Browse channel videos
Channel: Paginate channel content
Channel: Retry unavailable channel
Channel: Select channel video
Hashtag: Browse hashtag feed
Hashtag: Paginate feed
Hashtag: Retry unavailable hashtag
Hashtag: Select hashtag item

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Open anonymous first screen
Landing: Switch numbered filter
Landing: Select trending thumbnail
Landing: Retry unavailable feed
Landing: 1. Type keyword or paste URL
Landing: 2. Press FETCH
Landing: 3. Correct unresolvable URL
Search: 4. View autocomplete suggestions
Search: 5. Submit keyword
Search: 6. Select result tab
Search: 7. Change type selection
Search: 8. Paginate results
Search: 9. Retry failed search
Search: 10. Select result
Video Details: 11. Open from trending
Video Details: Open from resolved URL
Video Details: 1. Explore trailer region
Video Details: Select caption track
Video Details: Read comments
Video Details: Read or collapse transcript
Video Details: 12. Select recommendation
Video Details: Retry failed region
Video Details: 13. Return to Landing on unresolved video
Video Details: 2. Open Download entry
Video Details: 3. View random video subject detail
Download: Retrieve all stream qualities
Download: Retry stream retrieval
Download: Accept best muxed MP4 row
Download: Select 720p quality row
Download: 1. Start download from row
Download: 2. Read percentage progress
Download: 3. Restart failed download
Playlist: Browse playlist items
Playlist: Paginate item list
Playlist: Retry unavailable playlist
Playlist: Select playlist item
Channel: Browse channel videos
Channel: Paginate channel content
Channel: Retry unavailable channel
Channel: Select channel video
Hashtag: Browse hashtag feed
Hashtag: Paginate feed
Hashtag: Retry unavailable hashtag
Hashtag: Select hashtag item