Pre-Load WordPress Audio Metadata Automatically

WordPress Logo

Posted on April 16, 2015 in Development, Web

Out of the box, WordPress does not pre-load metadata or the tracks themselves when you embed an audio file in your post or page. Funny enough it does it for video embeds, but for audio files the preload attribute is set to ‘none’ by default. I am presuming they made the decision in order to reduce the bandwidth needed to load the page with audio embeds, though I do not understand why they handle audio and video embeds differently.

In any case, one of the unfortunate results of the metadata not being pre-loaded is that the embedded audio player will not display the track duration until you hit the Play button. The duration time will show 00:00. This might not be a huge issue if you run a blog with an occassional audio embed, but if your site is primarily based around providing your visitors with audio content and you list a dozen tracks on the same page, it does not translate to a good user experience. You can change the pre-load value in the properties of the audio embed when you insert it into your post, but it is tedious and relies on the site administrator to remember to do that every time.

Here is a snippet that will change the default behavior of the audio embeds and pre-load the metadata automatically:

/**
 * Automatically load embedded audio files' metadata. Out of the box, WordPress has this set to 'none' for audio files. 
 * When none, the duration of audio tracks doesn't show on the frontend. 
 */
function pixelninja_load_audio_metadata_by_default( $out, $pairs, $atts ) {
    if ( !isset($atts['preload']) ) {
        $out['preload'] = 'metadata';
    }
    return $out;
}
add_filter( 'shortcode_atts_audio', 'pixelninja_load_audio_metadata_by_default', 10, 3 );

It leverages the shortcode_atts function and if the preload attribute is not specifically set by the user, it will automatically set it to ‘metadata’.

Two things worth noting:

1) If you have this override enabled and want to embed an audio that would not pre-load the metadata, you will need to switch the WordPress WYSIWYG editor to ‘text’ and manually add preload=’none’ into the audio embed’s shortcode. Setting it to ‘none’ thorough the visual ‘Audio Details’ editor is not enough as WordPress does not write it out in the embed’s shortcode and the filter thinks the value has not been set (and thus will change it to ‘metadata’).

2) Not all the browsers currently support the preload attribute and if they do not, they may still not load the metadata or download the entire file. Not much that can be done about that.

April 29, 2016. Minor update to the function’s code to make it compatible with WordPress 4.5. The previous version wouldn’t correctly keep all the attributes of the shortcode and display a barebones audio player instead of a properly styled one.

Enjoyed this post? Share it with others.
Share on email
Email
Share on facebook
Facebook
Share on google
Google
Share on twitter
Twitter

Responses (9)

  1. Steve
    April 27, 2016 at 11:51 am · Reply

    This code seems to break in WordPress 4.5 but worked great in earlier version. In 4.5 or later, the coe strips somehow causes the resulting output code to set class=”” and style=””, so the audio player is reduced to a barebones version with no styling.

    Do you have a fix for this? I’d love to be able to use something like this in the current version of WordPress.

    • pixel.ninja
      April 27, 2016 at 4:52 pm ·

      Steve,

      Thanks for your message. I haven’t tested this snippet with WP 4.5. I quickly checked the 4.5 changelog and didn’t see any updates that might have an impact on this, but when I have a bit more time I’ll try to test it. I’ll let you know if I run into the same issue and if I’m able to find a solution.

    • pixel.ninja
      April 29, 2016 at 1:06 am ·

      Steve, I updated the function’s code snippet to make it compatible with WordPress 4.5.

  2. Sarcastro
    December 17, 2016 at 4:22 am · Reply

    Hey pixel ninja,

    For some reason when I preload the audio metadata, it doesn’t display the hours, only the minutes & seconds (ie. it shows a mixtape that’s 2:00:23 in length as 00:23, as though it was only 23 seconds long.)

    When I hit play, it immediately displays correctly. Any idea on how to get this to display properly by default? I’d much rather show the length instead of 00:00, but since all of my files are over an hour long, 00:00 is still better than displaying it without the hours.

    Any idea how to solve this? Or even a workaround that’ll let me define the length manually via the shortcode somehow would be helpful, eg. [audio src="abc.mp3" length="2:00:23"]..

    Thanks Richard, hope you can help!

    • pixel.ninja
      December 17, 2016 at 2:04 pm ·

      Hey Sarcastro,

      Thanks for stopping by. I’m not sure I’m correct without digging into it deeper and testing it, but the only reason I can think of as to why the hours wouldn’t be displayed is that WordPress uses Mediaelement.js to render the audio/video player. If you go to the Mediaelement website and check the player options, you’ll see there’s a alwaysShowHours option, which is false by default. My guess is that this option might be the culprit. You could try changing this option to true for your site and see if it helps.

      The file responsible for the Mediaelement player initialization is /wp-includes/js/mediaelement/wp-mediaelement.js. You could copy the file into your theme, modify it as needed and then de-register the original and register your custom one (more information here). Another possibility would be to write a simple function that would extend the _wpmejsSettings object with the required setting (see an example of such function e.g. here). The latter would be a better solution in case the wp-mediaelement.js file changes significantly in the future.

      As a last resort, you could remove the track duration time from the player completely and instead set it manually and display it in the post elsewhere. Not elegant, but might work for you.

      I hope this helps and sends you hunting in the right direction. If you figure it out, I’d appreciate if you left a comment – I’d love to know whether the alwaysShowHours option was the issue.

      On a related note, I decided not to pre-load the metadata for the project I was working on in the end. As I mention in the post, some browsers would not only download the metadata, but also start downloading the entire track. I can’t remember which browser it was now, but when you had a bunch of tracks on the page it was a huge overhead.

    • Sarcastro
      December 17, 2016 at 11:57 pm ·

      Thank you pixel!

      I switched to wp-mediaelement.js for a bit with the alwaysShowHours option enabled, and it definitely showed the full times (as 2:00:23 in Firefox, and as 120:23 in Chrome) but the players looked completely different from one another and no longer used any of the CSS styling I’d done. Using the full wp-mediaelement.js seemed to fix the length display problem on its own, I didn’t happen to notice any difference with/without the alwaysShowHours option enabled (although it’s possible I did it wrong.)

      You’re absolutely correct regarding preloading metadata for a lot of tracks on the same page… Chrome handled it fine, but Firefox was downloading the first ~25% or so of each file.. or trying to (there were 18 320kbps MP3s on the page totalling over 24hours.) Thanks a ton for pointing that out… I’ve since decided to go back to the minimal player, skip preloading the metadata and hide the .mejs-duration-container from the player.

      I’m now displaying the track length separately (along with bitrate, file size, etc.) directly from the ID3 tags using a custom WP-Filebase template… works like a charm.

      Thanks a bunch for the help, really appreciated! Who knows how long it would’ve taken me to discover the Firefox issue since I don’t use it as my main browser.

      Cheers 🙂

    • pixel.ninja
      December 18, 2016 at 12:17 am ·

      Thanks a lot for reporting back.

      That’s strange that overriding the wp-mediaelements.js file and using a custom one would change the look of the player. I don’t remember having that issue and I can’t think of why that would happen, unless your site wasn’t using the Mediaelements player in the first place. I guess it could be something specific to your theme, I’m not sure.

      Ah, yes, it was Firefox that was automatically downloading the whole tracks and not just the metadata. Like you, I had a a page that had 15 – 20 tracks on it in my project and while they weren’t as long as in your case, the bandwidth overhead was still huge. I too ended up disabling the metadata preloading and just lived with the 00:00 time, until the user clicked on the play button.

      In any case, you’re most welcome. I’m glad you managed to find a solution that works for your particular use case; sounds pretty good to me!

  3. Sarcastro
    December 18, 2016 at 2:31 am · Reply

    Not that it makes a difference now, but if you’re curious about the visual difference and the disparity between browsers, I did it again to take a couple of screenshots for ya: http://topdnb.com/mediaelement-change.jpg …mostly just an excuse to take another run at your comment Captcha game 😉

    I can’t imagine it’s theme-related.. this particular one (“Clean Black 1.4.2”) is really sparse, only ~300kb unzipped.

    • pixel.ninja
      December 18, 2016 at 3:04 am ·

      Hahaha, yeah, those Captcha games are cool 🙂

      From the screenshot it looks like the custom wp-mediaelement.js script is not loading correctly. It de-registers the original default WordPress one, but does not enqueue your custom version of it. The players that you’re seeing are default Chrome and Firefox HTML5 audio players, not the Mediaelement player. Probably a silly question, but you did copy the JS file into /js/wp-mediaelement.js inside your theme folder and modified it there, yeah?

Leave a reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.