8

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.

2 Answers 2

9

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 ;-)

9
  • I don't know how to thank you ! Amazing :)
    – mahdiar
    Commented Apr 26, 2014 at 17:08
  • Is there anyway to add download linkd beside every mp3 file name ?
    – mahdiar
    Commented Apr 26, 2014 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
    Commented Apr 30, 2014 at 23:20
  • Here's the plugin on github: github.com/birgire/wpse-playlist
    – birgire
    Commented May 1, 2014 at 17:01
  • 2
    This answer is ... wow. +1
    – kaiser
    Commented Jun 18, 2014 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.

2
  • Thanks . I think the third one is the best one . How can I do that ?
    – mahdiar
    Commented Apr 19, 2014 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
    Commented Apr 22, 2014 at 18:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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