LuanRT / YouTube.js

A wrapper around YouTube's internal API — reverse engineering InnerTube
https://www.npmjs.com/package/youtubei.js
MIT License
3.3k stars 199 forks source link

10.0.0 [YOUTUBEJS][Parser]: InnertubeError: Something went wrong at ContentMetadataView! #668

Open iBicha opened 2 weeks ago

iBicha commented 2 weeks ago

Steps to reproduce

Happens when trying to read playlists (I'll dig into this further when I have some time)

This is from yt2alt, usage looks like this

    async getPlaylistWithVideos(playlistId, limit = PLAYLIST_LIMIT) {
        await this.createSession();

        let playlist = await this.innertube.getPlaylist(playlistId);

        const videos = await this.getFeedVideosWithLimit(playlist, limit);

        return this.toPlaylistWithVideos(playlist, videos);
    }

    async getFeedVideosWithLimit(feed, limit = PLAYLIST_LIMIT) {
        const videos = [];
        while (limit === -1 || videos.length < limit) {
            try {
                videos.push(...feed.videos);
                if (!feed.has_continuation) {
                    break;
                }
                feed = await feed.getContinuation();
            } catch (error) {
                console.error(error);
                break;
            }
        }

        return videos.slice(0, limit)
            .map(video => this.toVideo(video));
    }

Failure Logs

[YOUTUBEJS][Parser]: InnertubeError: Something went wrong at ContentMetadataView!
This is a bug, please report it at https://github.com/LuanRT/YouTube.js/issues
    at ERROR_HANDLER (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:48:31)
    at Module.parseItem (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:393:13)
    at new PageHeaderView (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/PageHeaderView.js:16:32)
    at Module.parseItem (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:388:28)
    at new PageHeader (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/PageHeader.js:8:31)
    at parseItem (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:388:28)
    at parse (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:437:34)
    at Module.parseResponse (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:194:34)
    at new Feed (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/core/mixins/Feed.js:39:61)
    at new Playlist (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/youtube/Playlist.js:22:9) {
  info: {
    stack: "TypeError: Cannot destructure property 'content' of 'data' as it is undefined.\n" +
      '    at Text.fromAttributed (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/misc/Text.js:42:17)\n' +
      '    at file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/ContentMetadataView.js:10:32\n' +
      '    at Array.map (<anonymous>)\n' +
      '    at file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/ContentMetadataView.js:9:98\n' +
      '    at Array.map (<anonymous>)\n' +
      '    at new ContentMetadataView (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/ContentMetadataView.js:6:48)\n' +
      '    at Module.parseItem (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:388:28)\n' +
      '    at new PageHeaderView (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/PageHeaderView.js:16:32)\n' +
      '    at Module.parseItem (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/parser.js:388:28)\n' +
      '    at new PageHeader (file:///Users/brahim/Roku/yt2alt/node_modules/youtubei.js/dist/src/parser/classes/PageHeader.js:8:31)'
  },
  date: 2024-06-16T16:18:45.549Z,
  version: '10.0.0'
}

Expected behavior

Reads videos from playlists

Current behavior

Error printed, but still successfully reads videos (or at least the ids are there)

Version

Default

Anything else?

No response

Checklist

iBicha commented 2 weeks ago

So when reading this playlist I have, the issue is with the parsing of ContentMetadataView.

Parsing assumes that a ContentMetadataView contains rows, and each row contains parts, and each part is a text. But in my case I see that a part can be of type AvatarStack, which seems to be a list of avatars (I assume this is because maybe it is possible, or it will become possible, to collaborate on creating a playlist by multiple people maybe?)

Here's the json of this ContentMetadataView causing the bug

{
  "metadataRows": [
    {
      "metadataParts": [
        {
          "avatarStack": {
            "avatarStackViewModel": {
              "avatars": [
                {
                  "avatarViewModel": {
                    "image": {
                      "sources": [
                        {
                          "url": "https://yt3.ggpht.com/ytc/redacted",
                          "width": 48,
                          "height": 48
                        }
                      ],
                      "processor": {
                        "borderImageProcessor": {
                          "circular": true
                        }
                      }
                    },
                    "avatarImageSize": "AVATAR_SIZE_XS"
                  }
                }
              ],
              "text": {
                "content": "redacted",
                "commandRuns": [
                  {
                    "startIndex": 0,
                    "length": 15,
                    "onTap": {
                      "innertubeCommand": {
                        "clickTrackingParams": "redacted",
                        "commandMetadata": {
                          "webCommandMetadata": {
                            "url": "/@BrahimHadriche",
                            "webPageType": "WEB_PAGE_TYPE_CHANNEL",
                            "rootVe": 3611,
                            "apiUrl": "/youtubei/v1/browse"
                          }
                        },
                        "browseEndpoint": {
                          "browseId": "redacted",
                          "canonicalBaseUrl": "redacted"
                        }
                      }
                    }
                  }
                ],
                "styleRuns": [
                  {
                    "startIndex": 0,
                    "length": 15,
                    "weightLabel": "FONT_WEIGHT_NORMAL",
                    "styleRunExtensions": {
                      "styleRunColorMapExtension": {
                        "colorMap": [
                          {
                            "key": "USER_INTERFACE_THEME_LIGHT",
                            "value": 4294967295
                          },
                          {
                            "key": "USER_INTERFACE_THEME_DARK",
                            "value": 4294967295
                          }
                        ]
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    },
    {
      "metadataParts": [
        {
          "text": {
            "content": "9 videos"
          }
        },
        {
          "text": {
            "content": "Public"
          }
        }
      ]
    }
  ]
} 
absidue commented 2 weeks ago

Until now YouTube has only used that node on the channel page, hence the current handling. Sounds like they are switching to that on the playlist page too then.

Thank you for providing the snippet that causes the problem, that will make it easier to add support for it.