<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[23729] trunk: Introduce [audio] and [video] shortcodes, and use MediaElement.js to play them.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg > ul, #logmsg > ol { margin-left: 0; margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://core.trac.wordpress.org/changeset/23729">23729</a></dd>
<dt>Author</dt> <dd>markjaquith</dd>
<dt>Date</dt> <dd>2013-03-16 05:25:44 +0000 (Sat, 16 Mar 2013)</dd>
</dl>
<h3>Log Message</h3>
<pre>Introduce [audio] and [video] shortcodes, and use MediaElement.js to play them.
props wonderboymusic. see <a href="http://core.trac.wordpress.org/ticket/23282">#23282</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkwpadminincludesajaxactionsphp">trunk/wp-admin/includes/ajax-actions.php</a></li>
<li><a href="#trunkwpincludesfunctionsphp">trunk/wp-includes/functions.php</a></li>
<li><a href="#trunkwpincludesjsmediaeditorjs">trunk/wp-includes/js/media-editor.js</a></li>
<li><a href="#trunkwpincludesmediaphp">trunk/wp-includes/media.php</a></li>
<li><a href="#trunkwpincludespostformatsphp">trunk/wp-includes/post-formats.php</a></li>
<li><a href="#trunkwpincludesscriptloaderphp">trunk/wp-includes/script-loader.php</a></li>
<li><a href="#trunkwpincludesshortcodesphp">trunk/wp-includes/shortcodes.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li>trunk/wp-includes/mediaelement/</li>
<li><a href="#trunkwpincludesmediaelementbackgroundpng">trunk/wp-includes/mediaelement/background.png</a></li>
<li><a href="#trunkwpincludesmediaelementbigplaypng">trunk/wp-includes/mediaelement/bigplay.png</a></li>
<li><a href="#trunkwpincludesmediaelementbigplaysvg">trunk/wp-includes/mediaelement/bigplay.svg</a></li>
<li><a href="#trunkwpincludesmediaelementcontrolspng">trunk/wp-includes/mediaelement/controls.png</a></li>
<li><a href="#trunkwpincludesmediaelementcontrolssvg">trunk/wp-includes/mediaelement/controls.svg</a></li>
<li><a href="#trunkwpincludesmediaelementflashmediaelementswf">trunk/wp-includes/mediaelement/flashmediaelement.swf</a></li>
<li><a href="#trunkwpincludesmediaelementloadinggif">trunk/wp-includes/mediaelement/loading.gif</a></li>
<li><a href="#trunkwpincludesmediaelementmediaelementandplayerjs">trunk/wp-includes/mediaelement/mediaelement-and-player.js</a></li>
<li><a href="#trunkwpincludesmediaelementmediaelementandplayerminjs">trunk/wp-includes/mediaelement/mediaelement-and-player.min.js</a></li>
<li><a href="#trunkwpincludesmediaelementmediaelementplayercss">trunk/wp-includes/mediaelement/mediaelementplayer.css</a></li>
<li><a href="#trunkwpincludesmediaelementmediaelementplayermincss">trunk/wp-includes/mediaelement/mediaelementplayer.min.css</a></li>
<li><a href="#trunkwpincludesmediaelementsilverlightmediaelementxap">trunk/wp-includes/mediaelement/silverlightmediaelement.xap</a></li>
<li><a href="#trunkwpincludesmediaelementwpmediaelementcss">trunk/wp-includes/mediaelement/wp-mediaelement.css</a></li>
<li><a href="#trunkwpincludesmediaelementwpmediaelementjs">trunk/wp-includes/mediaelement/wp-mediaelement.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkwpadminincludesajaxactionsphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-admin/includes/ajax-actions.php (23728 => 23729)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-admin/includes/ajax-actions.php        2013-03-16 04:58:37 UTC (rev 23728)
+++ trunk/wp-admin/includes/ajax-actions.php        2013-03-16 05:25:44 UTC (rev 23729)
</span><span class="lines">@@ -2019,6 +2019,8 @@
</span><span class="cx">                 $caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : '';
</span><span class="cx">                 $title = ''; // We no longer insert title tags into <img> tags, as they are redundant.
</span><span class="cx">                 $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
</span><ins>+        } elseif ( 'video' === substr( $post->post_mime_type, 0, 5 ) || 'audio' === substr( $post->post_mime_type, 0, 5 ) ) {
+                $html = stripslashes_deep( $_POST['html'] );
</ins><span class="cx">         }
</span><span class="cx">
</span><span class="cx">         $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment );
</span></span></pre></div>
<a id="trunkwpincludesfunctionsphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/functions.php (23728 => 23729)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/functions.php        2013-03-16 04:58:37 UTC (rev 23728)
+++ trunk/wp-includes/functions.php        2013-03-16 05:25:44 UTC (rev 23729)
</span><span class="lines">@@ -4020,3 +4020,23 @@
</span><span class="cx"> </script>
</span><span class="cx"> </div>' ) );
</span><span class="cx"> }
</span><ins>+
+/**
+ * Return RegEx body to liberally match an opening HTML tag that:
+ * 1. Is self-closing or
+ * 2. Has no body but has a closing tag of the same name or
+ * 3. Contains a body and a closing tag of the same name
+ *
+ * Note: this RegEx does not balance inner tags and does not attempt to produce valid HTML
+ *
+ * @since 3.6.0
+ *
+ * @param string $tag An HTML tag name. Example: 'video'
+ * @return string
+ */
+function get_tag_regex( $tag ) {
+        if ( empty( $tag ) )
+                return;
+
+        return sprintf( '(<%1$s[^>]*(?:/?>$|>[\s\S]*?</%1$s>))', tag_escape( $tag ) );
+}
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkwpincludesjsmediaeditorjs"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/js/media-editor.js (23728 => 23729)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/js/media-editor.js        2013-03-16 04:58:37 UTC (rev 23728)
+++ trunk/wp-includes/js/media-editor.js        2013-03-16 05:25:44 UTC (rev 23729)
</span><span class="lines">@@ -66,7 +66,8 @@
</span><span class="cx">                                         src: size.url,
</span><span class="cx">                                         captionId: 'attachment_' + attachment.id
</span><span class="cx">                                 });
</span><del>-
</del><ins>+                        } else if ( 'video' === attachment.type || 'audio' === attachment.type ) {
+                                _.extend( props, _.pick( attachment, 'title', 'type', 'icon', 'mime' ) );
</ins><span class="cx">                         // Format properties for non-images.
</span><span class="cx">                         } else {
</span><span class="cx">                                 props.title = props.title || attachment.filename;
</span><span class="lines">@@ -95,6 +96,89 @@
</span><span class="cx">                         return wp.html.string( options );
</span><span class="cx">                 },
</span><span class="cx">
</span><ins>+                audio: function( props, attachment ) {
+                        var shortcode, html;
+
+                        props = wp.media.string.props( props, attachment );
+
+                        shortcode = {};
+
+                        if ( props.mime ) {
+                                switch ( props.mime ) {
+                                case 'audio/mpeg':
+                                        if ( props.linkUrl.indexOf( 'mp3' ) )
+                                                shortcode.mp3 = props.linkUrl;
+                                        else if ( props.linkUrl.indexOf( 'm4a' ) )
+                                                shortcode.m4a = props.linkUrl;
+                                        break;
+                                case 'audio/mp3':
+                                        shortcode.mp3 = props.linkUrl;
+                                        break;
+                                case 'audio/m4a':
+                                        shortcode.m4a = props.linkUrl;
+                                        break;
+                                case 'audio/wav':
+                                        shortcode.wav = props.linkUrl;
+                                        break;
+                                case 'audio/ogg':
+                                        shortcode.ogg = props.linkUrl;
+                                        break;
+                                case 'audio/x-ms-wma':
+                                case 'audio/wma':
+                                        shortcode.wma = props.linkUrl;
+                                        break;
+                                }
+                        }
+
+                        html = wp.shortcode.string({
+                                tag: 'audio',
+                                attrs: shortcode
+                        });
+
+                        return html;
+                },
+
+                video: function( props, attachment ) {
+                        var shortcode, html;
+
+                        props = wp.media.string.props( props, attachment );
+
+                        shortcode = {};
+
+                        if ( props.mime ) {
+                                switch ( props.mime ) {
+                                case 'video/mp4':
+                                        shortcode.mp4 = props.linkUrl;
+                                        break;
+                                case 'video/m4v':
+                                        shortcode.m4v = props.linkUrl;
+                                        break;
+                                case 'video/webm':
+                                        shortcode.webm = props.linkUrl;
+                                        break;
+                                case 'video/ogg':
+                                        shortcode.ogv = props.linkUrl;
+                                        break;
+                                case 'video/x-ms-wmv':
+                                case 'video/wmv':
+                                case 'video/asf':
+                                        shortcode.wmv = props.linkUrl;
+                                        break;
+                                case 'video/flv':
+                                case 'video/x-flv':
+                                        shortcode.flv = props.linkUrl;
+                                        break;
+                                }
+                        }
+
+                        html = wp.shortcode.string({
+                                tag: 'video',
+                                attrs: shortcode
+                        });
+
+                        return html;
+                },
+
</ins><span class="cx">                 image: function( props, attachment ) {
</span><span class="cx">                         var img = {},
</span><span class="cx">                                 options, classes, shortcode, html;
</span><span class="lines">@@ -575,7 +659,10 @@
</span><span class="cx">                                                 if ( props[ prop ] )
</span><span class="cx">                                                         options[ option ] = props[ prop ];
</span><span class="cx">                                         });
</span><del>-
</del><ins>+                                } else if ( 'video' === attachment.type ) {
+                                        html = wp.media.string.video( props );
+                                } else if ( 'audio' === attachment.type ) {
+                                        html = wp.media.string.audio( props );
</ins><span class="cx">                                 } else {
</span><span class="cx">                                         html = wp.media.string.link( props );
</span><span class="cx">                                         options.post_title = props.title;
</span></span></pre></div>
<a id="trunkwpincludesmediaphp"></a>
<div class="modfile"><h4>Modified: trunk/wp-includes/media.php (23728 => 23729)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/media.php        2013-03-16 04:58:37 UTC (rev 23728)
+++ trunk/wp-includes/media.php        2013-03-16 05:25:44 UTC (rev 23729)
</span><span class="lines">@@ -806,6 +806,233 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> /**
</span><ins>+ * Provide a No-JS Flash fallback as a last resort for audio / video
+ *
+ * @since 3.6.0
+ *
+ * @param string $url
+ * @return string Fallback HTML
+ */
+function wp_mediaelement_fallback( $url ) {
+        return apply_filters( 'wp_mediaelement_fallback', sprintf( '<a href="%1$s">%1$s</a>', esc_url( $url ) ), $url );
+}
+
+/**
+ * Return a filtered list of WP-supported audio formats
+ *
+ * @since 3.6.0
+ * @return array
+ */
+function wp_get_audio_extensions() {
+        return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'wma', 'm4a', 'wav' ) );
+}
+
+/**
+ * The Audio shortcode.
+ *
+ * This implements the functionality of the Audio Shortcode for displaying
+ * WordPress mp3s in a post.
+ *
+ * @since 3.6.0
+ *
+ * @param array $attr Attributes of the shortcode.
+ * @return string HTML content to display audio.
+ */
+function wp_audio_shortcode( $attr ) {
+        $post_id = get_post() ? get_the_ID() : 0;
+
+        static $instances = 0;
+        $instances++;
+
+        $audio = null;
+
+        $default_types = wp_get_audio_extensions();
+        $defaults_atts = array( 'src' => '' );
+        foreach ( $default_types as $type )
+                $defaults_atts[$type] = '';
+
+        $atts = shortcode_atts( $defaults_atts, $attr );
+        extract( $atts );
+
+        $primary = false;
+        if ( ! empty( $src ) ) {
+                $type = wp_check_filetype( $src );
+                if ( ! in_array( $type['ext'], $default_types ) ) {
+                        printf( '<a class="wp-post-format-link-audio" href="%1$s">%1$s</a>', $src );
+                        return;
+                }
+                $primary = true;
+                array_unshift( $default_types, 'src' );
+        } else {
+                foreach ( $default_types as $ext ) {
+                        if ( ! empty( $$ext ) ) {
+                                $type = wp_check_filetype( $$ext );
+                                if ( $type['ext'] === $ext )
+                                        $primary = true;
+                        }
+                }
+        }
+
+        if ( ! $primary ) {
+                $audios = get_post_audio( $post_id );
+                if ( empty( $audios ) )
+                        return;
+
+                $audio = reset( $audios );
+                $src = wp_get_attachment_url( $audio->ID );
+                if ( empty( $src ) )
+                        return;
+
+                array_unshift( $default_types, 'src' );
+        }
+
+        $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
+        if ( 'mediaelement' === $library ) {
+                wp_enqueue_style( 'wp-mediaelement' );
+                wp_enqueue_script( 'wp-mediaelement' );
+        }
+
+        $atts = array(
+                sprintf( 'class="%s"', apply_filters( 'wp_audio_shortcode_class', 'wp-audio-shortcode' ) ),
+                sprintf( 'id="audio-%d-%d"', $post_id, $instances ),
+        );
+
+        $html = sprintf( '<audio %s controls="controls" preload="none">', join( ' ', $atts ) );
+
+        $fileurl = '';
+        $source = '<source type="%s" src="%s" />';
+        foreach ( $default_types as $fallback ) {
+                if ( ! empty( $$fallback ) ) {
+                        if ( empty( $fileurl ) )
+                                $fileurl = $$fallback;
+                        $type = wp_check_filetype( $$fallback );
+                        $html .= sprintf( $source, $type['type'], $$fallback );
+                }
+        }
+
+        if ( 'mediaelement' === $library )
+                $html .= wp_mediaelement_fallback( $fileurl );
+        $html .= '</audio>';
+
+        return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id );
+}
+add_shortcode( 'audio', apply_filters( 'wp_audio_shortcode_handler', 'wp_audio_shortcode' ) );
+
+/**
+ * Return a filtered list of WP-supported video formats
+ *
+ * @since 3.6.0
+ * @return array
+ */
+function wp_get_video_extensions() {
+        return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'wmv', 'flv' ) );
+}
+
+/**
+ * The Video shortcode.
+ *
+ * This implements the functionality of the Video Shortcode for displaying
+ * WordPress mp4s in a post.
+ *
+ * @since 3.6.0
+ *
+ * @param array $attr Attributes of the shortcode.
+ * @return string HTML content to display video.
+ */
+function wp_video_shortcode( $attr ) {
+        global $content_width;
+        $post_id = get_post() ? get_the_ID() : 0;
+
+        static $instances = 0;
+        $instances++;
+
+        $video = null;
+
+        $default_types = wp_get_video_extensions();
+        $defaults_atts = array(
+                'src' => '',
+                'poster' => '',
+                'height' => 360,
+                'width' => empty( $content_width ) ? 640 : $content_width,
+        );
+        foreach ( $default_types as $type )
+                $defaults_atts[$type] = '';
+
+        $atts = shortcode_atts( $defaults_atts, $attr );
+        extract( $atts );
+
+        $primary = false;
+        if ( ! empty( $src ) ) {
+                $type = wp_check_filetype( $src );
+                if ( ! in_array( $type['ext'], $default_types ) ) {
+                        printf( '<a class="wp-post-format-link-video" href="%1$s">%1$s</a>', $src );
+                        return;
+                }
+                $primary = true;
+                array_unshift( $default_types, 'src' );
+        } else {
+                foreach ( $default_types as $ext ) {
+                        if ( ! empty( $$ext ) ) {
+                                $type = wp_check_filetype( $$ext );
+                                if ( $type['ext'] === $ext )
+                                        $primary = true;
+                        }
+                }
+        }
+
+        if ( ! $primary ) {
+                $videos = get_post_video( $post_id );
+                if ( empty( $videos ) )
+                        return;
+
+                $video = reset( $videos );
+                $src = wp_get_attachment_url( $video->ID );
+                if ( empty( $src ) )
+                        return;
+
+                array_unshift( $default_types, 'src' );
+        }
+
+        $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' );
+        if ( 'mediaelement' === $library ) {
+                wp_enqueue_style( 'wp-mediaelement' );
+                wp_enqueue_script( 'wp-mediaelement' );
+        }
+
+        $atts = array(
+                sprintf( 'class="%s"', apply_filters( 'wp_video_shortcode_class', 'wp-video-shortcode' ) ),
+                sprintf( 'id="video-%d-%d"', $post_id, $instances ),
+                sprintf( 'width="%d"', $width ),
+                sprintf( 'height="%d"', $height ),
+        );
+
+        if ( ! empty( $poster ) )
+                $atts[] = sprintf( 'poster="%s"', esc_url( $poster ) );
+
+        $html = sprintf( '<video %s controls="controls" preload="none">', join( ' ', $atts ) );
+
+        $fileurl = '';
+        $source = '<source type="%s" src="%s" />';
+        foreach ( $default_types as $fallback ) {
+                if ( ! empty( $$fallback ) ) {
+                        if ( empty( $fileurl ) )
+                                $fileurl = $$fallback;
+                        $type = wp_check_filetype( $$fallback );
+                        // m4v sometimes shows up as video/mpeg which collides with mp4
+                        if ( 'm4v' === $type['ext'] )
+                                $type['type'] = 'video/m4v';
+                        $html .= sprintf( $source, $type['type'], $$fallback );
+                }
+        }
+        if ( 'mediaelement' === $library )
+                $html .= wp_mediaelement_fallback( $fileurl, $width, $height );
+        $html .= '</video>';
+
+        return apply_filters( 'wp_video_shortcode', $html, $atts, $video, $post_id );
+}
+add_shortcode( 'video', apply_filters( 'wp_video_shortcode_handler', 'wp_video_shortcode' ) );
+
+/**
</ins><span class="cx"> * Display previous image link that has the same post parent.
</span><span class="cx"> *
</span><span class="cx"> * @since 2.5.0
</span><span class="lines">@@ -1545,3 +1772,91 @@
</span><span class="cx">
</span><span class="cx">         do_action( 'wp_enqueue_media' );
</span><span class="cx"> }
</span><ins>+
+/**
+ * Retrieve audio attached to the passed post
+ *
+ * @since 3.6.0
+ *
+ * @param int $post_id Post ID
+ * @return array Found audio attachments
+ */
+function get_post_audio( $post_id = 0 ) {
+        $post = empty( $post_id ) ? get_post() : get_post( $post_id );
+        if ( empty( $post ) )
+                return;
+
+        $children = get_children( array(
+                'post_parent' => $post->ID,
+                'post_type' => 'attachment',
+                'post_mime_type' => 'audio',
+                'posts_per_page' => -1
+        ) );
+
+        if ( ! empty( $children ) )
+                return $children;
+}
+
+/**
+ * Retrieve video attached to the passed post
+ *
+ * @since 3.6.0
+ *
+ * @param int $post_id Post ID
+ * @return array Found video attachments
+ */
+function get_post_video( $post_id = 0 ) {
+        $post = empty( $post_id ) ? get_post() : get_post( $post_id );
+        if ( empty( $post ) )
+                return;
+
+        $children = get_children( array(
+                'post_parent' => $post->ID,
+                'post_type' => 'attachment',
+                'post_mime_type' => 'video',
+                'posts_per_page' => -1
+        ) );
+
+        if ( ! empty( $children ) )
+                return $children;
+}
+
+/**
+ * Audio embed handler callback.
+ *
+ * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
+ * @param array $attr Embed attributes.
+ * @param string $url The original URL that was matched by the regex.
+ * @param array $rawattr The original unmodified attributes.
+ * @return string The embed HTML.
+ */
+function wp_audio_embed( $matches, $attr, $url, $rawattr ) {
+        $audio = $url;
+        if ( shortcode_exists( 'audio' ) )
+                $audio = do_shortcode( '[audio src="' . $url . '" /]' );
+        return apply_filters( 'wp_audio_embed', $audio, $attr, $url, $rawattr );
+}
+wp_embed_register_handler( 'wp_audio_embed', '#https?://.+?\.(' . join( '|', wp_get_audio_extensions() ) . ')#i', apply_filters( 'wp_audio_embed_handler', 'wp_audio_embed' ), 9999 );
+
+/**
+ * Video embed handler callback.
+ *
+ * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}.
+ * @param array $attr Embed attributes.
+ * @param string $url The original URL that was matched by the regex.
+ * @param array $rawattr The original unmodified attributes.
+ * @return string The embed HTML.
+ */
+function wp_video_embed( $matches, $attr, $url, $rawattr ) {
+        $dimensions = '';
+        $video = $url;
+        if ( shortcode_exists( 'video' ) ) {
+                if ( ! empty( $rawattr['width'] ) && ! empty( $rawattr['height'] ) ) {
+                        $dimensions .= sprintf( 'width="%d" ', (int) $rawattr['width'] );
+                        $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] );
+                }
+                $video = do_shortcode( '[video ' . $dimensions . 'src="' . $url . '" /]' );
+        }
+        return apply_filters( 'wp_video_embed', $video, $attr, $url, $rawattr );
+}
+wp_embed_register_handler( 'wp_video_embed', '#https?://.+?\.(' . join( '|', wp_get_video_extensions() ) . ')#i', apply_filters( 'wp_video_embed_handler', 'wp_video_embed' ), 9999 );
</ins></span></pre></div>
<a id="trunkwpincludesmediaelementbackgroundpng"></a>
<div class="addfile"><h4>Added: trunk/wp-includes/mediaelement/background.png (0 => 23729)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/mediaelement/background.png         (rev 0)
+++ trunk/wp-includes/mediaelement/background.png        2013-03-16 05:25:44 UTC (rev 23729)
</span><span class="lines">@@ -0,0 +1,4 @@
</span><ins>+\x89PNG
+
+
+IHDR 2 2 ?\x88\xB1 tEXtSoftware Adobe ImageReadyq\xC9e< HIDATx\xDA\xEC\xCF1 \xB1\xFFnj\xBD\xC4AN5-p[BDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\xE4\x8F'\xC0 D\x8D\xB8\xEFy\x8C IEND\xAEB`\x82
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkwpincludesmediaelementbigplaypng"></a>
<div class="addfile"><h4>Added: trunk/wp-includes/mediaelement/bigplay.png (0 => 23729)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/wp-includes/mediaelement/bigplay.png         (rev 0)
+++ trunk/wp-includes/mediaelement/bigplay.png        2013-03-16 05:25:44 UTC (rev 23729)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+\x89PNG
+
+
+IHDR d \xC8 )\xE2\xB4\xF3 sBIT\xDB\xE1O\xE0 \xD2PLTE\xFF\xFF\xFF\xCC\xCC\xCC \xCC\xCC\xCC \xCC\xCC\xCC \xD6\xD6\xD6\xCC\xCC\xCC \xDE\xDE\xDE\xD6\xD6\xD6ZZZQQQJJJAAA999333)))!!!\xE6\xE6\xE6\xDE\xDE\xDE|||ssskkkfffZZZQQQ\xEF\xEF\xEF\xE6\xE6晙\x99\x94\x94\x94\x8C\x8C\x8C\x84\x84\x84|||\xEF\xEF\xEF\xE6\xE6浵\xB5\xAD\xAD\xAD\xA4\xA4\xA4\x99\x99\x99\xF7\xF7\xF7\xEF\xEF\xEF\xCC\xCC\xCC\xC5\xC5ž\xBE\xBE\xB5\xB5\xB5\xF7\xF7\xF7\xD6\xD6\xD6\xCC\xCC\xCC\xC5\xC5\xC5\xF7\xF7\xF7\xDE\xDE\xDE\xD6\xD6\xD6\xFF\xFF\xFF\xF7\xF7\xF7\xE6\xE6\xE6\xDE\xDE\xDE\xFF\xFF\xFF\xF7\xF7\xF7\xEF\xEF\xEF\xE6\xE6\xE6\xFF\xFF\xFF\xF7\xF7\xF7\xFF\xFF\xFF\xF7\xF7\xF7\x94?\xB4P FtRNS ""33DDDDDDUUUUUUUUUUUffffffffwwwwwww\x88\x88\x88\x88\x88\x88\x99\x99\x99\x99\x99\x99\xAA\xAA\xAA\xAA\xBB\xBB\xBB\xCC\xCC\xCC\xCC\xDD\xDD\xDD\xDD\xEE\xEE\xFF\xFFE+:         pHYs