{"id":14979873,"url":"https://github.com/patrickkfkan/yt-mix-playlist","last_synced_at":"2025-10-28T20:30:16.636Z","repository":{"id":57404580,"uuid":"323943632","full_name":"patrickkfkan/yt-mix-playlist","owner":"patrickkfkan","description":"Node module for fetching YouTube Mix playlists.","archived":false,"fork":false,"pushed_at":"2023-04-03T20:12:54.000Z","size":99,"stargazers_count":2,"open_issues_count":4,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-09-28T03:40:23.098Z","etag":null,"topics":["mixes","playlist","youtube"],"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/patrickkfkan.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}},"created_at":"2020-12-23T15:56:44.000Z","updated_at":"2023-11-26T21:06:12.000Z","dependencies_parsed_at":"2024-06-21T20:22:32.031Z","dependency_job_id":"406f83dd-a542-4ea0-bfdc-5a5c94811153","html_url":"https://github.com/patrickkfkan/yt-mix-playlist","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickkfkan%2Fyt-mix-playlist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickkfkan%2Fyt-mix-playlist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickkfkan%2Fyt-mix-playlist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/patrickkfkan%2Fyt-mix-playlist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/patrickkfkan","download_url":"https://codeload.github.com/patrickkfkan/yt-mix-playlist/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219858899,"owners_count":16556039,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["mixes","playlist","youtube"],"created_at":"2024-09-24T14:00:49.515Z","updated_at":"2025-10-28T20:30:16.048Z","avatar_url":"https://github.com/patrickkfkan.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# yt-mix-playlist\n\nNode module for fetching YouTube Mix playlists.\n\n## Install\n\n```\nnpm install yt-mix-playlist --save\n```\n\n## Usage\n\nImport module:\n\n```\n// ESM\nimport ytmpl from 'yt-mix-playlist';\n\n// CJS\nconst ytmpl = require('yt-mix-playlist');\n\n```\n\nFetch Mix playlist for a video:\n\n```\nconst videoId = 'XCcN-IoYIJA';\nconst mixPlaylist = await ytmpl(videoId);\nconsole.log(mixPlaylist);\n```\n\nResult:\n```\nMixPlaylist {\n  id: 'RDXCcN-IoYIJA',\n  title: 'Mix - Wiljan \u0026 Xandra - Woodlands',\n  author: 'YouTube',\n  url: 'http://www.youtube.com/watch?v=XCcN-IoYIJA\u0026list=RDXCcN-IoYIJA',\n  videoCount: '50+ videos',\n  thumbnails: [\n    Thumbnail {\n      url: 'https://i.ytimg.com/vi/XCcN-IoYIJA/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLARuI_29dvrA_u7pQj4xs8X_HUwDw',\n      width: 336,\n      height: 188\n    },\n    Thumbnail {\n      url: 'https://i.ytimg.com/vi/XCcN-IoYIJA/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==\u0026rs=AOn4CLCnA4XJbGLUcY1BPiU3TjMhKj1VXA',\n      width: 168,\n      height: 94\n    }\n  ],\n  currentIndex: 0,\n  items: [\n    MixPlaylistItem {\n      id: 'XCcN-IoYIJA',\n      title: 'Wiljan \u0026 Xandra - Woodlands',\n      author: [Author],\n      url: 'https://www.youtube.com/watch?v=XCcN-IoYIJA\u0026list=RDXCcN-IoYIJA\u0026index=1',\n      selected: true,\n      duration: '5:30',\n      thumbnails: [Array]\n    },\n    MixPlaylistItem {\n      id: '_jYoI4rR_fg',\n      title: 'Waking Dreams - Someone Else',\n      author: [Author],\n      url: 'https://www.youtube.com/watch?v=_jYoI4rR_fg\u0026list=RDXCcN-IoYIJA\u0026index=2',\n      selected: false,\n      duration: '4:49',\n      thumbnails: [Array]\n    },\n    ...\n  ]\n}\n```\n\n`items` array contains videos currently in the playlist. `currentIndex` refers to the position of the selected video in the array.\n\nOn YouTube, when you select a video in a Mix playlist, the contents of the list may refresh depending on the position of the selected video. With this module, you can programatically 'select' a video and obtain an updated playlist with possibly changed contents.\n\n\nTo change selected video:\n```\n// Select by video Id or index from current list\nconst updatedPlaylist = await mixPlaylist.select(videoIdOrIndex);\n```\nor:\n```\n// Select the last video in current list\nconst updatedPlaylist = await mixPlaylist.selectLast();\n```\nor:\n```\n// Select the first video in current list\nconst updatedPlaylist = await mixPlaylist.selectFirst();\n```\n\nEach of the 'select' methods returns a new playlist. The original playlist remains unchanged.\n\nExample:\n```\n// Select last video in the list\nconst updatedPlaylist = await mixPlaylist.selectLast();\nconsole.log(updatedPlaylist);\n```\n\nResult:\n```\nMixPlaylist {\n  id: 'RDXCcN-IoYIJA',\n  title: 'Mix - Wiljan \u0026 Xandra - Woodlands',\n  author: 'YouTube',\n  url: 'http://www.youtube.com/watch?v=XXYlFuWEuKI\u0026list=RDXCcN-IoYIJA',\n  videoCount: '50+ videos',\n  thumbnails: [\n    Thumbnail {\n      url: 'https://i.ytimg.com/vi/XCcN-IoYIJA/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLARuI_29dvrA_u7pQj4xs8X_HUwDw',\n      width: 336,\n      height: 188\n    },\n    Thumbnail {\n      url: 'https://i.ytimg.com/vi/XCcN-IoYIJA/hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==\u0026rs=AOn4CLCnA4XJbGLUcY1BPiU3TjMhKj1VXA',\n      width: 168,\n      height: 94\n    }\n  ],\n  currentIndex: 24,\n  items: [\n    MixPlaylistItem {\n      id: 'XCcN-IoYIJA',\n      title: 'Wiljan \u0026 Xandra - Woodlands',\n      author: [Author],\n      url: 'https://www.youtube.com/watch?v=XCcN-IoYIJA\u0026list=RDXCcN-IoYIJA\u0026index=1',\n      selected: false,\n      duration: '5:30',\n      thumbnails: [Array]\n    },\n    ...\n    MixPlaylistItem {\n      id: 'XXYlFuWEuKI',\n      title: 'The Weeknd - Save Your Tears (Official Music Video)',\n      author: [Author],\n      url: 'https://www.youtube.com/watch?v=XXYlFuWEuKI\u0026list=RDXCcN-IoYIJA\u0026index=25',\n      selected: true,\n      duration: '4:09',\n      thumbnails: [Array]\n    },\n    MixPlaylistItem {\n      id: 'pxirHB4Hyzk',\n      title: 'Maya Bay',\n      author: [Author],\n      url: 'https://www.youtube.com/watch?v=pxirHB4Hyzk\u0026list=RDXCcN-IoYIJA\u0026index=26',\n      selected: false,\n      duration: '3:13',\n      thumbnails: [Array]\n    },\n    ...\n  ]\n}\n```\n\nMost times, we would be interested in obtaining new items from the playlist. We can do so as follows:\n```\nconst updatedPlaylist = await mixPlaylist.selectLast();\n\n// selectLast() will definitely return a list with new items.\n// There will be some items carried over from the original list.\n// To get the new items not in the original list, do this:\n\nconst newItems = updatedPlaylist.getItemsAfterSelected();\n```\n## API\n\n**ytmpl(`videoId`: string, `options`?: { `gl`?: string, `hl`?: string }): Promise\u003c`MixPlaylist` | `null`\u003e**\n\nOptions:\n- `hl`: language\n- `gl`: region\n\nExample:\n```\nconst mixPlaylist = await ytmpl('XCcN-IoYIJA', { hl: 'en', gl: 'US' });\n```\n\nReturns a Promise that resolves to a `MixPlaylist` instance representing the Mix playlist for the video, or `null` if none found.\n\n### `MixPlaylist` methods\n\n**select(`index`: number): Promise\u003c`MixPlaylist` | `null`\u003e**\\\n**select(`videoId`: string): Promise\u003c`MixPlaylist` | `null`\u003e**\n\nSelects video in the playlist by its `index` or `videoId`. Returns a Promise that resolves to a new `MixPlaylist` instance representing the updated playlist after selection. Original playlist is not changed.\n\n**selectFirst(): Promise\u003c`MixPlaylist` | `null`\u003e**\n\nConvenience method that passes the first item in the playlist to `select()` and returns the result.\n\n**selectLast(): Promise\u003c`MixPlaylist` | `null`\u003e**\n\nConvenience method that passes the last item in the playlist to `select()` and returns the result.\n\n**getSelected(): `MixPlaylistItem`**\n\nReturns a `MixPlaylistItem` object representing the selected item in the playlist. Same as calling `playlist.items[playlist.currentIndex]`.\n\n**getItemsBeforeSelected(): Array\u003c`MixPlaylistItem`\u003e**\n\nReturns playlist items as an array of `MixPlaylistItem` objects up to but not including the selected one.\n\n**getItemsAfterSelected(): Array\u003c`MixPlaylistItem`\u003e**\n\nReturns playlist items as an array of `MixPlaylistItem` objects after the selected one.\n\n## Properties\n\n|Property               |Remark                                           |\n|-----------------------|-------------------------------------------------|\n|id                     |Id of the Mix playlist                           |\n|title                  |                                                 |\n|author                 |'YouTube'                                        |\n|url                    |Share URL                                        |\n|items                  |Array\u003c`MixPlaylistItem`\u003e: videos in the playlist |\n|currentIndex           |Index of the selected item                       |\n|videoCount             |'50+ ...'                                        |\n|thumbnails             |Array\u003c`Thumbnail`\u003e: {url, width, height}         |\n\nEach item in the `items` array is a `MixPlaylistItem` object with the following properties:\n\n|Property               |Remark                                     |\n|-----------------------|-------------------------------------------|\n|id                     |Video Id                                   |\n|title                  |                                           |\n|url                    |                                           |\n|author                 |`Author`: { name, channelId, url }         |\n|selected               |Whether item is selected in the playlist   |\n|duration               |                                           |\n|thumbnails             |Array\u003c`Thumbnail`\u003e: {url, width, height}   |\n\n## Changelog\n\n1.0.1:\n- Fix fetching of continuation data\n- Fix silly bug with reading undefined data\n\n1.0.0:\n- Rewrite with Typescript and as ESM + CJS hybrid module\n- Replace [request](https://github.com/request/request) dependency with [node-fetch](https://github.com/node-fetch/node-fetch) + [fetch-cookie](https://github.com/valeriangalliat/fetch-cookie), as 'request' is deprecated and contains critical vulnerability.\n- Changed license to MIT (not that it really affects anything...)\n\n0.1.2-b.2:\n- Fix regression bug\n\n0.1.2-b:\n- More robust fetching of mix playlists (using continuation tokens if necessary)\n- Use semantic versioning from now on\n\n0.1.1b:\n- Fix dependencies\n\n0.1.0b:\n- Initial release\n\n## License\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickkfkan%2Fyt-mix-playlist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpatrickkfkan%2Fyt-mix-playlist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpatrickkfkan%2Fyt-mix-playlist/lists"}