Make WordPress Core


Ignore:
Timestamp:
03/16/2013 05:25:44 AM (12 years ago)
Author:
markjaquith
Message:

Introduce [audio] and [video] shortcodes, and use MediaElement.js to play them.

props wonderboymusic. see #23282.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/media.php

    r23714 r23729  
    805805    return $output;
    806806}
     807
     808/**
     809 * Provide a No-JS Flash fallback as a last resort for audio / video
     810 *
     811 * @since 3.6.0
     812 *
     813 * @param string $url
     814 * @return string Fallback HTML
     815 */
     816function wp_mediaelement_fallback( $url ) {
     817    return apply_filters( 'wp_mediaelement_fallback', sprintf( '<a href="%1$s">%1$s</a>', esc_url( $url ) ), $url );
     818}
     819
     820/**
     821 * Return a filtered list of WP-supported audio formats
     822 *
     823 * @since 3.6.0
     824 * @return array
     825 */
     826function wp_get_audio_extensions() {
     827    return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'wma', 'm4a', 'wav' ) );
     828}
     829
     830/**
     831 * The Audio shortcode.
     832 *
     833 * This implements the functionality of the Audio Shortcode for displaying
     834 * WordPress mp3s in a post.
     835 *
     836 * @since 3.6.0
     837 *
     838 * @param array $attr Attributes of the shortcode.
     839 * @return string HTML content to display audio.
     840 */
     841function wp_audio_shortcode( $attr ) {
     842    $post_id = get_post() ? get_the_ID() : 0;
     843
     844    static $instances = 0;
     845    $instances++;
     846
     847    $audio = null;
     848
     849    $default_types = wp_get_audio_extensions();
     850    $defaults_atts = array( 'src' => '' );
     851    foreach ( $default_types as $type  )
     852        $defaults_atts[$type] = '';
     853
     854    $atts = shortcode_atts( $defaults_atts, $attr );
     855    extract( $atts );
     856
     857    $primary = false;
     858    if ( ! empty( $src ) ) {
     859        $type = wp_check_filetype( $src );
     860        if ( ! in_array( $type['ext'], $default_types ) ) {
     861            printf( '<a class="wp-post-format-link-audio" href="%1$s">%1$s</a>', $src );
     862            return;
     863        }
     864        $primary = true;
     865        array_unshift( $default_types, 'src' );
     866    } else {
     867        foreach ( $default_types as $ext ) {
     868            if ( ! empty( $$ext ) ) {
     869                $type = wp_check_filetype( $$ext );
     870                if ( $type['ext'] === $ext )
     871                    $primary = true;
     872            }
     873        }
     874    }
     875
     876    if ( ! $primary ) {
     877        $audios = get_post_audio( $post_id );
     878        if ( empty( $audios ) )
     879            return;
     880
     881        $audio = reset( $audios );
     882        $src = wp_get_attachment_url( $audio->ID );
     883        if ( empty( $src ) )
     884            return;
     885
     886        array_unshift( $default_types, 'src' );
     887    }
     888
     889    $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
     890    if ( 'mediaelement' === $library ) {
     891        wp_enqueue_style( 'wp-mediaelement' );
     892        wp_enqueue_script( 'wp-mediaelement' );
     893    }
     894
     895    $atts = array(
     896        sprintf( 'class="%s"', apply_filters( 'wp_audio_shortcode_class', 'wp-audio-shortcode' ) ),
     897        sprintf( 'id="audio-%d-%d"', $post_id, $instances ),
     898    );
     899
     900    $html = sprintf( '<audio %s controls="controls" preload="none">', join( ' ', $atts ) );
     901
     902    $fileurl = '';
     903    $source = '<source type="%s" src="%s" />';
     904    foreach ( $default_types as $fallback ) {
     905        if ( ! empty( $$fallback ) ) {
     906            if ( empty( $fileurl ) )
     907                $fileurl = $$fallback;
     908            $type = wp_check_filetype( $$fallback );
     909            $html .= sprintf( $source, $type['type'], $$fallback );
     910        }
     911    }
     912
     913    if ( 'mediaelement' === $library )
     914        $html .= wp_mediaelement_fallback( $fileurl );
     915    $html .= '</audio>';
     916
     917    return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id );
     918}
     919add_shortcode( 'audio', apply_filters( 'wp_audio_shortcode_handler', 'wp_audio_shortcode' ) );
     920
     921/**
     922 * Return a filtered list of WP-supported video formats
     923 *
     924 * @since 3.6.0
     925 * @return array
     926 */
     927function wp_get_video_extensions() {
     928    return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'wmv', 'flv' ) );
     929}
     930
     931/**
     932 * The Video shortcode.
     933 *
     934 * This implements the functionality of the Video Shortcode for displaying
     935 * WordPress mp4s in a post.
     936 *
     937 * @since 3.6.0
     938 *
     939 * @param array $attr Attributes of the shortcode.
     940 * @return string HTML content to display video.
     941 */
     942function wp_video_shortcode( $attr ) {
     943    global $content_width;
     944    $post_id = get_post() ? get_the_ID() : 0;
     945
     946    static $instances = 0;
     947    $instances++;
     948
     949    $video = null;
     950
     951    $default_types = wp_get_video_extensions();
     952    $defaults_atts = array(
     953        'src' => '',
     954        'poster' => '',
     955        'height' => 360,
     956        'width' => empty( $content_width ) ? 640 : $content_width,
     957    );
     958    foreach ( $default_types as $type  )
     959        $defaults_atts[$type] = '';
     960
     961    $atts = shortcode_atts( $defaults_atts, $attr );
     962    extract( $atts );
     963
     964    $primary = false;
     965    if ( ! empty( $src ) ) {
     966        $type = wp_check_filetype( $src );
     967        if ( ! in_array( $type['ext'], $default_types ) ) {
     968            printf( '<a class="wp-post-format-link-video" href="%1$s">%1$s</a>', $src );
     969            return;
     970        }
     971        $primary = true;
     972        array_unshift( $default_types, 'src' );
     973    } else {
     974        foreach ( $default_types as $ext ) {
     975            if ( ! empty( $$ext ) ) {
     976                $type = wp_check_filetype( $$ext );
     977                if ( $type['ext'] === $ext )
     978                    $primary = true;
     979            }
     980        }
     981    }
     982
     983    if ( ! $primary ) {
     984        $videos = get_post_video( $post_id );
     985        if ( empty( $videos ) )
     986            return;
     987
     988        $video = reset( $videos );
     989        $src = wp_get_attachment_url( $video->ID );
     990        if ( empty( $src ) )
     991            return;
     992
     993        array_unshift( $default_types, 'src' );
     994    }
     995
     996    $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' );
     997    if ( 'mediaelement' === $library ) {
     998        wp_enqueue_style( 'wp-mediaelement' );
     999        wp_enqueue_script( 'wp-mediaelement' );
     1000    }
     1001
     1002    $atts = array(
     1003        sprintf( 'class="%s"', apply_filters( 'wp_video_shortcode_class', 'wp-video-shortcode' ) ),
     1004        sprintf( 'id="video-%d-%d"', $post_id, $instances ),
     1005        sprintf( 'width="%d"', $width ),
     1006        sprintf( 'height="%d"', $height ),
     1007    );
     1008
     1009    if ( ! empty( $poster ) )
     1010        $atts[] = sprintf( 'poster="%s"', esc_url( $poster ) );
     1011
     1012    $html = sprintf( '<video %s controls="controls" preload="none">', join( ' ', $atts ) );
     1013
     1014    $fileurl = '';
     1015    $source = '<source type="%s" src="%s" />';
     1016    foreach ( $default_types as $fallback ) {
     1017        if ( ! empty( $$fallback ) ) {
     1018            if ( empty( $fileurl ) )
     1019                $fileurl = $$fallback;
     1020            $type = wp_check_filetype( $$fallback );
     1021            // m4v sometimes shows up as video/mpeg which collides with mp4
     1022            if ( 'm4v' === $type['ext'] )
     1023                $type['type'] = 'video/m4v';
     1024            $html .= sprintf( $source, $type['type'], $$fallback );
     1025        }
     1026    }
     1027    if ( 'mediaelement' === $library )
     1028        $html .= wp_mediaelement_fallback( $fileurl, $width, $height );
     1029    $html .= '</video>';
     1030
     1031    return apply_filters( 'wp_video_shortcode', $html, $atts, $video, $post_id );
     1032}
     1033add_shortcode( 'video', apply_filters( 'wp_video_shortcode_handler', 'wp_video_shortcode' ) );
    8071034
    8081035/**
     
    15461773    do_action( 'wp_enqueue_media' );
    15471774}
     1775
     1776/**
     1777 * Retrieve audio attached to the passed post
     1778 *
     1779 * @since 3.6.0
     1780 *
     1781 * @param int $post_id  Post ID
     1782 * @return array Found audio attachments
     1783 */
     1784function get_post_audio( $post_id = 0 ) {
     1785    $post = empty( $post_id ) ? get_post() : get_post( $post_id );
     1786    if ( empty( $post ) )
     1787        return;
     1788
     1789    $children = get_children( array(
     1790        'post_parent' => $post->ID,
     1791        'post_type' => 'attachment',
     1792        'post_mime_type' => 'audio',
     1793        'posts_per_page' => -1
     1794    ) );
     1795
     1796    if ( ! empty( $children ) )
     1797        return $children;
     1798}
     1799
     1800/**
     1801 * Retrieve video attached to the passed post
     1802 *
     1803 * @since 3.6.0
     1804 *
     1805 * @param int $post_id  Post ID
     1806 * @return array Found video attachments
     1807 */
     1808function get_post_video( $post_id = 0 ) {
     1809    $post = empty( $post_id ) ? get_post() : get_post( $post_id );
     1810    if ( empty( $post ) )
     1811        return;
     1812
     1813    $children = get_children( array(
     1814        'post_parent' => $post->ID,
     1815        'post_type' => 'attachment',
     1816        'post_mime_type' => 'video',
     1817        'posts_per_page' => -1
     1818    ) );
     1819
     1820    if ( ! empty( $children ) )
     1821        return $children;
     1822}
     1823
     1824/**
     1825 * Audio embed handler callback.
     1826 *
     1827 * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
     1828 * @param array $attr Embed attributes.
     1829 * @param string $url The original URL that was matched by the regex.
     1830 * @param array $rawattr The original unmodified attributes.
     1831 * @return string The embed HTML.
     1832 */
     1833function wp_audio_embed( $matches, $attr, $url, $rawattr ) {
     1834    $audio = $url;
     1835    if ( shortcode_exists( 'audio' ) )
     1836        $audio = do_shortcode( '[audio src="' . $url . '" /]' );
     1837    return apply_filters( 'wp_audio_embed', $audio, $attr, $url, $rawattr );
     1838}
     1839wp_embed_register_handler( 'wp_audio_embed', '#https?://.+?\.(' . join( '|', wp_get_audio_extensions() ) . ')#i', apply_filters( 'wp_audio_embed_handler', 'wp_audio_embed' ), 9999 );
     1840
     1841/**
     1842 * Video embed handler callback.
     1843 *
     1844 * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
     1845 * @param array $attr Embed attributes.
     1846 * @param string $url The original URL that was matched by the regex.
     1847 * @param array $rawattr The original unmodified attributes.
     1848 * @return string The embed HTML.
     1849 */
     1850function wp_video_embed( $matches, $attr, $url, $rawattr ) {
     1851    $dimensions = '';
     1852    $video = $url;
     1853    if ( shortcode_exists( 'video' ) ) {
     1854        if ( ! empty( $rawattr['width'] ) && ! empty( $rawattr['height'] ) ) {
     1855            $dimensions .= sprintf( 'width="%d" ', (int) $rawattr['width'] );
     1856            $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] );
     1857        }
     1858        $video = do_shortcode( '[video ' . $dimensions . 'src="' . $url . '" /]' );
     1859    }
     1860    return apply_filters( 'wp_video_embed', $video, $attr, $url, $rawattr );
     1861}
     1862wp_embed_register_handler( 'wp_video_embed', '#https?://.+?\.(' . join( '|', wp_get_video_extensions() ) . ')#i', apply_filters( 'wp_video_embed_handler', 'wp_video_embed' ), 9999 );
Note: See TracChangeset for help on using the changeset viewer.