### Project Setup and Dependencies Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/replay_page.html Instructions for setting up the project and installing necessary dependencies using npm or yarn. This includes installing the youtube-chat library and testing tools like Jest. ```bash # Install dependencies npm install youtube-chat jest ts-jest @types/jest typescript --save-dev # Or using yarn yarn add youtube-chat jest ts-jest @types/jest typescript --dev # Configure Jest for TypeScript (jest.config.js) # module.exports = { # preset: 'ts-jest', # testEnvironment: 'node', # }; # Run tests npm test # Or using yarn yarn test ``` -------------------------------- ### Project Setup and Dependencies Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/replay_page.html This section outlines the necessary steps to set up the project and install dependencies. It includes commands for initializing a Node.js project, installing TypeScript, Jest, and Axios, and configuring TypeScript for the project. ```bash # Initialize a new Node.js project npm init -y # Install TypeScript, Jest, and Axios npm install --save-dev typescript jest ts-jest @types/jest npm install axios # Create a tsconfig.json file for TypeScript configuration tsc --init # Configure Jest to work with TypeScript (e.g., in jest.config.js) # module.exports = { # preset: 'ts-jest', # testEnvironment: 'node', # }; # Example of running tests # npx jest ``` -------------------------------- ### Installation Source: https://github.com/linatsukusu/youtube-chat/blob/develop/README.md Install the youtube-chat library using either npm or yarn package managers. ```bash npm i youtube-chat yarn add youtube-chat ``` -------------------------------- ### Starting and Stopping LiveChat Source: https://github.com/linatsukusu/youtube-chat/blob/develop/README.md Start the live chat fetching loop and stop it when necessary. The start method returns a promise indicating success or failure. ```javascript // Start fetch loop const ok = await liveChat.start() if (!ok) { console.log("Failed to start, check emitted error") } // Stop loop liveChat.stop() ``` -------------------------------- ### Node.js YouTube Chat Fetcher (with Jest Testing) Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html Example code demonstrating how to fetch YouTube chat data using Node.js and TypeScript. This snippet also includes setup for testing with npm and Jest. ```typescript // Example of fetching YouTube chat data // This is a conceptual example and may require specific YouTube API libraries or methods. import axios from 'axios'; async function getYouTubeChatData(channelUrl: string): Promise { try { const response = await axios.get(`https://www.youtube.com/oembed?format=json&url=${encodeURIComponent(channelUrl)}`); return response.data; } catch (error) { console.error('Error fetching YouTube chat data:', error); throw error; } } // Example usage: const channelLiveUrl = 'https://www.youtube.com/channel/UCxkOLgdNumvVIQqn5ps_bJA/live'; getYouTubeChatData(channelLiveUrl) .then(data => { console.log('YouTube Chat Data:', data); }) .catch(err => { console.error('Failed to get chat data.'); }); // For testing with Jest, you would typically mock the axios.get call. // Example test structure (conceptual): /* import { getYouTubeChatData } from './your_module'; import axios from 'axios'; jest.mock('axios'); const mockedAxios = axios as jest.Mocked; describe('getYouTubeChatData', () => { it('should fetch chat data successfully', async () => { const mockData = { title: '[Node/TypeScript] Youtubeのチャット取得するやつ ~テスト書く編~ [npm/jest]' }; mockedAxios.get.mockResolvedValue({ data: mockData }); const data = await getYouTubeChatData(channelLiveUrl); expect(data).toEqual(mockData); expect(mockedAxios.get).toHaveBeenCalledWith(`https://www.youtube.com/oembed?format=json&url=${encodeURIComponent(channelLiveUrl)}`); }); }); */ ``` -------------------------------- ### Video Metadata Example Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/no_live_page.html This snippet provides an example of video metadata, including title, view count, and publication time, as rendered in a grid format. ```json { "gridVideoRenderer": { "videoId": "loqgzSronLs", "thumbnail": { "thumbnails": [ { "url": "https://i.ytimg.com/vi/loqgzSronLs/hqdefault.jpg?sqp=-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==\u0026rs=AOn4CLA5fa-lgXpBvJbFL5PoAxcuVds2Og", "width": 168, "height": 94 }, { "url": "https://i.ytimg.com/vi/loqgzSronLs/hqdefault.jpg?sqp=-oaymwEiCMQBEG5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==\u0026rs=AOn4CLD7e6hfnB_CpDTwnz-UINUILqH2aQ", "width": 196, "height": 110 }, { "url": "https://i.ytimg.com/vi/loqgzSronLs/hqdefault.jpg?sqp=-oaymwEjCPYBEIoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=\u0026rs=AOn4CLAwsoGBHWRBq2ttdJFmVMqOrAnzKQ", "width": 246, "height": 138 }, { "url": "https://i.ytimg.com/vi/loqgzSronLs/hqdefault.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=\u0026rs=AOn4CLAeOhPC7svJ5-u0r-MzN6Vsx_KE-g", "width": 336, "height": 188 } ] }, "title": { "accessibility": { "accessibilityData": { "label": "[Minecraft] VTuberWanted イベント告知PV [第3段] 作成者: 創好リナ [バーチャルイキリプログラマ] 3 年前 20 秒 390 回視聴" }, "simpleText": "[Minecraft] VTuberWanted イベント告知PV [第3段]" } }, "publishedTimeText": { "simpleText": "3 年前" }, "viewCountText": { "simpleText": "390 回視聴" }, "navigationEndpoint": { "clickTrackingParams": "CDEQlDUYAyITCOfjn-2ptvQCFczjTAIdXrgBHTIGZy1oaWdoWhhVQ3hrT0xnZE51bXZWSVFxbjVwc19iSkGaAQUQ8jgYZKoBIlBMRTZiZ1lTUXZobk9zSUQzWWh4VE4yWFBITmlPYVVSeHE=", "commandMetadata": { "webCommandMetadata": { "url": "/watch?v=loqgzSronLs", "webPageType": "WEB_PAGE_TYPE_WATCH", "rootVe": 3832 } }, "watchEndpoint": { "videoId": "loqgzSronLs", "watchEndpointSupportedOnesieConfig": { "html5PlaybackOnesieConfig": { "commonConfig": { "url": "https://r7---sn-nvoxu-ioq6.googlevideo.com/initplayback?source=youtube\u0026orc=1\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odeak=1\u0026odepv=1\u0026osfc=1\u0026ip=118.237.39.228\u0026id=968aa0cd2ae89cbb\u0026initcwndbps=65" } } } } } } } ``` -------------------------------- ### TypeScript tsconfig and Webpack Configuration Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/replay_page.html This snippet provides an example of TypeScript configuration using tsconfig.json and Webpack setup for a project. It's crucial for setting up the development environment and build process for TypeScript applications. ```typescript // Example tsconfig.json content (conceptual) { "compilerOptions": { "target": "es2016", "module": "commonjs", "strict": true, "esModuleInterop": true } } // Example Webpack configuration (conceptual) const path = require('path'); module.exports = { entry: './src/index.ts', module: { rules: [ { test: /.ts?$/, use: 'ts-loader', exclude: /node_modules/ } ] }, resolve: { extensions: ['.ts', '.js'] }, output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') } }; ``` -------------------------------- ### YouTube Video Renderer Example Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html Demonstrates the structure of a YouTube video renderer, including thumbnail, title, channel information, view counts, and navigation endpoints. This is typically used for displaying video cards or search results. ```json { "compactVideoRenderer": { "videoId": "qSHlXcSces8", "thumbnail": { "thumbnails": [ { "url": "https://i.ytimg.com/vi/qSHlXcSces8/hqdefault.jpg?sqp=-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLDN1ug4WLd9sN-7YPHmreJ2ajiWtw", "width": 168, "height": 94 }, { "url": "https://i.ytimg.com/vi/qSHlXcSces8/hqdefault.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLDmqQu1Xb2L9H5dexUz1rKGRmbR6A", "width": 336, "height": 188 } ] }, "title": { "accessibility": { "accessibilityData": { "label": "【日本一わかりやすいTypeScript入門】tsconfigとWebpackの設定を理解して環境構築 作成者: 【とらゼミ】トラハックのエンジニア学習講座 10 か月前 50 分 15,777 回視聴" } }, "simpleText": "【日本一わかりやすいTypeScript入門】tsconfigとWebpackの設定を理解して環境構築" }, "longBylineText": { "runs": [ { "text": "【とらゼミ】トラハックのエンジニア学習講座", "navigationEndpoint": { "clickTrackingParams": "CIoBEKQwGAMiEwjWjOPU4a30AhWQ50wCHXOEAjcyB3JlbGF0ZWQ=", "commandMetadata": { "webCommandMetadata": { "url": "/user/1492tiger", "webPageType": "WEB_PAGE_TYPE_CHANNEL", "rootVe": 3611, "apiUrl": "/youtubei/v1/browse" } }, "browseEndpoint": { "browseId": "UC-bOAxx-YOsviSmqh8COR0w", "canonicalBaseUrl": "/user/1492tiger" } } } ] }, "publishedTimeText": {"simpleText": "10 か月前"}, "viewCountText": {"simpleText": "15,777 回視聴"}, "lengthText": { "accessibility": { "accessibilityData": { "label": "50 分 7 秒" } }, "simpleText": "50:07" }, "navigationEndpoint": { "clickTrackingParams": "CIoBEKQwGAMiEwjWjOPU4a30AhWQ50wCHXOEAjcyB3JlbGF0ZWRIwuDbnMXOmuR1mgEFCAEQ-B0=", "commandMetadata": { "webCommandMetadata": { "url": "/watch?v=qSHlXcSces8", "webPageType": "WEB_PAGE_TYPE_WATCH", "rootVe": 3832 } }, "watchEndpoint": { "videoId": "qSHlXcSces8", "nofollow": true, "watchEndpointSupportedOnesieConfig": { "html5PlaybackOnesieConfig": { "commonConfig": { "url": "https://r6---sn-nvoxu-ioqr.googlevideo.com/initplayback?source=youtube&orc=1&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odeak=1&odepv=1&osfc=1&ip=118.237.39.228&id=a921e55dc49c7acf&initcwndbps=977500&mt=1637645337&oweuc=&pxtags=Cg4KAnR4EggyNDAyNzcwMQ&rxtags=Cg4KAnR4EggyNDAyNzY5OQ%2CCg4KAnR4EggyNDAyNzcwMA%2CCg4KAnR4EggyNDAyNzcwMQ%2CCg4KAnR4EggyNDAyNzcwMg%2CCg4KAnR4EggyNDA2Nzg1NA" } } } } }, "shortBylineText": { "runs": [ { "text": "【とらゼミ】トラハックのエンジニア学習講座", "navigationEndpoint": { "clickTrackingParams": "CIoBEKQwGAMiEwjWjOPU4a30AhWQ50wCHXOEAjcyB3JlbGF0ZWQ=", "commandMetadata": { "webCommandMetadata": { "url": "/user/1492tiger", "webPageType": "WEB_PAGE_TYPE_CHANNEL", "rootVe": 3611, "apiUrl": "/youtubei/v1/browse" } }, "browseEndpoint": { "browseId": "UC-bOAxx-YOsviSmqh8COR0w", "canonicalBaseUrl": "/user/1492tiger" } } } ] }, "channelThumbnail": { "thumbnails": [ { "url": "https://yt3.ggpht.com/ytc/AKedOLRza-gyGwvrXtsX35ZaWK-GlQM05E7uy2xy3iFB=s68-c-k-c0x00ffffff-no-rj", "width": 68, "height": 68 } ] }, "trackingParams": "CIoBEKQwGAMiEwjWjOPU4a30AhWQ50wCHXOEAjdAz_XxpNyr-ZCpAQ==", "shortViewCountText": { "accessibility": { "accessibilityData": { "label": "1.5万 回視聴" } }, "simpleText": "1.5万 回視聴" }, "menu": { "menuRenderer": { "items": [ { "menuServiceItemRenderer": { "text": {"runs": [{"text": "キューに追加"}]}, "icon": {"iconType": "ADD_TO_QUEUE_TAIL"}, "serviceEndpoint": { "clickTrackingParams": "CI0BEP6YBBgFIhMI1ozj1OGt9AIVkOdMAh1zhAI3", "commandMetadata": {"webCommandMetadata": {"sendPost": true}}, "signalServiceEndpoint": { "signal": "CLIENT_SIGNAL", "actions": [ { "clickTrackingParams": "CI0BEP6YBBgFIhMI1ozj1OGt9AIVkOdMAh1zhAI3", "addToPlaylistCommand": { "openMiniplayer": false, "openListPanel": true, "videoId": "qSHlXcSces8", "listType": "PLAYLIST_EDIT_LIST_TYPE_QUEUE", "onCreateListCommand": { "clickTrackingParams": "CI0BEP6YBBgFIhMI1ozj1OGt9AIVkOdMAh1zhAI3", "commandMetadata": { "webCommandMetadata": { "sendPost": true, "apiUrl": "/youtubei/v1/playlist/create" } }, "createPlaylistServiceEndpoint": {"videoIds": ["qSHlXcSces8"], "params": "CAQ%3D"} }, "videoIds": ["qSHlXcSces8"] } }, { "clickTrackingParams": "CI0BEP6YBBgFIhMI1ozj1OGt9AIVkOdMAh1zhAI3", "openPopupAction": { "popup": { "notificationActionRenderer": { "responseText": {"simpleText": "キューに追加しました"}, "trackingParams": "CI4BELlqIhMI1ozj1OGt9AIVkOdMAh1zhAI3" } }, "popupType": "TOAST" } } ] } }, "trackingParams": "CI0BEP6YBBgFIhMI1ozj1OGt9AIVkOdMAh1zhAI3" } } ], "trackingParam": "" } } } } ``` -------------------------------- ### YouTube UI Tooltip Example Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html Demonstrates a tooltip element in the YouTube UI, including its text, position, and dismissal strategy. The tooltip text is in Japanese. ```json { "tooltip": { "uiActions": { "hideEnclosingContainer": true } }, "targetId": "create-clip-button-action-bar", "text": { "runs": [ { "text": "クリップ作成" } ] }, "detailsText": { "runs": [ { "text": "この動画の 5~60 秒の部分を他のユーザーと共有できます" } ] }, "suggestedPosition": { "type": "TOOLTIP_POSITION_TYPE_BELOW" }, "dismissStrategy": { "type": "TOOLTIP_DISMISS_TYPE_TAP_ANYWHERE" }, "dwellTimeMs": "5000", "trackingParams": "CBoQvJkCIhMI1ozj1OGt9AIVkOdMAh1zhAI3" } ``` -------------------------------- ### YouTube Chat Fetching Library Setup and Usage Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html This snippet demonstrates how to set up and use the YouTube chat fetching library. It covers basic initialization and how to retrieve chat messages from a live stream. Dependencies include Node.js and TypeScript. ```typescript import YouTubeChat from 'youtube-chat'; const CHAT_ID = 'dchqdFOW8EI'; // Replace with your YouTube video/live chat ID const chat = new YouTubeChat(CHAT_ID); chat.on('chat', (chat) => { console.log(`New chat message: ${chat.message}`); }); chat.on('error', (error) => { console.error('Error fetching chat:', error); }); // To stop fetching chat messages: // chat.stop(); ``` -------------------------------- ### YouTube Player Initialization Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html This JavaScript code snippet demonstrates how to initialize the YouTube player on a web page. It sets up necessary configurations and calls the player creation function. ```javascript window.ytplayer = window.ytplayer || {} window.ytplayer.bootstrapPlayerContainer = document.getElementById('player-api') window.ytplayer.bootstrapWebPlayerContextConfig = window.yt && window.yt.config_ && window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS && window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS['WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH'] window.ytplayer.bootstrapPlayerResponse = window['ytInitialPlayerResponse']; (function playerBootstrap() { if (window.ytplayer.bootstrapPlayerContainer && window.ytplayer.bootstrapWebPlayerContextConfig) { var createPlayer = window.yt && window.yt.player && window.yt.player.Application && (window.yt.player.Application.createAlternate || window.yt.player.Application.create) if (createPlayer) { if (window.ytplayer.bootstrapPlayerResponse) { window.ytplayer.config = {args: {raw_player_response: window.ytplayer.bootstrapPlayerResponse}} if (window.ytcsi) window.ytcsi.tick('cfg', null, '') } createPlayer(window.ytplayer.bootstrapPlayerContainer, window.ytplayer.config, window.ytplayer.bootstrapWebPlayerContextConfig) } } })() ytplayer.load = function() { throw new Error('Unexpected call to ytplayer.load.') } ``` -------------------------------- ### Node.js YouTube Chat Example Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/replay_page.html Example of fetching YouTube chat data using Node.js and TypeScript. This snippet demonstrates how to interact with YouTube's API to retrieve chat information. ```javascript import axios from 'axios'; async function getYouTubeChat(videoId) { const apiUrl = `https://www.youtube.com/watch?v=${videoId}`; try { const response = await axios.get(apiUrl); // Process the response to extract chat data console.log('Successfully fetched YouTube page.'); // Example: Extracting video title from the response const videoTitleMatch = response.data.match(//); if (videoTitleMatch && videoTitleMatch[1]) { console.log('Video Title:', videoTitleMatch[1]); } // Further parsing would be needed to extract actual chat messages } catch (error) { console.error('Error fetching YouTube chat:', error); } } // Example usage: // getYouTubeChat('dchqdFOW8EI'); ``` -------------------------------- ### YouTube Polymer Ready Event Handling Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/replay_page.html This JavaScript code defines a handler for the 'PolymerReady' event, which is crucial for initializing components after the Polymer framework is ready. It removes the event listener and logs a performance tick. If Polymer is not immediately available, it sets up an event listener for 'script-load-dpj'. ```javascript var onPolymerReady = function(e) {window.removeEventListener('script-load-dpj', onPolymerReady); if (window.ytcsi) {window.ytcsi.tick('apr', null, '');} }; if (window.Polymer && Polymer.RenderStatus) {onPolymerReady();} else {window.addEventListener('script-load-dpj', onPolymerReady);} ``` -------------------------------- ### YouTube Player Bootstrap Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/replay_page.html Initializes and bootstraps the YouTube player by setting up necessary DOM elements, configurations, and player responses. It checks for the existence of required elements and functions before creating the player instance. ```javascript window.ytplayer = window.ytplayer || {}; window.ytplayer.bootstrapPlayerContainer = document.getElementById('player-api'); window.ytplayer.bootstrapWebPlayerContextConfig = window.yt && window.yt.config_ && window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS && window.yt.config_.WEB_PLAYER_CONTEXT_CONFIGS['WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH']; window.ytplayer.bootstrapPlayerResponse = window['ytInitialPlayerResponse'];(function playerBootstrap(){if(window.ytplayer.bootstrapPlayerContainer&&window.ytplayer.bootstrapWebPlayerContextConfig){var createPlayer=window.yt&&window.yt.player&&window.yt.player.Application&&(window.yt.player.Application.createAlternate||window.yt.player.Application.create);if(createPlayer){if(window.ytplayer.bootstrapPlayerResponse){window.ytplayer.config={args:{raw_player_response:window.ytplayer.bootstrapPlayerResponse}};if(window.ytcsi)window.ytcsi.tick("cfg",null,"")}createPlayer(window.ytplayer.bootstrapPlayerContainer, window.ytplayer.config,window.ytplayer.bootstrapWebPlayerContextConfig)}}})();ytplayer.load=function(){throw new Error("Unexpected call to ytplayer.load.");}; ``` -------------------------------- ### Python Data Processing Example Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/no_live_page.html A Python example illustrating how to process extracted YouTube data. This code snippet shows basic data manipulation and could be extended for more complex analysis or integration with other services. ```python def process_youtube_data(video_data): video_id = video_data.get('videoId') title = video_data.get('title', {}).get('simpleText') views = video_data.get('viewCountText', {}).get('simpleText') channel = video_data.get('shortBylineText', {}).get('runs', [{}])[0].get('text') print(f"Video ID: {video_id}") print(f"Title: {title}") print(f"Views: {views}") print(f"Channel: {channel}") # Example usage: # youtube_data = {...} # Your extracted JSON data # process_youtube_data(youtube_data) ``` -------------------------------- ### YouTube Client Configuration Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html This snippet outlines various configuration parameters for the YouTube client, including settings for response parsing, web context, data synchronization, and feature experiments. It also includes API keys and URLs for related services. ```javascript response_parsing=true&web_yt_config_context=true&woffle_relinquish_lock_on_inactivity=true&www_for_videostats=true&ytidb_fetch_datasync_ids_for_data_cleanup=true&ytidb_is_supported_cache_success_result=true&ytidb_remake_db_enable_backoff_delay=true&ytidb_remake_db_retries=3&ytidb_stop_transaction_commit=true&ytidb_transaction_ended_event_rate_limit=0.02', 'disableFullscreen': true, 'cspNonce': '5MlFJ+pmX7y551oBskmoAA', 'canaryState': 'none', 'datasyncId': 'DPufGtSe6s4||', }, }, 'XSRF_FIELD_NAME': 'session_token', 'XSRF_TOKEN': 'QUFFLUhqbXgyZ0hySVhUbnB3R1RmUW1EMlZKNWZYR05TQXxBQ3Jtc0tuSmFyZXI1S2oyMng3N0FmSExScFJxaF8xdHJ1dklYWWxFUEFiRWFzdjBhSGV4aTFhaGNyQ2V1UUtqV1lxZkRUVl9kUzA5Y2gwb3VtMEVHak40VlVNSkpxT01PdVEtZFljWjZfN3MtT3gzbDZwU3FFWQ==', 'YPC_MB_URL': 'https://payments.youtube.com/payments/v4/js/integrator.js?ss=md', 'YTR_FAMILY_CREATION_URL': 'https://families.google.com/webcreation?usegapi=1', 'SERVER_VERSION': 'prod', 'REUSE_COMPONENTS': true, 'STAMPER_STABLE_LIST': true, 'DATASYNC_ID': 'DPufGtSe6s4||', 'SERIALIZED_CLIENT_CONFIG_DATA': 'CIr78YwGEJTqrQUQt8utBRCw1K0FEJHprQUQ7sT9EhCR-PwSENi-rQU%3D', 'LIVE_CHAT_BASE_TANGO_CONFIG': { 'apiKey': 'AIzaSyDZNkyC-AtROwMBpLfevIvqYk-Gfi8ZOeo', 'channelUri': 'https://client-channel.google.com/client-channel/client', 'clientName': 'yt-live-comments', 'requiresAuthToken': true, 'senderUri': 'https://clients4.google.com/invalidation/lcs/client', 'useNewTango': true, }, 'FEXP_EXPERIMENTS': [23983296, 23986025, 24001373, 24002022, 24002025, 24004644, 24007246, 24027701, 24064555, 24080738, 24082661, 24106628, 24113538, 24115508, 24115586, 24116772, 24118516, 24129402, 24129452, 24129776, 24131277, 24132435, 24136255, 24137390], 'LIVE_CHAT_SEND_MESSAGE_ACTION': 'live_chat/watch_page/send', 'ROOT_VE_TYPE': 3832, 'CLIENT_PROTOCOL': 'HTTP/1.1', 'CLIENT_TRANSPORT': 'tcp', 'VISIBILITY_TIME_BETWEEN_JOBS_MS': 100, 'START_IN_THEATER_MODE': false, 'START_IN_FULL_WINDOW_MODE': false, 'SERVICE_WORKER_PROMPT_NOTIFICATIONS': true, 'SBOX_LABELS': {'SUGGESTION_DISMISS_LABEL': '削除', 'SUGGESTION_DISMISSED_LABEL': '候補を非表示にしました'}, 'ONE_PICK_URL': '', 'NO_EMPTY_DATA_IMG': true, 'MENTIONS_EDU_HELP_LINK': 'https://support.google.com/youtube/?p=creator_community', 'IS_WATCH_PAGE_COLD': true, 'DEFERRED_DETACH': true, 'ZWIEBACK_PING_URLS': ['https://www.google.com/pagead/lvz?evtid=AKB78cikSaJCKHFYnYbwelh2I51kfNxHnFQo5ZlT5PiDMCFPFFG2W4q-pJQdImetJwvNO1Gh7elcHZe7Mo4H4yKDnU1K8Wrixg&req_ts=1637645706&pg=MainAppBootstrap%3AChannels&az=1&sigh=AKFpyYVVqrno-SO6remRs_Kl0r4c-7HEFQ', 'https://www.google.co.jp/pagead/lvz?evtid=AKB78cikSaJCKHFYnYbwelh2I51kfNxHnFQo5ZlT5PiDMCFPFFG2W4q-pJQdImetJwvNO1Gh7elcHZe7Mo4H4yKDnU1K8Wrixg&req_ts=1637645706&pg=MainAppBootstrap%3AChannels&az=1&sigh=AKFpyYVVqrno-SO6remRs_Kl0r4c-7HEFQ'], 'VOZ_API_KEY': 'AIzaSyBU2xE_JHvB6wag3tMfhxXpg2Q_W8xnM-I', 'STS': 18952, 'SBOX_SETTINGS': { 'HAS_ON_SCREEN_KEYBOARD': false, 'IS_FUSION': false, 'IS_POLYMER': true, 'REQUEST_DOMAIN': 'jp', 'REQUEST_LANGUAGE': 'ja', 'SEND_VISITOR_DATA': true, 'SEARCHBOX_BEHAVIOR_EXPERIMENT': 'zero-prefix', 'SEARCHBOX_ENABLE_REFINEMENT_SUGGEST': true, 'SEARCHBOX_TAP_TARGET_EXPERIMENT': 0, 'SEARCHBOX_ZERO_TYPING_SUGGEST_USE_REGULAR_SUGGEST': 'always', 'SUGG_EXP_ID': 'ytsem2bce,rankembed.ruyteb=1,rankembed.oydiw=0,cfro=1', 'VISITOR_DATA': 'CgtEUHVmR3RTZTZzNCiK-_GMBg%3D%3D', 'SEARCHBOX_HOST_OVERRIDE': 'suggestqueries-clients6.youtube.com', 'HIDE_REMOVE_LINK': false, }, 'SBOX_JS_URL': 'https://www.youtube.com/s/desktop/c3755e48/jsbin/www-searchbox.vflset/www-searchbox.js', 'RECAPTCHA_V3_SITEKEY': '6LedoOcUAAAAAHA4CFG9zRpaCNjYj33SYjzQ9cTy', 'PLAYER_JS_URL': '/s/player/4c89207b/player_ias.vflset/ja_JP/base.js', 'PLAYER_CSS_URL': '/s/player/4c89207b/www-player.css', 'LINK_GAL_DOMAIN': 'https://accountlinking-pa-clients6.youtube.com', 'LINK_OIS_DOMAIN': 'oauthintegrations-clients6.youtube.com', 'IS_TABLET': false, 'LINK_API_KEY': 'AIzaSyDophAQuyyiBr8h0nypEwXUKozH-BEswD0', 'DISABLE_WARM_LOADS': false, } ``` -------------------------------- ### Video Metadata Example Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html This snippet shows an example of metadata extracted for a YouTube video, including its title, view count, and publication time. It is part of a larger dataset likely used for analyzing YouTube content. ```json { "videoId": "lFbsR2lAEDE", "thumbnail": { "thumbnails": [ { "url": "https://i.ytimg.com/vi/lFbsR2lAEDE/hqdefault.jpg?sqp=-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLBcyz1DrOqhNMdHB_eQBjBNjxIZjw", "width": 168, "height": 94 }, { "url": "https://i.ytimg.com/vi/lFbsR2lAEDE/hqdefault.jpg?sqp=-oaymwEiCMQBEG5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ==&rs=AOn4CLDaPQhTUTYpBxcwB0w7Ss550swALw", "width": 196, "height": 110 }, { "url": "https://i.ytimg.com/vi/lFbsR2lAEDE/hqdefault.jpg?sqp=-oaymwEjCPYBEIoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLD7oSCjh5yB3G8tTWhM47lndJ82TQ", "width": 246, "height": 138 }, { "url": "https://i.ytimg.com/vi/lFbsR2lAEDE/hqdefault.jpg?sqp=-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE=&rs=AOn4CLBbCfK4ExiDlu8-n13P2j0Is0Y9Ww", "width": 336, "height": 188 } ] }, "title": { "accessibility": { "accessibilityData": { "label": "[RFA] ボディ・リファクタリング アクセラレーション・ブースト [リングフィット] 作成者: 創好リナ [バーチャルイキリプログラマ] 8 か月前 に配信済み 42 分 18 回視聴" }, "simpleText": "[RFA] ボディ・リファクタリング アクセラレーション・ブースト [リングフィット]" }, "simpleText": "[RFA] ボディ・リファクタリング アクセラレーション・ブースト [リングフィット]" }, "shortBylineText": { "runs": [ { "text": "創好リナ [バーチャルイキリプログラマ]", "navigationEndpoint": { "clickTrackingParams": "CCcQvU4YBiITCNaM49ThrfQCFZDnTAIdc4QCNw==", "commandMetadata": { "webCommandMetadata": { "url": "/channel/UCxkOLgdNumvVIQqn5ps_bJA", "webPageType": "WEB_PAGE_TYPE_CHANNEL", "rootVe": 3611, "apiUrl": "/youtubei/v1/browse" } }, "browseEndpoint": { "browseId": "UCxkOLgdNumvVIQqn5ps_bJA", "canonicalBaseUrl": "/channel/UCxkOLgdNumvVIQqn5ps_bJA" } } } ] }, "lengthText": { "accessibility": { "accessibilityData": { "label": "42 分 2 秒" }, "simpleText": "42:02" }, "simpleText": "42:02" }, "lengthInSeconds": 2522, "navigationEndpoint": { "clickTrackingParams": "CCcQvU4YBiITCNaM49ThrfQCFZDnTAIdc4QCNzIJZW5kc2NyZWVuSMLg25zFzprkdZoBBQgCEPgd", "commandMetadata": { "webCommandMetadata": { "url": "/watch?v=lFbsR2lAEDE", "webPageType": "WEB_PAGE_TYPE_WATCH", "rootVe": 3832 } }, "watchEndpoint": { "videoId": "lFbsR2lAEDE", "watchEndpointSupportedOnesieConfig": { "html5PlaybackOnesieConfig": { "commonConfig": { "url": "https://r4---sn-nvoxu-ioqr.googlevideo.com/initplayback?source=youtube&orc=1&oeis=1&c=WEB&oad=3200&ovd=3200&oaad=11000&oavd=11000&ocs=700&oewis=1&oputc=1&ofpcc=1&msp=1&odeak=1&odepv=1&osfc=1&ip=118.237.39.228&id=9456ec4769401031&initcwndbps=977500&mt=1637645337&oweuc=&pxtags=Cg4KAnR4EggyNDAyNzcwMQ&rxtags=Cg4KAnR4EggyNDAyNzY5OQ%2CCg4KAnR4EggyNDAyNzcwMA%2CCg4KAnR4EggyNDAyNzcwMQ%2CCg4KAnR4EggyNDAyNzcwMg%2CCg4KAnR4EggyNDA2Nzg1NA" } } } } }, "trackingParams": "CCcQvU4YBiITCNaM49ThrfQCFZDnTAIdc4QCNw==", "shortViewCountText": { "accessibility": { "accessibilityData": { "label": "18 回視聴" }, "simpleText": "18 回視聴" }, "simpleText": "18 回視聴" }, "publishedTimeText": { "simpleText": "8 か月前 に配信済み" }, "thumbnailOverlays": [ { "thumbnailOverlayTimeStatusRenderer": { "text": { "accessibility": { "accessibilityData": { "label": "42 分 2 秒" }, "simpleText": "42:02" }, "simpleText": "42:02" }, "style": "DEFAULT" } }, { "thumbnailOverlayNowPlayingRenderer": { "text": { "runs": [ { "text": "再生中" } ] } } } ] } ``` -------------------------------- ### YouTube Configuration and Experiment Flags Source: https://github.com/linatsukusu/youtube-chat/blob/develop/test/testdata/live-page.html Handles loading YouTube's configuration data and experiment flags. It prioritizes specific configuration sources and provides a way to access experiment flags, with fallback mechanisms. ```javascript var P, Q, R, S = y.window, T = (null === (P = null === S || void 0 === S ? void 0 : S.yt) || void 0 === P ? void 0 : P.config_) || (null === (Q = null === S || void 0 === S ? void 0 : S.ytcfg) || void 0 === Q ? void 0 : Q.data_) || {}, pa = (null === (R = null === S || void 0 === S ? void 0 : S.ytcfg) || void 0 === R ? void 0 : R.obfuscatedData_) || [] function qa() { O.apply(this, arguments) } w(qa, O) new qa(pa) z('yt.config_', T) z('yt.configJspb_', pa) function ra(a) { var b = {} return a in T ? T[a] : b } function U(a) { a = sa(a); return 'string' === typeof a && 'false' === a ? !1 : !!a } function sa(a) { var b = ra('EXPERIMENTS_FORCED_FLAGS'); return void 0 !== b[a] ? b[a] : ra('EXPERIMENT_FLAGS')[a] } ```