diff --git a/lib/info.js b/lib/info.js index e514b067..b5f54573 100644 --- a/lib/info.js +++ b/lib/info.js @@ -41,9 +41,17 @@ const AGE_RESTRICTED_URLS = [ */ exports.getBasicInfo = async(id, options) => { const retryOptions = Object.assign({}, miniget.defaultOptions, options.requestOptions); - const isValid = info => - info.player_response && (info.player_response.streamingData || isRental(info.player_response)); - let info = await pipeline([id, options], retryOptions, isValid, [ + const validate = info => { + let playErr = utils.playError(info.player_response, ['ERROR'], UnrecoverableError); + let privateErr = privateVideoError(info.player_response); + if (playErr || privateErr) { + throw playErr || privateErr; + } + return info && ( + info.player_response.streamingData || isRental(info.player_response) || isNotYetBroadcasted(info.player_response) + ); + }; + let info = await pipeline([id, options], validate, retryOptions, [ getJSONWatchPage, getEmbedPage, getVideoInfoPage, @@ -75,8 +83,8 @@ exports.getBasicInfo = async(id, options) => { }; const privateVideoError = player_response => { - let playability = player_response.playabilityStatus; - if (playability.status === 'LOGIN_REQUIRED' && playability.messages && + let playability = player_response && player_response.playabilityStatus; + if (playability && playability.status === 'LOGIN_REQUIRED' && playability.messages && playability.messages.filter(m => /This is a private video/.test(m)).length) { return new UnrecoverableError(playability.reason || (playability.messages && playability.messages[0])); } else { @@ -91,6 +99,12 @@ const isRental = player_response => { }; +const isNotYetBroadcasted = player_response => { + let playability = player_response.playabilityStatus; + return playability && playability.status === 'LIVE_STREAM_OFFLINE'; +}; + + const getHTMLWatchURL = (id, options) => `${VIDEO_URL + id}&hl=${options.lang || 'en'}`; const getHTMLWatchPageBody = (id, options) => { const url = getHTMLWatchURL(id, options); @@ -122,12 +136,12 @@ const getIdentityToken = (id, options, key, throwIfNotFound) => * If unable to succeed with one endpoint, moves onto the next one. * * @param {Array.} args + * @param {Function} validate * @param {Object} retryOptions - * @param {Function} isValid * @param {Array.} endpoints * @returns {[Object, Object, Object]} */ -const pipeline = async(args, retryOptions, isValid, endpoints) => { +const pipeline = async(args, validate, retryOptions, endpoints) => { let info; for (let func of endpoints) { try { @@ -137,7 +151,7 @@ const pipeline = async(args, retryOptions, isValid, endpoints) => { newInfo.player_response.videoDetails); newInfo.player_response = assign(info && info.player_response, newInfo.player_response); info = assign(info, newInfo); - if (isValid(info)) { + if (validate(info, false)) { break; } } catch (err) { @@ -257,12 +271,6 @@ const getJSONWatchPage = async(id, options) => { info.player_response = findPlayerResponse('watch.json `player_response`', info); info.html5player = info.player && info.player.assets && info.player.assets.js; - let playErr = utils.playError(info.player_response, ['ERROR'], UnrecoverableError); - let privateErr = privateVideoError(info.player_response); - if (playErr || privateErr) { - throw playErr || privateErr; - } - return info; }; diff --git a/lib/utils.js b/lib/utils.js index 86951c5e..977a5bb3 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -111,7 +111,7 @@ exports.cutAfterJSON = mixedJson => { * @returns {!Error} */ exports.playError = (player_response, statuses, ErrorType = Error) => { - let playability = player_response.playabilityStatus; + let playability = player_response && player_response.playabilityStatus; if (playability && statuses.includes(playability.status)) { return new ErrorType(playability.reason || (playability.messages && playability.messages[0])); } diff --git a/test/files/refresh.js b/test/files/refresh.js index 541a1587..414beda9 100644 --- a/test/files/refresh.js +++ b/test/files/refresh.js @@ -64,7 +64,7 @@ const videos = [ { id: '_HSylqgVYQI', type: 'regular', - keep: ['video.flv', 'watch-reload-now.json', 'watch-reload-now-2.json', 'watch-empty.json'], + keep: ['video.flv', 'watch-reload-now.json', 'watch-reload-now-2.json'], saveInfo: true, transform: [ { @@ -132,7 +132,7 @@ const videos = [ 'x-youtube-client-version': '0', }, } }, - keep: ['embed-player-vars.html', 'watch-backup.html', 'watch-reload-now.json'], + keep: ['embed-player-vars.html', 'watch-backup.html', 'watch-reload-now.json', 'watch-empty.json'], transform: [ { page: 'embed.html', diff --git a/test/files/videos/regular/watch-empty.json b/test/files/videos/embed-backup/watch-empty.json similarity index 100% rename from test/files/videos/regular/watch-empty.json rename to test/files/videos/embed-backup/watch-empty.json diff --git a/test/files/videos/live-future/embed.html b/test/files/videos/live-future/embed.html deleted file mode 100644 index a6f5a1ad..00000000 --- a/test/files/videos/live-future/embed.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Join Dr. Berg for a lively discussion on KETO and Intermittent Fasting this Friday at 11:00 AM EST - YouTube - - - - - - -
- \ No newline at end of file diff --git a/test/files/videos/live-future/get_video_info b/test/files/videos/live-future/get_video_info deleted file mode 100644 index 390ce736..00000000 --- a/test/files/videos/live-future/get_video_info +++ /dev/null @@ -1 +0,0 @@ -root_ve_type=27240&use_miniplayer_ui=1&cr=US&csi_page_type=embed&innertube_api_version=v1&vss_host=s.youtube.com&fexp=23735347%2C23744176%2C23804281%2C23839597%2C23853952%2C23856950%2C23857950%2C23868333%2C23880043%2C23882503%2C23884386%2C23885572%2C23890959%2C23895671%2C23911055%2C23914483%2C23915990%2C23918597%2C23921553%2C23928508%2C23934970%2C23942338%2C23942633%2C23942769%2C23944779%2C23945480%2C23946420%2C23947680%2C23948841%2C23948944%2C23948944%2C23950597%2C23951139%2C23954761%2C23955862%2C23958692%2C23958803%2C23961290%2C23961732%2C23962662%2C23963837%2C23964179%2C23964949%2C23965505%2C23965755%2C24590289%2C24631715%2C9449243&fflags=html5_remove_not_servable_check_killswitch%3Dtrue%26html5_quality_cap_min_age_secs%3D0%26html5_unrewrite_timestamps%3Dtrue%26html5_subsegment_readahead_target_buffer_health_secs%3D0.5%26hoffle_cache_size_secs%3D0%26html5_decoder_freeze_timeout_delay_ms%3D0%26html5_default_quality_cap%3D0%26html5_minimum_readahead_seconds%3D0.0%26network_polling_interval%3D30000%26tvhtml5_disable_live_prefetch%3Dtrue%26html5_enable_embedded_player_visibility_signals%3Dtrue%26html5_gl_fps_threshold%3D0%26web_player_music_visualizer_treatment%3Dfake%26enable_ve_tracker_key%3Dtrue%26live_chunk_readahead%3D3%26self_podding_header_string_template%3Dself_podding_interstitial_message%26hide_preskip%3Dtrue%26web_player_live_monitor_env_killswitch%3Dtrue%26html5_gapless_preloading%3Dtrue%26html5_ios_force_seek_to_zero_on_stop%3Dtrue%26html5_player_dynamic_bottom_gradient%3Dtrue%26gvi_channel_client_screen%3Dtrue%26web_client_version_override%3D%26disable_legacy_desktop_remote_queue%3Dtrue%26html5_expanded_max_vss_pings%3Dtrue%26web_client_counter_random_seed%3Dtrue%26html5_performance_cap_floor%3D360%26html5_log_live_discontinuity%3Dtrue%26html5_request_size_padding_secs%3D3.0%26html5_hack_gapless_init%3Dtrue%26should_clear_video_data_on_player_cued_unstarted%3Dtrue%26html5_max_headm_for_streaming_xhr%3D0%26html5_autonav_cap_idle_secs%3D0%26html5_av1_thresh_hcc%3D1080%26html5_subsegment_readahead_load_speed_check_interval%3D0.5%26html5_subsegment_readahead_min_buffer_health_secs%3D0.25%26align_ad_to_video_player_lifecycle_for_bulleit%3Dtrue%26web_yt_config_context%3Dtrue%26html5_seek_set_cmt_delay_ms%3D2000%26html5_heartbeat_set_ended%3Dtrue%26html5_enable_per_format_loudness%3Dtrue%26use_player_params_for_passing_desktop_conversion_urls%3Dtrue%26html5_desktop_vr180_allow_panning%3Dtrue%26html5_bandwidth_window_size%3D0%26html5_live_normal_latency_bandwidth_window%3D0.0%26enable_eviction_protection_for_bulleit%3Dtrue%26kevlar_miniplayer%3Dtrue%26html5_experiment_id_label%3D0%26external_fullscreen_with_edu%3Dtrue%26set_interstitial_start_button%3Dtrue%26html5_stop_video_in_cancel_playback%3Dtrue%26use_video_ad_break_offset_ms_int64%3Dtrue%26autoplay_time_for_music_content%3D-1%26html5_min_upgrade_health%3D0%26web_player_watch_next_response%3Dtrue%26mdx_enable_privacy_disclosure_ui%3Dtrue%26self_podding_midroll_choice_string_template%3Dself_podding_midroll_choice%26html5_av1_thresh_lcc%3D480%26html5_random_playback_cap%3D0%26html5_live_abr_head_miss_fraction%3D0.0%26html5_unify_sqless_flow%3Dtrue%26web_wn_macro_markers%3Dtrue%26pair_servlet_deprecation_warning_enabled%3Dtrue%26html5_default_ad_gain%3D0.5%26music_enable_shared_audio_tier_logic%3Dtrue%26web_gel_debounce_ms%3D10000%26delay_gel_until_config_ready%3Dtrue%26html5_prefer_server_bwe3%3Dtrue%26log_js_error_clusters%3D1.0%26html5_deadzone_multiplier%3D1.0%26web_op_endpoint_banlist%3D%28%29%26web_macro_markers_snapping_threshold%3D4%26html5_new_element_on_invalid_state%3Dtrue%26html5_autoplay_default_quality_cap%3D0%26html5_source_buffer_attach_retry_limit%3D0%26html5_fludd_suspend%3Dtrue%26html5_ios7_force_play_on_stall%3Dtrue%26html5_pause_on_nonforeground_platform_errors%3Dtrue%26html5_new_elem_on_hidden%3Dtrue%26enable_client_page_id_header_for_first_party_pings%3Dtrue%26html5_unreported_seek_reseek_delay_ms%3D0%26web_player_watch_next_response_parsing%3Dtrue%26html5_gapless_seek_tolerance_secs%3D3.0%26html5_error_cooldown_in_ms%3D30000%26html5_manifestless_vp9_otf%3Dtrue%26ad_pod_disable_companion_persist_ads_quality%3Dtrue%26kevlar_miniplayer_expand_top%3Dtrue%26html5_min_readbehind_cap_secs%3D60%26html5_manifestless_media_source_duration%3D25200%26polymer_verifiy_app_state%3Dtrue%26web_player_ss_media_time_offset%3Dtrue%26html5_remove_pause%3Dfalse%26web_player_ios_mweb_resizing%3Dtrue%26html5_player_min_build_cl%3D-1%26self_podding_highlighted_button_blue%3Dtrue%26autoplay_time_for_music_content_after_autoplayed_video%3D-1%26web_op_continuation_type_banlist%3D%28%29%26web_player_icons%3Dtrue%26web_deprecate_service_ajax_map_dependency%3Dtrue%26web_player_innertube_share_panel%3Dtrue%26embeds_enable_embed_module%3Dtrue%26suppress_sparkles_for_whitelisted_instream_on_desktop%3Dtrue%26use_ivar_to_extract_ad_video_id%3Dtrue%26www_for_videostats%3Dtrue%26disable_simple_mixed_direction_formatted_strings%3Dtrue%26web_player_bigger_buttons%3Dtrue%26mweb_native_control_in_faux_fullscreen_shared%3Dtrue%26html5_time_based_consolidation_ms%3D10%26html5_log_experiment_id_from_player_response_to_ctmp%3D%26web_player_response_overlay_parsing%3Dfalse%26html5_log_playback_rate_change_killswitch%3Dtrue%26dash_manifest_version%3D5%26html5_disable_subscribe_new_vis%3Dtrue%26enable_svg_mode_on_embed_mobile%3Dtrue%26html5_subsegment_readahead_min_load_speed%3D1.5%26html5_aspect_from_adaptive_format%3Dtrue%26html5_hls_initial_bitrate%3D0%26allow_poltergust_autoplay%3Dtrue%26web_player_touch_mode_improvements%3Dtrue%26web_player_vss_pageid_header%3Dtrue%26botguard_async_snapshot_timeout_ms%3D3000%26csi_on_gel%3Dtrue%26fast_autonav_in_background%3Dtrue%26use_typescript_transport%3Dtrue%26html5_live_ultra_low_latency_bandwidth_window%3D0.0%26web_player_inline_botguard%3Dtrue%26html5_workaround_delay_trigger%3Dtrue%26html5_delay_initial_loading%3Dtrue%26web_player_innertube_subscription_update%3Dtrue%26html5_disable_preserve_reference%3Dtrue%26html5_jumbo_ull_subsegment_readahead_target%3D1.3%26variable_buffer_timeout_ms%3D0%26disable_new_pause_state3%3Dtrue%26use_inlined_player_rpc%3Dtrue%26html5_max_readbehind_secs%3D0%26html5_allow_video_keyframe_without_audio%3Dtrue%26render_enhanced_overlays_as_ctas_for_desktop_style%3Dunset%26html5_not_vp9_supported_quality_cap%3D0%26player_enable_playback_playlist_change%3Dtrue%26html5_probe_primary_delay_base_ms%3D0%26html5_set_ended_in_pfx_live%3Dtrue%26web_player_ipp_canary_type_for_logging%3D%26kabuki_pangea_prefer_audio_only_for_atv_and_uploads%3Dtrue%26html5_ios4_seek_above_zero%3Dtrue%26custom_csi_timeline_use_gel%3Dtrue%26networkless_throttle_timeout%3D100%26enable_live_premiere_web_player_indicator%3Dtrue%26html5_enable_eac3%3Dtrue%26html5_restrict_streaming_xhr_on_sqless_requests%3Dtrue%26delay_ads_gvi_call_on_bulleit_living_room_ms%3D0%26live_fresca_scheduled_persistent%3Dtrue%26desktop_player_button_tooltip_with_shortcut%3Dtrue%26web_logging_max_batch%3D150%26enable_client_deferred_full_screen_filtering_for_mweb_phones%3Dtrue%26web_player_live_monitor_env_killswitch2%3Dtrue%26kevlar_queue_use_update_api%3Dtrue%26html5_static_abr_resolution_shelf%3D0%26player_ads_set_adformat_on_client%3Dtrue%26html5_max_readahead_bandwidth_cap%3D0%26self_podding_highlight_non_default_button%3Dtrue%26html5_long_rebuffer_threshold_ms%3D30000%26manifestless_post_live_ufph%3Dtrue%26ensure_only_one_resolved_midroll_response_on_web%3Dtrue%26networkless_ytidb_version%3D1%26unplugged_tvhtml5_video_preload_on_focus_delay_ms%3D0%26html5_post_interrupt_readahead%3D20%26html5_disable_reset_on_append_error%3Dtrue%26html5_disable_non_contiguous%3Dtrue%26html5_maximum_readahead_seconds%3D0.0%26html5_gapless_error_check_killswitch%3Dtrue%26html5_seek_over_discontinuities%3Dtrue%26html5_jumbo_ull_nonstreaming_mffa_ms%3D4000%26html5_store_xhr_headers_readable%3Dtrue%26html5_max_drift_per_track_secs%3D0.0%26html5_hls_min_video_height%3D0%26html5_hdcp_probing_stream_url%3D%26enable_ad_pod_specific_ui%3Dtrue%26html5_inline_video_quality_survey%3Dtrue%26html5_live_abr_repredict_fraction%3D0.0%26max_resolution_for_white_noise%3D360%26html5_video_tbd_min_kb%3D0%26html5_log_timestamp_offset%3Dtrue%26html5_readahead_ratelimit%3D3000%26web_screen_associated_all_layers%3Dtrue%26suppress_error_204_logging%3Dtrue%26web_log_app_install_experiments%3Dtrue%26web_op_signal_type_banlist%3D%28%29%26disable_thumbnail_preloading%3Dtrue%26html5_license_constraint_delay%3D5000%26html5_av1_thresh_arm%3D240%26suppress_gen_204%3Dtrue%26html5_av1_thresh%3D1080%26mweb_muted_autoplay_animation%3Dshrink%26html5_health_to_gel%3Dtrue%26web_player_innertube_playlist_update%3Dtrue%26enable_ypc_clickwrap_on_living_room%3Dtrue%26web_gel_timeout_cap%3Dtrue%26html5_decode_to_texture_cap%3Dtrue%26web_player_include_innertube_commands%3Dtrue%26html5_release_on_error%3Dtrue%26botguard_eval_with_script_tag%3Dtrue%26html5_rewrite_manifestless_for_continuity%3Dtrue%26html5_long_rebuffer_jiggle_cmt_delay_ms%3D0%26html5_allowable_liveness_drift_chunks%3D2%26html5_gapless_ended_transition_buffer_ms%3D200%26player_destroy_old_version%3Dtrue%26fix_ads_tracking_for_swf_config_deprecation_mweb%3Dtrue%26html5_ignore_bad_bitrates%3Dtrue%26html5_av1_tv_killswitch%3Dtrue%26kevlar_allow_multistep_video_init%3Dtrue%26html5_perf_cap_override_sticky%3Dtrue%26kevlar_miniplayer_play_pause_on_scrim%3Dtrue%26player_doubletap_to_seek%3Dtrue%26live_fresca_v2%3Dtrue%26html5_sync_seeking_state%3Dtrue%26log_js_exceptions_fraction%3D1.0%26html5_autonav_quality_cap%3D0%26html5_probe_live_using_range%3Dtrue%26overwrite_polyfill_on_logging_lib_loaded%3Dtrue%26html5_probe_secondary_during_timeout_miss_count%3D2%26web_network_combined_catch%3Dtrue%26bulleit_get_midroll_info_timeout_ms%3D8000%26debug_sherlog_username%3D%26html5_request_sizing_multiplier%3D0.8%26polymer_bad_build_labels%3Dtrue%26web_player_show_music_in_this_video_graphic%3Dvideo_thumbnail%26html5_vp9_new_mime%3Dtrue%26mweb_cougar_big_controls%3Dtrue%26html5_live_quality_cap%3D0%26web_player_response_fairplay_config_killswitch%3Dtrue%26html5_reload_element_long_rebuffer_delay_ms%3D20000%26html5_peak_shave%3Dtrue%26mweb_enable_custom_control_shared%3Dtrue%26html5_ads_preroll_lock_timeout_delay_ms%3D0%26html5_manifestless_max_segment_history%3D0%26html5_manifestless_vp9%3Dtrue%26debug_dapper_trace_id%3D%26html5_license_server_error_retry_limit%3D3%26enable_device_forwarding_from_polymer_network_manager%3Dtrue%26html5_subsegment_readahead_min_buffer_health_secs_on_timeout%3D0.1%26self_podding_pod_choice_string_template%3Dself_podding_pod_choice%26html5_background_quality_cap%3D360%26html5_seek_jiggle_cmt_delay_ms%3D8000%26use_survey_skip_in_0s%3Dtrue%26html5_media_fullscreen%3Dtrue%26html5_ignore_start_seconds_for_ads_killswitch%3Dtrue%26html5_df_downgrade_thresh%3D0.2%26html5_jumbo_mobile_subsegment_readahead_target%3D3.0%26allow_live_autoplay%3Dtrue%26web_player_response_playback_tracking_parsing%3Dtrue%26html5_seek_new_elem_delay_ms%3D12000%26web_foreground_heartbeat_interval_ms%3D28000%26html5_subsegment_readahead_timeout_secs%3D2.0%26enable_topsoil_wta_for_halftime%3Dtrue%26html5_source_buffer_attach_delay_time%3D15000%26skip_ad_button_with_thumbnail%3Dtrue%26html5_live_low_latency_bandwidth_window%3D0.0%26html5_min_readbehind_secs%3D0%26player_allow_autonav_after_playlist%3Dtrue%26networkless_request_age_limit%3D30%26enable_mixed_direction_formatted_strings%3Dtrue%26web_player_ss_dai_ad_fetching_timeout_ms%3D5000%26html5_in_buffer_ptl_timeout_ms%3D0%26html5_max_live_dvr_window_plus_margin_secs%3D46800.0%26html5_manifestless_seg_drift_limit_secs%3D0%26bulleit_use_touch_events_for_skip%3Dtrue%26web_player_no_endscreen_crop%3Dtrue%26variable_load_timeout_ms%3D0%26html5_suspend_loader%3Dtrue%26manifestless_post_live%3Dtrue%26html5_disable_aac_ac3%3Dtrue%26hoffle_max_video_duration_secs%3D0%26web_player_sentinel_is_uniplayer%3Dtrue%26web_api_url%3Dtrue%26autoplay_time%3D8000%26kevlar_frontend_video_list_actions%3Dtrue%26web_player_live_monitor_env%3Dtrue%26html5_seek_timeout_delay_ms%3D20000%26html5_crypto_period_secs_from_emsg%3Dtrue%26web_player_api_logging_fraction%3D0.01%26use_remote_context_in_populate_remote_client_info%3Dtrue%26tvhtml5_unplugged_preload_cache_size%3D5%26web_log_connection%3Dtrue%26unplugged_tvhtml5_botguard_attestation%3Dtrue%26release_player_on_abandon_for_bulleit_lr_ads_frontend%3Dtrue%26html5_buffer_health_to_defer_slice_processing%3D0.0%26html5_gapless_max_played_ranges%3D12%26use_touch_events_for_bulleit_mweb%3Dtrue%26html5_encourage_array_coalescing%3Dtrue%26enable_kevlar_action_companion_cleanup%3Dtrue%26log_window_onerror_fraction%3D0.1%26html5_background_cap_idle_secs%3D60%26html5_qoe_intercept%3D%26kevlar_queue_use_dedicated_list_type%3Dtrue%26html5_log_rebuffer_events%3D5%26html5_hfr_quality_cap%3D0%26web_post_search%3Dtrue%26html5_gapless_no_requests_after_lock%3Dtrue%26html5_use_current_media_time_for_glrem_gllat%3Dtrue%26html5_gapless_ad_byterate_multiplier%3D1.6%26html5_qoe_user_intent_match_health%3Dtrue%26html5_ad_timeout_ms%3D0%26kevlar_playback_associated_queue%3Dtrue%26kevlar_gel_error_routing%3Dtrue%26kevlar_autonav_miniplayer_fix%3Dtrue%26html5_disable_move_pssh_to_moov%3Dtrue%26enable_device_forwarding_from_xhr_client%3Dtrue%26html5_safari_desktop_eme_min_version%3D0%26desktop_action_companion_wta_support%3Dtrue%26html5_subsegment_readahead_seek_latency_fudge%3D0.5%26networkless_retry_attempts%3D1%26html5_enable_ac3%3Dtrue%26html5_disable_extra_update_resource%3Dtrue%26mweb_enable_skippables_on_jio_phone%3Dtrue%26html5_restore_perf_cap%3Dfalse%26deprecate_pair_servlet_enabled%3Dtrue%26html5_player_autonav_logging%3Dtrue%26player_bootstrap_method%3Dtrue%26playready_first_play_expiration%3D-1%26player_web_canary_stage%3D0%26error_message_for_gsuite_network_restrictions%3Dtrue%26preskip_button_style_ads_backend%3Dcountdown_next_to_thumbnail%26html5_vp9_mime_full_range_flag%3Dtrue%26html5_platform_minimum_readahead_seconds%3D0.0%26html5_check_segnum_discontinuity%3Dtrue%26ignore_empty_xhr%3Dtrue%26enable_cookie_reissue_iframe%3Dtrue%26desktop_sparkles_light_cta_button%3Dtrue%26set_interstitial_advertisers_question_text%3Dtrue%26hfr_dropped_framerate_fallback_threshold%3D0%26html5_no_placeholder_rollbacks%3Dtrue%26html5_non_network_rebuffer_duration_ms%3D0%26html5_sticky_reduces_discount_by%3D0.0&player_response=%7B%22responseContext%22%3A%7B%22serviceTrackingParams%22%3A%5B%7B%22service%22%3A%22GFEEDBACK%22%2C%22params%22%3A%5B%7B%22key%22%3A%22is_viewed_live%22%2C%22value%22%3A%22False%22%7D%2C%7B%22key%22%3A%22logged_in%22%2C%22value%22%3A%220%22%7D%2C%7B%22key%22%3A%22e%22%2C%22value%22%3A%2223958692%2C23962662%2C23964179%2C23946420%2C23735347%2C24590289%2C23942338%2C23884386%2C23942633%2C23965755%2C23804281%2C23950597%2C23839597%2C23944779%2C23928508%2C23948841%2C23921553%2C23911055%2C23961732%2C1714256%2C23951139%2C23942769%2C23956754%2C23958803%2C23947680%2C23918597%2C23853952%2C23890959%2C23880043%2C23963837%2C23955862%2C23882503%2C23948944%2C23744176%2C23934970%2C23954761%2C23857950%2C23965505%2C23885572%22%7D%5D%7D%2C%7B%22service%22%3A%22CSI%22%2C%22params%22%3A%5B%7B%22key%22%3A%22c%22%2C%22value%22%3A%22WEB%22%7D%2C%7B%22key%22%3A%22cver%22%2C%22value%22%3A%222.20201102.01.00%22%7D%2C%7B%22key%22%3A%22yt_li%22%2C%22value%22%3A%220%22%7D%2C%7B%22key%22%3A%22GetPlayer_rid%22%2C%22value%22%3A%220xbfa934b350163b15%22%7D%5D%7D%2C%7B%22service%22%3A%22GUIDED_HELP%22%2C%22params%22%3A%5B%7B%22key%22%3A%22logged_in%22%2C%22value%22%3A%220%22%7D%5D%7D%2C%7B%22service%22%3A%22ECATCHER%22%2C%22params%22%3A%5B%7B%22key%22%3A%22client.version%22%2C%22value%22%3A%222.20201028%22%7D%2C%7B%22key%22%3A%22client.name%22%2C%22value%22%3A%22WEB%22%7D%5D%7D%5D%2C%22webResponseContextExtensionData%22%3A%7B%22hasDecorated%22%3Atrue%7D%7D%2C%22playabilityStatus%22%3A%7B%22status%22%3A%22LIVE_STREAM_OFFLINE%22%2C%22reason%22%3A%22This+live+event+will+begin+in+2+days.%22%2C%22playableInEmbed%22%3Atrue%2C%22liveStreamability%22%3A%7B%22liveStreamabilityRenderer%22%3A%7B%22videoId%22%3A%22VIBFo3Ti5vQ%22%2C%22offlineSlate%22%3A%7B%22liveStreamOfflineSlateRenderer%22%3A%7B%22scheduledStartTime%22%3A%221604678400%22%2C%22mainText%22%3A%7B%22runs%22%3A%5B%7B%22text%22%3A%22Live+in+%22%7D%2C%7B%22text%22%3A%222+days%22%7D%5D%7D%2C%22subtitleText%22%3A%7B%22simpleText%22%3A%22November+6%2C+8%3A00+AM+PST%22%7D%2C%22thumbnail%22%3A%7B%22thumbnails%22%3A%5B%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fdefault.jpg%3Fv%3D5f9f3271%22%2C%22width%22%3A120%2C%22height%22%3A90%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ%3D%3D%5Cu0026rs%3DAOn4CLB21XNMm0fupPnOmXr79v2Lfa5-CA%22%2C%22width%22%3A168%2C%22height%22%3A94%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEWCMQBEG5IWvKriqkDCQgBFQAAiEIYAQ%3D%3D%5Cu0026rs%3DAOn4CLBK5F24rQK8nRv0nmjDzS0y3KfeOQ%22%2C%22width%22%3A196%2C%22height%22%3A110%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE%3D%5Cu0026rs%3DAOn4CLAMKqt3E3lvJoNJFIGPTZsWLWAL5g%22%2C%22width%22%3A246%2C%22height%22%3A138%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fmqdefault.jpg%3Fv%3D5f9f3271%22%2C%22width%22%3A320%2C%22height%22%3A180%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE%3D%5Cu0026rs%3DAOn4CLDbgy-RVNNsGiU0nJ9PwangZfgYHg%22%2C%22width%22%3A336%2C%22height%22%3A188%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault.jpg%3Fv%3D5f9f3271%22%2C%22width%22%3A480%2C%22height%22%3A360%7D%5D%7D%7D%7D%2C%22pollDelayMs%22%3A%2215000%22%7D%7D%2C%22miniplayer%22%3A%7B%22miniplayerRenderer%22%3A%7B%22playbackMode%22%3A%22PLAYBACK_MODE_ALLOW%22%7D%7D%2C%22contextParams%22%3A%22Q0FFU0FnZ0M%3D%22%7D%2C%22videoDetails%22%3A%7B%22videoId%22%3A%22VIBFo3Ti5vQ%22%2C%22title%22%3A%22Join+Dr.+Berg+for+a+lively+discussion+on+KETO+and+Intermittent+Fasting+this+Friday+at+11%3A00+AM+EST%22%2C%22lengthSeconds%22%3A%220%22%2C%22channelId%22%3A%22UC3w193M5tYPJqF0Hi-7U-2g%22%2C%22isOwnerViewing%22%3Afalse%2C%22shortDescription%22%3A%22Take+Dr.+Berg%27s+Free+Keto+Mini-Course%3A+http%3A%2F%2Fpxlme.me%2F-i717vtY+or+go+here%3A+http%3A%2F%2Fbit.ly%2F2RmaFDS%5Cn%5CnBoron+Video%3A+https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DZWrMhU577SY%5Cn%5CnDownload+Keto+Essentials%5Cnhttp%3A%2F%2Fbit.ly%2F2DH0d6o%5Cn%5CnDr.+Eric+Berg+DC+Bio%3A%5CnDr.+Berg%2C+age+55%2C+is+a+chiropractor+who+specializes+in+Healthy+Ketosis+%5Cu0026+Intermittent+Fasting.+He+is+the+author+of+the+best-selling+book+The+Healthy+Keto+Plan%2C+and+is+the+Director+of+Dr.+Berg%E2%80%99s+Nutritionals.+He+no+longer+practices%2C+but+focuses+on+health+education+through+social+media.%5Cn%5CnDR.+BERG%27S+SHOP%3A+http%3A%2F%2Fshop.drberg.com%2F%5Cn%5CnFollow+us+on+FACEBOOK%3A+fb.me%2FDrEricBerg%5Cn%5CnSend+a+Message+to+his+team%3A+m.me%2FDrEricBerg%5Cn%5CnABOUT+DR.+BERG%3A+https%3A%2F%2Fwww.drberg.com%2Fdr-eric-berg%2Fbio%5Cn%5CnDisclaimer%3A%5CnDr.+Eric+Berg+received+his+Doctor+of+Chiropractic+degree+from+Palmer+College+of+Chiropractic+in+1988.++His+use+of+%E2%80%9Cdoctor%E2%80%9D+or+%E2%80%9CDr.%E2%80%9D+in+relation+to+himself+solely+refers+to+that+degree.++Dr.+Berg+is+a+licensed+chiropractor+in+Virginia%2C+California%2C+and+Louisiana%2C+but+he+no+longer+practices+chiropractic+in+any+state+and+does+not+see+patients+so+he+can+focus+on+educating+people+as+a+full+time+activity%2C+yet+he+maintains+an+active+license.+This+video+is+for+general+informational+purposes+only.++It+should+not+be+used+to+self-diagnose+and+it+is+not+a+substitute+for+a+medical+exam%2C+cure%2C+treatment%2C+diagnosis%2C+and+prescription+or+recommendation.++It+does+not+create+a+doctor-patient+relationship+between+Dr.+Berg+and+you.++You+should+not+make+any+change+in+your+health+regimen+or+diet+before+first+consulting+a+physician+and+obtaining+a+medical+exam%2C+diagnosis%2C+and+recommendation.++Always+seek+the+advice+of+a+physician+or+other+qualified+health+provider+with+any+questions+you+may+have+regarding+a+medical+condition.+The+Health+%5Cu0026+Wellness%2C+Dr.+Berg+Nutritionals+and+Dr.+Eric+Berg%2C+D.C.+are+not+liable+or+responsible+for+any+advice%2C+course+of+treatment%2C+diagnosis+or+any+other+information%2C+services+or+product+you+obtain+through+this+video+or+site.%22%2C%22isCrawlable%22%3Atrue%2C%22thumbnail%22%3A%7B%22thumbnails%22%3A%5B%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEiCKgBEF5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ%3D%3D%5Cu0026rs%3DAOn4CLBmEnrufOyeI_dv8_E7BPf_1LelwQ%22%2C%22width%22%3A168%2C%22height%22%3A94%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEiCMQBEG5IWvKriqkDFQgBFQAAAAAYASUAAMhCPQCAokN4AQ%3D%3D%5Cu0026rs%3DAOn4CLBn9C4gVeD3E_DGtcw3LriYekGotA%22%2C%22width%22%3A196%2C%22height%22%3A110%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEjCPYBEIoBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE%3D%5Cu0026rs%3DAOn4CLC-W92iFVC6IIp5qsJW8XQgQq5ZHA%22%2C%22width%22%3A246%2C%22height%22%3A138%7D%2C%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%3Fsqp%3DCJDFiP0F-oaymwEjCNACELwBSFryq4qpAxUIARUAAAAAGAElAADIQj0AgKJDeAE%3D%5Cu0026rs%3DAOn4CLDTJDOIK8vB4_U3qCx_fJMZb1ejaQ%22%2C%22width%22%3A336%2C%22height%22%3A188%7D%5D%7D%2C%22isUpcoming%22%3Atrue%2C%22averageRating%22%3A4.8518519%2C%22allowRatings%22%3Atrue%2C%22viewCount%22%3A%220%22%2C%22author%22%3A%22Dr.+Eric+Berg+DC%22%2C%22isLowLatencyLiveStream%22%3Afalse%2C%22isPrivate%22%3Afalse%2C%22isUnpluggedCorpus%22%3Afalse%2C%22latencyClass%22%3A%22MDE_STREAM_OPTIMIZATIONS_RENDERER_LATENCY_NORMAL%22%2C%22isLiveContent%22%3Atrue%7D%2C%22microformat%22%3A%7B%22playerMicroformatRenderer%22%3A%7B%22thumbnail%22%3A%7B%22thumbnails%22%3A%5B%7B%22url%22%3A%22https%3A%2F%2Fi.ytimg.com%2Fvi%2FVIBFo3Ti5vQ%2Fhqdefault_live.jpg%22%2C%22width%22%3A480%2C%22height%22%3A360%7D%5D%7D%2C%22embed%22%3A%7B%22iframeUrl%22%3A%22https%3A%2F%2Fwww.youtube.com%2Fembed%2FVIBFo3Ti5vQ%22%2C%22flashUrl%22%3A%22http%3A%2F%2Fwww.youtube.com%2Fv%2FVIBFo3Ti5vQ%3Fversion%3D3%5Cu0026autohide%3D1%22%2C%22width%22%3A480%2C%22height%22%3A360%2C%22flashSecureUrl%22%3A%22https%3A%2F%2Fwww.youtube.com%2Fv%2FVIBFo3Ti5vQ%3Fversion%3D3%5Cu0026autohide%3D1%22%7D%2C%22title%22%3A%7B%22simpleText%22%3A%22Join+Dr.+Berg+for+a+lively+discussion+on+KETO+and+Intermittent+Fasting+this+Friday+at+11%3A00+AM+EST%22%7D%2C%22description%22%3A%7B%22simpleText%22%3A%22Take+Dr.+Berg%27s+Free+Keto+Mini-Course%3A+http%3A%2F%2Fpxlme.me%2F-i717vtY+or+go+here%3A+http%3A%2F%2Fbit.ly%2F2RmaFDS%5Cn%5CnBoron+Video%3A+https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DZWrMhU577SY%5Cn%5CnDownload+Keto+Essentials%5Cnhttp%3A%2F%2Fbit.ly%2F2DH0d6o%5Cn%5CnDr.+Eric+Berg+DC+Bio%3A%5CnDr.+Berg%2C+age+55%2C+is+a+chiropractor+who+specializes+in+Healthy+Ketosis+%5Cu0026+Intermittent+Fasting.+He+is+the+author+of+the+best-selling+book+The+Healthy+Keto+Plan%2C+and+is+the+Director+of+Dr.+Berg%E2%80%99s+Nutritionals.+He+no+longer+practices%2C+but+focuses+on+health+education+through+social+media.%5Cn%5CnDR.+BERG%27S+SHOP%3A+http%3A%2F%2Fshop.drberg.com%2F%5Cn%5CnFollow+us+on+FACEBOOK%3A+fb.me%2FDrEricBerg%5Cn%5CnSend+a+Message+to+his+team%3A+m.me%2FDrEricBerg%5Cn%5CnABOUT+DR.+BERG%3A+https%3A%2F%2Fwww.drberg.com%2Fdr-eric-berg%2Fbio%5Cn%5CnDisclaimer%3A%5CnDr.+Eric+Berg+received+his+Doctor+of+Chiropractic+degree+from+Palmer+College+of+Chiropractic+in+1988.++His+use+of+%E2%80%9Cdoctor%E2%80%9D+or+%E2%80%9CDr.%E2%80%9D+in+relation+to+himself+solely+refers+to+that+degree.++Dr.+Berg+is+a+licensed+chiropractor+in+Virginia%2C+California%2C+and+Louisiana%2C+but+he+no+longer+practices+chiropractic+in+any+state+and+does+not+see+patients+so+he+can+focus+on+educating+people+as+a+full+time+activity%2C+yet+he+maintains+an+active+license.+This+video+is+for+general+informational+purposes+only.++It+should+not+be+used+to+self-diagnose+and+it+is+not+a+substitute+for+a+medical+exam%2C+cure%2C+treatment%2C+diagnosis%2C+and+prescription+or+recommendation.++It+does+not+create+a+doctor-patient+relationship+between+Dr.+Berg+and+you.++You+should+not+make+any+change+in+your+health+regimen+or+diet+before+first+consulting+a+physician+and+obtaining+a+medical+exam%2C+diagnosis%2C+and+recommendation.++Always+seek+the+advice+of+a+physician+or+other+qualified+health+provider+with+any+questions+you+may+have+regarding+a+medical+condition.+The+Health+%5Cu0026+Wellness%2C+Dr.+Berg+Nutritionals+and+Dr.+Eric+Berg%2C+D.C.+are+not+liable+or+responsible+for+any+advice%2C+course+of+treatment%2C+diagnosis+or+any+other+information%2C+services+or+product+you+obtain+through+this+video+or+site.%22%7D%2C%22lengthSeconds%22%3A%220%22%2C%22ownerProfileUrl%22%3A%22http%3A%2F%2Fwww.youtube.com%2Fuser%2Fdrericberg123%22%2C%22externalChannelId%22%3A%22UC3w193M5tYPJqF0Hi-7U-2g%22%2C%22availableCountries%22%3A%5B%22AD%22%2C%22AE%22%2C%22AF%22%2C%22AG%22%2C%22AI%22%2C%22AL%22%2C%22AM%22%2C%22AO%22%2C%22AQ%22%2C%22AR%22%2C%22AS%22%2C%22AT%22%2C%22AU%22%2C%22AW%22%2C%22AX%22%2C%22AZ%22%2C%22BA%22%2C%22BB%22%2C%22BD%22%2C%22BE%22%2C%22BF%22%2C%22BG%22%2C%22BH%22%2C%22BI%22%2C%22BJ%22%2C%22BL%22%2C%22BM%22%2C%22BN%22%2C%22BO%22%2C%22BQ%22%2C%22BR%22%2C%22BS%22%2C%22BT%22%2C%22BV%22%2C%22BW%22%2C%22BY%22%2C%22BZ%22%2C%22CA%22%2C%22CC%22%2C%22CD%22%2C%22CF%22%2C%22CG%22%2C%22CH%22%2C%22CI%22%2C%22CK%22%2C%22CL%22%2C%22CM%22%2C%22CN%22%2C%22CO%22%2C%22CR%22%2C%22CU%22%2C%22CV%22%2C%22CW%22%2C%22CX%22%2C%22CY%22%2C%22CZ%22%2C%22DE%22%2C%22DJ%22%2C%22DK%22%2C%22DM%22%2C%22DO%22%2C%22DZ%22%2C%22EC%22%2C%22EE%22%2C%22EG%22%2C%22EH%22%2C%22ER%22%2C%22ES%22%2C%22ET%22%2C%22FI%22%2C%22FJ%22%2C%22FK%22%2C%22FM%22%2C%22FO%22%2C%22FR%22%2C%22GA%22%2C%22GB%22%2C%22GD%22%2C%22GE%22%2C%22GF%22%2C%22GG%22%2C%22GH%22%2C%22GI%22%2C%22GL%22%2C%22GM%22%2C%22GN%22%2C%22GP%22%2C%22GQ%22%2C%22GR%22%2C%22GS%22%2C%22GT%22%2C%22GU%22%2C%22GW%22%2C%22GY%22%2C%22HK%22%2C%22HM%22%2C%22HN%22%2C%22HR%22%2C%22HT%22%2C%22HU%22%2C%22ID%22%2C%22IE%22%2C%22IL%22%2C%22IM%22%2C%22IN%22%2C%22IO%22%2C%22IQ%22%2C%22IR%22%2C%22IS%22%2C%22IT%22%2C%22JE%22%2C%22JM%22%2C%22JO%22%2C%22JP%22%2C%22KE%22%2C%22KG%22%2C%22KH%22%2C%22KI%22%2C%22KM%22%2C%22KN%22%2C%22KP%22%2C%22KR%22%2C%22KW%22%2C%22KY%22%2C%22KZ%22%2C%22LA%22%2C%22LB%22%2C%22LC%22%2C%22LI%22%2C%22LK%22%2C%22LR%22%2C%22LS%22%2C%22LT%22%2C%22LU%22%2C%22LV%22%2C%22LY%22%2C%22MA%22%2C%22MC%22%2C%22MD%22%2C%22ME%22%2C%22MF%22%2C%22MG%22%2C%22MH%22%2C%22MK%22%2C%22ML%22%2C%22MM%22%2C%22MN%22%2C%22MO%22%2C%22MP%22%2C%22MQ%22%2C%22MR%22%2C%22MS%22%2C%22MT%22%2C%22MU%22%2C%22MV%22%2C%22MW%22%2C%22MX%22%2C%22MY%22%2C%22MZ%22%2C%22NA%22%2C%22NC%22%2C%22NE%22%2C%22NF%22%2C%22NG%22%2C%22NI%22%2C%22NL%22%2C%22NO%22%2C%22NP%22%2C%22NR%22%2C%22NU%22%2C%22NZ%22%2C%22OM%22%2C%22PA%22%2C%22PE%22%2C%22PF%22%2C%22PG%22%2C%22PH%22%2C%22PK%22%2C%22PL%22%2C%22PM%22%2C%22PN%22%2C%22PR%22%2C%22PS%22%2C%22PT%22%2C%22PW%22%2C%22PY%22%2C%22QA%22%2C%22RE%22%2C%22RO%22%2C%22RS%22%2C%22RU%22%2C%22RW%22%2C%22SA%22%2C%22SB%22%2C%22SC%22%2C%22SD%22%2C%22SE%22%2C%22SG%22%2C%22SH%22%2C%22SI%22%2C%22SJ%22%2C%22SK%22%2C%22SL%22%2C%22SM%22%2C%22SN%22%2C%22SO%22%2C%22SR%22%2C%22SS%22%2C%22ST%22%2C%22SV%22%2C%22SX%22%2C%22SY%22%2C%22SZ%22%2C%22TC%22%2C%22TD%22%2C%22TF%22%2C%22TG%22%2C%22TH%22%2C%22TJ%22%2C%22TK%22%2C%22TL%22%2C%22TM%22%2C%22TN%22%2C%22TO%22%2C%22TR%22%2C%22TT%22%2C%22TV%22%2C%22TW%22%2C%22TZ%22%2C%22UA%22%2C%22UG%22%2C%22UM%22%2C%22US%22%2C%22UY%22%2C%22UZ%22%2C%22VA%22%2C%22VC%22%2C%22VE%22%2C%22VG%22%2C%22VI%22%2C%22VN%22%2C%22VU%22%2C%22WF%22%2C%22WS%22%2C%22YE%22%2C%22YT%22%2C%22ZA%22%2C%22ZM%22%2C%22ZW%22%5D%2C%22isUnlisted%22%3Afalse%2C%22hasYpcMetadata%22%3Afalse%2C%22viewCount%22%3A%220%22%2C%22category%22%3A%22Education%22%2C%22publishDate%22%3A%222020-11-01%22%2C%22ownerChannelName%22%3A%22Dr.+Eric+Berg+DC%22%2C%22liveBroadcastDetails%22%3A%7B%22isLiveNow%22%3Afalse%2C%22startTimestamp%22%3A%222020-11-06T16%3A00%3A00%2B00%3A00%22%7D%2C%22uploadDate%22%3A%222020-11-01%22%7D%7D%2C%22trackingParams%22%3A%22CAAQu2kiEwjizoGI_OfsAhW29-MHHRRrCpk%3D%22%2C%22messages%22%3A%5B%7B%22mealbarPromoRenderer%22%3A%7B%22icon%22%3A%7B%22thumbnails%22%3A%5B%7B%22url%22%3A%22https%3A%2F%2Fwww.gstatic.com%2Fyoutube%2Fimg%2Fpromos%2Fgrowth%2Fb4679ce8aeacf18fc02523d86e54112fbb119f787e1314f696de76e82440e22c_384x384.png%22%2C%22width%22%3A384%2C%22height%22%3A384%7D%5D%7D%2C%22messageTexts%22%3A%5B%7B%22runs%22%3A%5B%7B%22text%22%3A%22With+unlimited+DVR+storage+space%2C+enjoy+your+favorite+shows+and+movies+anytime%2C+anywhere%22%7D%5D%7D%5D%2C%22actionButton%22%3A%7B%22buttonRenderer%22%3A%7B%22style%22%3A%22STYLE_BLUE_TEXT%22%2C%22size%22%3A%22SIZE_DEFAULT%22%2C%22text%22%3A%7B%22runs%22%3A%5B%7B%22text%22%3A%22Try+it+free%22%7D%5D%7D%2C%22serviceEndpoint%22%3A%7B%22clickTrackingParams%22%3A%22CAMQ7G8iEwjizoGI_OfsAhW29-MHHRRrCpk%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22%2Fservice_ajax%22%2C%22sendPost%22%3Atrue%2C%22apiUrl%22%3A%22%2Fyoutubei%2Fv1%2Ffeedback%22%7D%7D%2C%22feedbackEndpoint%22%3A%7B%22feedbackToken%22%3A%22AB9zfpIAsFNccEwW0UHnLCuiKKsoqTGD_UVCa2mP23QZnLw3XEANUXu7QDTWFvimA3ti5I_1ljtzTe-X2hLMqWoiiiLpKoUl-OXpNGed4aZ5MXUwqIOA5dS4Xl4h01k4J7y1mSEq9QAKFS5xoRBhAH6oVB7fpDwL3KJenXE0twaoAlKaWTaxoAg%22%2C%22uiActions%22%3A%7B%22hideEnclosingContainer%22%3Atrue%7D%7D%7D%2C%22navigationEndpoint%22%3A%7B%22clickTrackingParams%22%3A%22CAMQ7G8iEwjizoGI_OfsAhW29-MHHRRrCpk%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22https%3A%2F%2Ftv.youtube.com%2F%3Fpid%3Ddmea-acq-u-junerefreshsoa%5Cu0026utm_source%3Ddmea%5Cu0026utm_medium%3Dnp%5Cu0026utm_campaign%3Djunerefresh_dmea_lo_1%22%2C%22webPageType%22%3A%22WEB_PAGE_TYPE_UNKNOWN%22%2C%22rootVe%22%3A83769%7D%7D%2C%22urlEndpoint%22%3A%7B%22url%22%3A%22https%3A%2F%2Ftv.youtube.com%2F%3Fpid%3Ddmea-acq-u-junerefreshsoa%5Cu0026utm_source%3Ddmea%5Cu0026utm_medium%3Dnp%5Cu0026utm_campaign%3Djunerefresh_dmea_lo_1%22%2C%22target%22%3A%22TARGET_NEW_WINDOW%22%7D%7D%2C%22trackingParams%22%3A%22CAMQ7G8iEwjizoGI_OfsAhW29-MHHRRrCpk%3D%22%7D%7D%2C%22dismissButton%22%3A%7B%22buttonRenderer%22%3A%7B%22style%22%3A%22STYLE_TEXT%22%2C%22size%22%3A%22SIZE_DEFAULT%22%2C%22text%22%3A%7B%22runs%22%3A%5B%7B%22text%22%3A%22No+thanks%22%7D%5D%7D%2C%22serviceEndpoint%22%3A%7B%22clickTrackingParams%22%3A%22CAIQ7W8iEwjizoGI_OfsAhW29-MHHRRrCpk%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22%2Fservice_ajax%22%2C%22sendPost%22%3Atrue%2C%22apiUrl%22%3A%22%2Fyoutubei%2Fv1%2Ffeedback%22%7D%7D%2C%22feedbackEndpoint%22%3A%7B%22feedbackToken%22%3A%22AB9zfpKMDZVyBaaYgjk-JrvJl5eS1cERaSCaPLsPgpAtKhAn4VBI_Vr25uZGwAHZKp1mBPvYDLrI-Rt3IN_bAxGa3mogfC0OgXFlDeGfvsSnytMPSgR8LxG4jtbbPzxDgCHftypeX7t9zXOmkje_zxxDxQnR7aSwHBwc1KeVu8USbxQHWKCDwlM%22%2C%22uiActions%22%3A%7B%22hideEnclosingContainer%22%3Atrue%7D%7D%7D%2C%22trackingParams%22%3A%22CAIQ7W8iEwjizoGI_OfsAhW29-MHHRRrCpk%3D%22%7D%7D%2C%22triggerCondition%22%3A%22TRIGGER_CONDITION_DEFAULT%22%2C%22style%22%3A%22STYLE_MESSAGE%22%2C%22trackingParams%22%3A%22CAEQ42kYACITCOLOgYj85-wCFbb34wcdFGsKmQ%3D%3D%22%2C%22impressionEndpoints%22%3A%5B%7B%22clickTrackingParams%22%3A%22CAEQ42kYACITCOLOgYj85-wCFbb34wcdFGsKmQ%3D%3D%22%2C%22commandMetadata%22%3A%7B%22webCommandMetadata%22%3A%7B%22url%22%3A%22%2Fservice_ajax%22%2C%22sendPost%22%3Atrue%2C%22apiUrl%22%3A%22%2Fyoutubei%2Fv1%2Ffeedback%22%7D%7D%2C%22feedbackEndpoint%22%3A%7B%22feedbackToken%22%3A%22AB9zfpJ2nQn9r8JViTW_IKRooWpzW8cNO7zpS29vUJEI2BXt9Qi-Mya_rjFjQ720Pbm-qZuB99xB5XFkOuJduEFZozTVg3ldPRZ6uJWGjBXJIlg2uKJ9_EwRTONgbo2hyKVko4lrT8OPjNsWq5EqgEkb06moC7wTSIV2rsCucpdylBtx6saHONY%22%2C%22uiActions%22%3A%7B%22hideEnclosingContainer%22%3Afalse%7D%7D%7D%5D%2C%22isVisible%22%3Atrue%2C%22messageTitle%22%3A%7B%22runs%22%3A%5B%7B%22text%22%3A%22Record+now%2C+watch+later%22%7D%5D%7D%7D%7D%5D%7D&ps=desktop-polymer&host_language=en&gapi_hint_params=m%3B%2F_%2Fscs%2Fabc-static%2F_%2Fjs%2Fk%3Dgapi.gapi.en.9Ky5Gf3gP0o.O%2Fd%3D1%2Fct%3Dzgms%2Frs%3DAHpOoo9ntgUgaVmSKxb6oXsk111880adyg%2Fm%3D__features__&hl=en_US&c=WEB&cver=2.20201102.01.00&innertube_api_key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8&watermark=%2Chttps%3A%2F%2Fs.ytimg.com%2Fyts%2Fimg%2Fwatermark%2Fyoutube_watermark-vflHX6b6E.png%2Chttps%3A%2F%2Fs.ytimg.com%2Fyts%2Fimg%2Fwatermark%2Fyoutube_hd_watermark-vflAzLcD6.png&csn=5SKiX9WiNZPPj-8Pupm9-A4&enablecsi=1&innertube_context_client_version=2.20201102.01.00&status=ok \ No newline at end of file diff --git a/test/info-test.js b/test/info-test.js index ec90a67c..9ca3ea6a 100644 --- a/test/info-test.js +++ b/test/info-test.js @@ -307,7 +307,7 @@ describe('ytdl.getInfo()', () => { const scope = nock(id, 'embed-backup', { embed: [true, 200, 'player-vars'], }); - let info = await ytdl.getInfo(id); + let info = await ytdl.getInfo(id, { requestOptions: { maxRetries: 0 } }); scope.done(); assert.strictEqual(info.formats.length, expected.formats.length); }); @@ -403,18 +403,13 @@ describe('ytdl.getInfo()', () => { }); describe('When watch.json page gives back an empty response', () => { - it('Retries the request', async() => { - const id = '_HSylqgVYQI'; - const scope1 = nock(id, 'regular', { + it('Uses next endpoint as backup', async() => { + const id = 'LuZu9N53Vd0'; + const scope1 = nock(id, 'embed-backup', { watchJson: [true, 200, 'empty'], }); - const scope2 = nock(id, 'regular', { - watchHtml: false, - player: false, - }); - let info = await ytdl.getInfo(id, { requestOptions: { maxRetries: 1 } }); + let info = await ytdl.getInfo(id, { requestOptions: { maxRetries: 0 } }); scope1.done(); - scope2.done(); assert.ok(info.formats.length); assert.ok(info.formats[0].url); });