{"id":21626453,"url":"https://github.com/qodesmith/dl-yt-playlist","last_synced_at":"2026-04-21T05:31:39.055Z","repository":{"id":195332262,"uuid":"692715727","full_name":"qodesmith/dl-yt-playlist","owner":"qodesmith","description":"An app to download all videos in a YouTube playlist, including metadata.","archived":false,"fork":false,"pushed_at":"2026-01-16T12:39:50.000Z","size":295,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-21T17:30:29.367Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/qodesmith.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-09-17T11:10:52.000Z","updated_at":"2026-01-16T12:39:54.000Z","dependencies_parsed_at":"2023-09-17T14:27:41.563Z","dependency_job_id":"fe33e1b3-e453-4f16-86a8-ee5aa933cc6c","html_url":"https://github.com/qodesmith/dl-yt-playlist","commit_stats":null,"previous_names":["qodesmith/youtube-playlist-videos-metadata","qodesmith/dl-yt-playlist","qodesmith/download-youtube-playlist"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/qodesmith/dl-yt-playlist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qodesmith%2Fdl-yt-playlist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qodesmith%2Fdl-yt-playlist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qodesmith%2Fdl-yt-playlist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qodesmith%2Fdl-yt-playlist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qodesmith","download_url":"https://codeload.github.com/qodesmith/dl-yt-playlist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qodesmith%2Fdl-yt-playlist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32078741,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-21T02:38:07.213Z","status":"ssl_error","status_checked_at":"2026-04-21T02:38:06.559Z","response_time":128,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-25T01:13:24.577Z","updated_at":"2026-04-21T05:31:39.026Z","avatar_url":"https://github.com/qodesmith.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Download YouTube Playlist\n\nDownload all videos from a YouTube playlist. You can optionally download the audio and thumbnail images as well.\n\n## Prerequisites\n\nYou'll need a few things to use this project:\n\n- This project uses [Bun](https://bun.sh/)! Get that installed or feel free to edit the source code to use Node instead (it'll only be a few adjustments).\n- You'll need a [YouTube Data API](https://developers.google.com/youtube/v3) key. Set that to the `API_KEY` env variable.\n- The [yt-dlp](https://github.com/yt-dlp/yt-dlp) command line tool needs to be present on your system. You can easily install it with a tool like [Brew](https://formulae.brew.sh/formula/yt-dlp).\n\n## Usage\n\nThe type signature looks like this:\n\n```typescript\ndownloadYoutubePlaylist({\n  /** YouTube playlist id. */\n  playlistId: string\n\n  /**\n   * YouTube API key. This will be used to fetch all metadata for videos in the\n   * playlist.\n   */\n  youTubeApiKey: string\n\n  /**\n   * The absolute path to where the data should be stored. Sub-folders will be\n   * created as needed. The folder structure will be:\n   *\n   * - `\u003cdirectory\u003e/metadata.json` - an array of objects (`Video[]`)\n   * - `\u003cdirectory\u003e/audio` - contains the audio files\n   * - `\u003cdirectory\u003e/video` - contains the video files\n   * - `\u003cdirectory\u003e/thumbnails` - contains the jpg thumbnail files\n   */\n  directory: string\n\n  /**\n   * `'none'`  - No files will be downloaded, including thumbnails. Only the\n   *             `metadata.json` file will be written.\n   *\n   * `'audio'` - Download only audio files as determined by the `audioFormat`\n   *             option. Defaults to `'mp3'`.\n   *\n   * `'video'` - Download only video files as determined by the `videoFormat`\n   *             option. Defaults to `'mp4'`\n   *\n   * `'both'`  - Download audio and video files as determined by their\n   *             corresponding format options.\n   */\n  downloadType: DownloadType\n\n  /**\n   * Optional - default value `'mp3'`\n   *\n   * A valid ffmpeg audio [format](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#format-selection) string.\n   */\n  audioFormat?: string\n\n  /**\n   * Optional - default value `'mp4'`\n   *\n   * A valid ffmpeg video [format](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#format-selection) string.\n   */\n  videoFormat?: string\n\n  /**\n   * Optional - default value `false`\n   *\n   * A boolean indicating wether to download a `.jpg` thumbnail for each video.\n   * The highest resolution available will be downloaded. Only thumbnails for\n   * new videos will be downloaded.\n   */\n  downloadThumbnails?: boolean\n\n  /**\n   * Optional - default value `Infinity`\n   *\n   * The maximum duration in seconds a playlist item can be to be downloaded.\n   */\n  maxDurationSeconds?: number\n\n  /**\n   * Optional - default value `undefined`\n   *\n   * A _positive_ number (max of 50) indicating how many items in the playlist\n   * to retrieve, starting with the most recent. Negative and invalid numbers\n   * will be ignored. All items will be retrieved if no value is provided.\n   *\n   * I.e. `mostRecentItemsCount: 20` will only retrieve data for the most recent\n   * 20 videos in the playlist. This option is useful when running in a cron job\n   * to avoid fetching and parsing the entire list when you may already have a\n   * substantial portion processed and downloaded already.\n   */\n  mostRecentItemsCount?: number\n\n  /**\n   * Optional - default value `false`\n   *\n   * Boolean indicating wether to silence all internal console.log's.\n   */\n  silent?: boolean\n\n  /**\n   * Optional - deafaults to the system time zone.\n   *\n   * String indicating what timezone to use for the logger.\n   */\n  timeZone?: string\n\n  /**\n   * Options - default value `4`\n   *\n   * The number of concurrent fetch calls made to the YouTube\n   * [VideosList API](https://developers.google.com/youtube/v3/docs/videos/list).\n   */\n  maxConcurrentFetchCalls?: number\n\n  /**\n   * Options - default value `10`\n   *\n   * The number of concurrent downloads to process. We use\n   * [Bun's shell](https://bun.sh/docs/runtime/shell) to asychronously execute\n   * the [yt-dlp](https://github.com/yt-dlp/yt-dlp) command.\n   */\n  maxConcurrentYtdlpCalls?: number\n\n  /**\n   * Optiona - default value `false`\n   *\n   * Boolean indicated whether to save the response data directly from the\n   * YouTube API. This can be helpful for debugging. If set to `true`, two files\n   * will be saved:\n   *\n   * - youtubePlaylistResponses.json\n   * - youtubeVideoResponses.json\n   */\n  saveRawResponses?: boolean\n}): Promise\u003cFailuresObj\u003e\n```\n\n## Folder Structure\n\nDownloads will be organized into the following folder structure:\n\n```\ndirectory-you-provided\n  /\u003cplaylist name\u003e\n    /video\n      \u003ctitle\u003e [\u003cvideo id\u003e].mp4\n      ...\n    /audio\n      \u003ctitle\u003e [\u003cvideo id\u003e].mp3\n      ...\n    /thumbnails\n      \u003cvideo id\u003e.jpg\n      ...\n    metadata.json\n    youtubePlaylistResponses.json (only if `saveRawResponses` is true)\n    youtubeVideoResponses.json (only if `saveRawResponses` is true)\n```\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e/video\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThis folder will contain all the video files (file extension is dependent upon `audioFormat` option).\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e/audio\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThis folder will contain all the audio files (file extension is dependent upon `videoFormat` option).\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003e/thumbnails\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThis folder will contain all the jpg thumbnail files\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003emetadata.json\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThis file will contain an array of metadata on each video. See shape below\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eyoutubePlaylistResponses.json\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThis file will contain an array of raw responses from YouTube's \u003ca href=\"https://developers.google.com/youtube/v3/docs/playlistItems/list\"\u003ePlaylistItems: list\u003c/a\u003e api.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd\u003e\u003ccode\u003eyoutubeVideoResponses.json\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eThis file will contain an array of raw responses from YouTube's \u003ca href=\"https://developers.google.com/youtube/v3/docs/videos/list\"\u003eVideos: list\u003c/a\u003e api.\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Metadata Shape\n\nEach video will have metadata stored in the `metadata.json` file with the following shape:\n\n```typescript\n{\n  id: string\n  title: string\n  description: string\n  channelId: string\n  channelName: string\n  dateCreated: string\n  dateAddedToPlaylist: string\n  thumbnailUrl: string | null\n  durationInSeconds: number\n  url: string\n  channelUrl: string | null\n  audioFileExtension: string | null\n  videoFileExtension: string | null\n\n  /**\n   * This value will be changed to `true` when future API calls are made and the\n   * video is found to be unavailable. This will allow us to retain previously\n   * fetch metadata.\n   */\n  isUnavailable: boolean\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqodesmith%2Fdl-yt-playlist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqodesmith%2Fdl-yt-playlist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqodesmith%2Fdl-yt-playlist/lists"}