7

In WordPress 3.9 there is a new feature that can make a playlist with uploaded audio files. I'd like to use external audio files. I use two web hosts. One for my website and one for my audio files.

7

Playlist shortcode with external audio or video files

Here I explain how you can implement idea 3 in my other answer, where we use the following shortcode structure:

[wpse_playlist type="" current="" style="" tracklist="" tracknumbers="" images="" artist=""]
    [wpse_trac src="" title="" type="" caption="" description="" image="" 
            meta_artist="" meta_album="" meta_genre="" meta_length_formatted=""
            image_src="" image_width="" image_height=""
            thumb_src="" thumb_width="" thumb_height=""]
    [wpse_trac src="" title="" type="" caption="" description="" image="" 
            meta_artist="" meta_album="" meta_genre="" meta_length_formatted=""
            image_src="" image_width="" image_height=""
            thumb_src="" thumb_width="" thumb_height=""]
[/wpse_playlist]

but this does not include the complete list of attributes, since the plugin is still in developement ;-)

Example 1:

You can use for example:

[wpse_playlist]
   [wpse_trac title="Ain't Misbehavin'" src="//s.w.org/images/core/3.9/AintMisbehavin.mp3"]
   [wpse_trac title="Buddy Bolden's Blues" src="//s.w.org/images/core/3.9/JellyRollMorton-BuddyBoldensBlues.mp3"]
[/wpse_playlist]

in your post content and it will display like this:

wpse playlist

Example 2:

Here's a more extensive example:

[wpse_playlist type="audio" tracklist="true" tracknumbers="true" images="true" artist="true"]
   [wpse_trac title="Ain't Misbehavin'" src="//s.w.org/images/core/3.9/AintMisbehavin.mp3" type="audio/mpeg" caption="" description="" image="" meta_artist="Louis Armstrong and His Orchestra" meta_album="78 RPMs and Cylinder Recordings" meta_genre="" meta_length_formatted="3:21" image_src="//s.w.org/images/core/3.9/louis.jpg" image_width="308" image_height="240" thumb_src="//s.w.org/images/core/3.9/louis.jpg" thumb_width="308" thumb_height="240"]
   [wpse_trac title="Buddy Bolden's Blues" src="//s.w.org/images/core/3.9/JellyRollMorton-BuddyBoldensBlues.mp3" type="audio/mpeg" caption="" description="" image="" meta_artist="Jelly Roll Morten" meta_album="78 RPMs and Cylinder Recordings" meta_genre="Jazz" meta_length_formatted="2:09"]
[/wpse_playlist]

with the following output:

extensive - wpse playlist

Example 3:

Here's the vanilla version:

Vanilla version

generated from the shortcode:

[wpse_playlist type="audio" current="no" tracklist="yes" tracknumbers="no" images="no" artist="no"]
    [wpse_trac title="Davenport Blues" src="//s.w.org/images/core/3.9/DavenportBlues.mp3"]
    [wpse_trac title="Dixie Blues" src="//s.w.org/images/core/3.9/Louisiana_Five-Dixie_Blues-1919.mp3"]
[/wpse_playlist]

Example 4:

Here's the video playlist:

video playlist

from this shortcode:

[wpse_playlist type="video"]
    [wpse_trac caption="Live widgets previews in WordPress 3.9" src="//s.w.org/images/core/3.9/widgets.mp4" image_src="/wp-content/uploads/2014/04/widgets_screen.png"]
    [wpse_trac caption="Another cool video showing how live widgets previews works in WordPress 3.9" src="//s.w.org/images/core/3.9/widgets.mp4" image_src="/wp-content/uploads/2014/04/widgets_screen2.png"]
[/wpse_playlist]

Code:

Here's a first draft version of a single file plugin, but I will try to refine it further on github and post the link soon (Update: https://github.com/birgire/wpse-playlist ):

<?php 
/**
 * Plugin Name: WPSE Playlist shortcode for external files
 * Plugin URI: http://wordpress.stackexchange.com/q/141766/
 * Version: 0.0.1
 */

add_action( 'wp', 'wpse_playlist_init' );

function wpse_playlist_init()
{
    $playlist = new WPSE_Playlist;
    $playlist->init();
}


/**
 * Class WPSE_Playlist
 */

class WPSE_Playlist
{
    protected $type     = '';
    protected $types    = array( 'audio', 'video' );
    protected $instance = 0;

    public function init()
    {
        add_shortcode( 'wpse_playlist', array( $this, 'playlist_shortcode' ) );
        add_shortcode( 'wpse_trac',     array( $this, 'trac_shortcode'     ) );
    }

    public function playlist_shortcode( $atts = array(), $content = '' ) 
    {        
        $this->instance++;
        $atts = shortcode_atts( 
            array(
                'type'          => 'audio',
                'style'         => 'light',
                'tracklist'     => 'true',
                'tracknumbers'  => 'true',
                'images'        => 'true',
                'artists'       => 'true',
                'current'       => 'true',
                'loop'          => 'false',
                'autoplay'      => 'false',
                'id'            => '',
                'width'         => '',
                'height'        => '',
            ), $atts, 'wpse_playlist_shortcode' );

        //----------
        // Input
        //----------
        $atts['id']           = esc_attr( $atts['id'] );
        $atts['type']         = esc_attr( $atts['type'] );
        $atts['style']        = esc_attr( $atts['style'] );
        $atts['tracklist']    = filter_var( $atts['tracklist'], FILTER_VALIDATE_BOOLEAN );
        $atts['tracknumbers'] = filter_var( $atts['tracknumbers'], FILTER_VALIDATE_BOOLEAN );
        $atts['images']       = filter_var( $atts['images'], FILTER_VALIDATE_BOOLEAN );
        $atts['autoplay']     = filter_var( $atts['current'], FILTER_VALIDATE_BOOLEAN );

        // Audio specific:
        $atts['artists']      = filter_var( $atts['artists'], FILTER_VALIDATE_BOOLEAN );
        $atts['current']      = filter_var( $atts['current'], FILTER_VALIDATE_BOOLEAN );

        // Video specific:
        $atts['loop']         = filter_var( $atts['loop'], FILTER_VALIDATE_BOOLEAN );

        // Nested shortcode support:
        $this->type           = ( in_array( $atts['type'], $this->types, TRUE ) ) ? $atts['type'] : 'audio';
        $content              = substr(  strip_tags( nl2br( do_shortcode( $content ) ) ), 0, -2 );

        // Enqueue default scripts and styles for the playlist.
        ( 1 === $this->instance ) && do_action( 'wp_playlist_scripts', $atts['type'], $atts['style'] );

        //----------
        // Output
        //----------
        $html = '';
        $html .= sprintf( '<div class="wp-playlist wp-%s-playlist wp-playlist-%s">', 
            $this->type, 
            $atts['style'] 
        );

        // Current audio item:
        if( $atts['current'] && 'audio' === $this->type )
            $html .= '<div class="wp-playlist-current-item"></div>';   

        // Video player:                      
        if( 'video' === $this->type ):
            $html .= sprintf( '<video controls="controls" preload="none" width="%s" height="%s"></video>',
                $atts['style'],
                $atts['width'],
                $atts['height']
            );
        // Audio player:                      
        else:
            $html .= sprintf( '<audio controls="controls" preload="metadata"></audio>', 
                $atts['style'] 
            );
        endif;

       // Next/Previous:
        $html .= '<div class="wp-playlist-next"></div><div class="wp-playlist-prev"></div>';

        // JSON 
        $html .= sprintf( '
            <script type="application/json">{
                "type":"%s",
                "tracklist":%b,
                "tracknumbers":%b,
                "images":%b,
                "artists":%b,
                "tracks":[%s]
            }</script></div>', 
            $atts['type'], 
            $atts['tracklist'], 
            $atts['tracknumbers'],  
            $atts['images'],
            $atts['artists'],
            $content
        );

        return $html;
    }

    public function trac_shortcode( $atts = array(), $content = '' ) 
    {        
        $atts = shortcode_atts( 
            array(
            'src'                   => '',
            'type'                  => ( 'video' === $this->type ) ? 'video/mp4' : 'audio/mpeg',
            'title'                 => '',
            'caption'               => '',
            'description'           => '',
            'image_src'             => sprintf( '%s/wp-includes/images/media/%s.png', get_site_url(), $this->type ),
            'image_width'           => '48',
            'image_height'          => '64',
            'thumb_src'             => sprintf( '%s/wp-includes/images/media/%s.png', get_site_url(), $this->type ),
            'thumb_width'           => '48',
            'thumb_height'          => '64',
            'meta_artist'           => '',
            'meta_album'            => '',
            'meta_genre'            => '',
            'meta_length_formatted' => '',
            'dimensions_original_width'  => '300',
            'dimensions_original_height' => '200',
            'dimensions_resized_width'   => '600',
            'dimensions_resized_height'  => '400',
        ), $atts, 'wpse_trac_shortcode' );

        //----------
        // Input
        //----------
        $data['src']                      = esc_url( $atts['src'] );
        $data['title']                    = sanitize_text_field( $atts['title'] );
        $data['type']                     = sanitize_text_field( $atts['type'] );
        $data['caption']                  = sanitize_text_field( $atts['caption'] );
        $data['description']              = sanitize_text_field( $atts['description'] );
        $data['image']['src']             = esc_url( $atts['image_src'] );
        $data['image']['width']           = intval( $atts['image_width'] );
        $data['image']['height']          = intval( $atts['image_height'] );
        $data['thumb']['src']             = esc_url( $atts['thumb_src'] );
        $data['thumb']['width']           = intval( $atts['thumb_width'] );
        $data['thumb']['height']          = intval( $atts['thumb_height'] );
        $data['meta']['length_formatted'] = sanitize_text_field( $atts['meta_length_formatted'] );

        // Video related:
        if( 'video' === $this->type ) 
        {
            $data['dimensions']['original']['width']  = sanitize_text_field( $atts['dimensions_original_width'] );
            $data['dimensions']['original']['height'] = sanitize_text_field( $atts['dimensions_original_height'] );
            $data['dimensions']['resized']['width']   = sanitize_text_field( $atts['dimensions_resized_width'] );
            $data['dimensions']['resized']['height']  = sanitize_text_field( $atts['dimensions_resized_height'] );

        // Audio related:
        } else {
            $data['meta']['artist']           = sanitize_text_field( $atts['meta_artist'] );
            $data['meta']['album']            = sanitize_text_field( $atts['meta_album'] );
            $data['meta']['genre']            = sanitize_text_field( $atts['meta_genre'] );
        }

        //----------
        // Output:           
        //----------
        return json_encode( $data ) . ',';      
    }

} // end class

Happy listening ;-)

  • I don't know how to thank you ! Amazing :) – mahdiar Apr 26 '14 at 17:08
  • Is there anyway to add download linkd beside every mp3 file name ? – mahdiar Apr 26 '14 at 17:08
  • @mahdiar Please check out my answer to your question here, where I describe how you can modify the playlist template to your needs. – birgire Apr 30 '14 at 23:20
  • Here's the plugin on github: github.com/birgire/wpse-playlist – birgire May 1 '14 at 17:01
  • 2
    This answer is ... wow. +1 – kaiser Jun 18 '14 at 14:35
3

When you construct a playlist and add it to your post content, you get a shortcode like this one:

[playlist ids="2855,1296"]

where the ids are referring to the audio attachments.

The playlists contains lots of audio meta data, so it's not possible to include external files this way.

Here are some untested ideas:

Idea 1:

I wonder if it would work for you to upload the files to your main WordPress install at example.com, to collect the meta data and construct the playlists but then serve the audio files from your second host, audio.example.com ?

You can try to modify the audio files urls, in your playlist, with:

// Add filter for playlists
add_filter( 'post_playlist', function(){
    add_filter( 'wp_get_attachment_url' ,'wpse_141766_wp_get_attachment_url' );
});

// Remove filter 
add_action( 'wp_playlist_scripts', function(){
    remove_filter( 'wp_get_attachment_url' ,'wpse_141766_wp_get_attachment_url' );
});

where

function wpse_141766_wp_get_attachment_url( $url )
{
    // Edit to your needs:    
    return str_ireplace( 'example.com', 'audio.example.com', $url );
}

Idea 2:

You could create the playlist manually.

If you check out the wp-admin/about.php?updated page in your new 3.9 install, you will see that it contains a working playlist with external audio files. Here's the playlist with two tracks:

    <div class="wp-playlist wp-audio-playlist wp-playlist-light">
        <div class="wp-playlist-current-item"></div>
        <audio controls="controls" preload="metadata"></audio>
        <div class="wp-playlist-next"></div>
        <div class="wp-playlist-prev"></div>
        <?php
        $audio_icon_js = esc_js( includes_url( 'images/media/audio.png' ) );
        $wp_host = '//s.w.org/images/core/3.9/';
        ?>

        <script type="application/json">{
            "type":"audio",
            "tracklist":true,
            "tracknumbers":true,
            "images":true,
            "artists":true,
            "tracks":[{
                "src":"<?php echo $wp_host ?>AintMisbehavin.mp3",
                "type":"audio\/mpeg","title":"Ain't Misbehavin'","caption":"","description":"",
                "meta":{
                    "artist":"Louis Armstrong & His Orchestra",
                    "album":"78 RPMs & Cylinder Recordings",
                    "genre":"Jazz",
                    "length_formatted":"3:21"
                },
                "image":{"src":"//s.w.org/images/core/3.9/louis.jpg","width":308,"height":240},
                "thumb":{"src":"//s.w.org/images/core/3.9/louis.jpg","width":308,"height":240}
            },
            {
                "src":"<?php echo $wp_host ?>JellyRollMorton-BuddyBoldensBlues.mp3",
                "type":"audio\/mpeg","title":"Buddy Bolden's Blues","caption":"","description":"",
                "meta":{
                    "artist":"Jelly Roll Morten",
                    "album":"78 RPMs & Cylinder Recordings",
                    "genre":"Jazz",
                    "length_formatted":"2:09"
                },
                "image":{"src":"<?php echo $audio_icon_js ?>","width":48,"height":64},
                "thumb":{"src":"<?php echo $audio_icon_js ?>","width":48,"height":64}

            }]
        }</script>
    </div>

where the top of that page contains:

wp_enqueue_style( 'wp-mediaelement' );
wp_enqueue_script( 'wp-playlist' );
add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 );

But I think you can just use

do_action( 'wp_playlist_scripts', 'audio', 'light' );

or

do_action( 'wp_playlist_scripts', 'audio', 'dark' );

instead.

Idea 3:

You could try to create your own playlist shortcode:

[myplaylist type="" tracklist="" tracknumbers="" images="" artist="" ]
    [mytrac src="" title="" type="" caption="" description="" image=""]
        [mymeta artist="" album="" genre="" length_formatted=""]
        [myimage src="" width="" height=""]
        [mythumb src="" width="" height=""]
    [/mytrac]
    [mytrac src="" title="" type="" caption="" description="" image=""]
        [mymeta artist="" album="" genre="" length_formatted=""]
        [myimage src="" width="" height=""]
        [mythumb src="" width="" height=""]
    [/mytrac]
[/myplaylist]

or

[myplaylist type="" tracklist="" tracknumbers="" images="" artist="" ]
    [mytrac src="" title="" type="" caption="" description="" image="" 
            meta_artist="" meta_album="" meta_genre="" meta_length_formatted=""
            image_src="" image_width="" image_height=""
            thumb_src="" thumb_width="" thumb_height=""]
    [mytrac src="" title="" type="" caption="" description="" image="" 
            meta_artist="" meta_album="" meta_genre="" meta_length_formatted=""
            image_src="" image_width="" image_height=""
            thumb_src="" thumb_width="" thumb_height=""]
[/myplaylist]

This looks quite clumsy, so you could try a simplifed version, with default values for the unused attributes:

[myplaylist]
    [mytrac src="" title=""]
    [mytrac src="" title=""]
[/myplaylist]

or some structure that suits you better.

  • Thanks . I think the third one is the best one . How can I do that ? – mahdiar Apr 19 '14 at 20:09
  • @mahdiar, I added a new answer based on the 3rd option where I included a first draft version of a plugin. – birgire Apr 22 '14 at 18:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.