Ran into this same issue and I found the answer after many hours and almost giving up. It's in a bit of code that written to make the Customizer work with playlists. Checkout this comment from /wp-includes/widgets/class-wp-widget-text.php
:
/**
* Enqueue preview scripts.
*
* These scripts normally are enqueued just-in-time when a playlist shortcode is used.
* However, in the customizer, a playlist shortcode may be used in a text widget and
* dynamically added via selective refresh, so it is important to unconditionally enqueue them.
*
* @since 4.9.3
*/
public function enqueue_preview_scripts() {
require_once dirname( __DIR__ ) . '/media.php';
wp_playlist_scripts( 'audio' );
wp_playlist_scripts( 'video' );
}
So this is being used in the customizer, which also loads the HTML dynamically after the page has loaded. If we want to do a similar thing on the front end, we will also need to definitely load these things when the page first loads. Here's the code I ended up using:
function squarecandy_wp_enqueue_scripts() {
wp_enqueue_script( 'wp-playlist' );
require_once get_home_path() . 'wp-includes/media.php';
wp_playlist_scripts( 'audio' );
wp_playlist_scripts( 'video' );
}
add_action( 'wp_enqueue_scripts', 'squarecandy_wp_enqueue_scripts' );
Boom! Now you can run wp.playlist.initialize()
in your js at anytime without errors.
One more thing to note: This issue can be particularly vexing to troubleshoot because if you have a page that naturally contains a playlist on the initial page load, then you can load additional playlist HTML on to the page and then run wp.playlist.initialize()
and everything works out fine. It only fails if you have no playlists on your initial page (so this mysterious "just-in-time" enqueue never happens) and then you try and load in a playlist later.
Update
This works better, now that we don't need to support IE9 anymore:
function squarecandy_wp_enqueue_scripts() {
if ( defined( 'ABSPATH' ) && ! is_admin() && ! wp_doing_ajax() ) {
require_once ABSPATH . 'wp-includes/media.php';
wp_enqueue_script( 'wp-playlist' );
wp_enqueue_script( 'wp-mediaelement' );
wp_enqueue_style( 'wp-mediaelement' );
add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 );
}
}
add_action( 'wp_enqueue_scripts', 'squarecandy_wp_enqueue_scripts' );