WordPress 5.3.x YouTube oEmbed is not working

So apparently the issue also happens in WordPress 5.6 (the latest release as of writing), and YouTube is probably at fault because the (oEmbed) <link> tags are in the body instead of the head (see screenshot below), and that in turn causes the issue because WP_oEmbed::discover() looks for the <link> tags in the head only. And secondly, YouTube uses http:// instead of https:// (secure protocol) in the <link> tags, so you would need to replace that http:// with https:// if your site uses https:// or is SSL-enabled.

Screenshot 1: Elements inspector tab (in Chrome)

Chrome DevTools

Screenshot 2: Server-generated HTML source (press Ctrl+U on Chrome)

Chrome view-source

And maybe (YouTube is not at fault and) the WordPress core team should revise the function so that it tries to also search in the body? Or perhaps use a better way to find the tags like using DOMDocument …?

But anyway, as mentioned by @Rup, you could alternatively use WP_oEmbed::get_provider() which will load the sanctioned/trusted oEmbed providers defined in the class constructor, and (as of writing) YouTube is actually the very first in the providers list.

// So instead of:
// this fetches the <link> tags from the provider site
$provider = $oembed->discover( $video_url );

// Use this one:
// this finds in the sanctioned oEmbed providers first
// then tries with the above discover()..
$provider = $oembed->get_provider( $video_url );

Or as I said in the comments, if you just wanted to get the HTML/embed code, then you could simply use wp_oembed_get() which should work since, although indirectly, the function uses WP_oEmbed::get_data() which uses WP_oEmbed::get_provider():

// I'd prefer this:
echo wp_oembed_get( $video_url );

// But that is equivalent to:
$video = $oembed->get_data( $video_url );
echo $video->html;

// And that is equivalent to:
$provider = $oembed->get_provider( $video_url );
$video = $oembed->fetch( $provider, $video_url );
echo $video->html;