diff --git wp-admin/includes/ajax-actions.php wp-admin/includes/ajax-actions.php
index 8581c9e..93a897f 100644
--- wp-admin/includes/ajax-actions.php
+++ wp-admin/includes/ajax-actions.php
@@ -2024,6 +2024,8 @@ function wp_ajax_send_attachment_to_editor() {
 		$caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : '';
 		$title = ''; // We no longer insert title tags into <img> tags, as they are redundant.
 		$html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt );
+	} elseif ( 'video' === substr( $post->post_mime_type, 0, 5 ) || 'audio' === substr( $post->post_mime_type, 0, 5 )  ) {
+		$html = stripslashes_deep( $_POST['html'] );
 	}
 
 	$html = apply_filters( 'media_send_to_editor', $html, $id, $attachment );
diff --git wp-includes/functions.php wp-includes/functions.php
index b29b941..78dedb6 100644
--- wp-includes/functions.php
+++ wp-includes/functions.php
@@ -4020,3 +4020,23 @@ $("#wp-auth-check-form iframe").load(function(){
 </script>
 </div>' ) );
 }
+
+/**
+ * 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 ) );
+}
\ No newline at end of file
diff --git wp-includes/js/media-editor.js wp-includes/js/media-editor.js
index 15eff8d..7dbbb79 100644
--- wp-includes/js/media-editor.js
+++ wp-includes/js/media-editor.js
@@ -66,7 +66,8 @@
 					src:       size.url,
 					captionId: 'attachment_' + attachment.id
 				});
-
+			} else if ( 'video' === attachment.type || 'audio' === attachment.type ) {
+				_.extend( props, _.pick( attachment, 'title', 'type', 'icon', 'mime' ) );
 			// Format properties for non-images.
 			} else {
 				props.title = props.title || attachment.filename;
@@ -95,6 +96,89 @@
 			return wp.html.string( options );
 		},
 
+		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;
+		},
+
 		image: function( props, attachment ) {
 			var img = {},
 				options, classes, shortcode, html;
@@ -575,7 +659,10 @@
 						if ( props[ prop ] )
 							options[ option ] = props[ prop ];
 					});
-
+				} else if ( 'video' === attachment.type ) {
+					html = wp.media.string.video( props );
+				} else if ( 'audio' === attachment.type ) {
+					html = wp.media.string.audio( props );
 				} else {
 					html = wp.media.string.link( props );
 					options.post_title = props.title;
diff --git wp-includes/media.php wp-includes/media.php
index c543389..5b65f3d 100644
--- wp-includes/media.php
+++ wp-includes/media.php
@@ -803,6 +803,233 @@ function gallery_shortcode($attr) {
 }
 
 /**
+ * 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' ) );
+
+/**
  * Display previous image link that has the same post parent.
  *
  * @since 2.5.0
@@ -1542,3 +1769,91 @@ function wp_enqueue_media( $args = array() ) {
 
 	do_action( 'wp_enqueue_media' );
 }
+
+/**
+ * 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 );
diff --git wp-includes/post-formats.php wp-includes/post-formats.php
index 828447b..7dfc171 100644
--- wp-includes/post-formats.php
+++ wp-includes/post-formats.php
@@ -308,6 +308,8 @@ function post_formats_compat( $content, $id = 0 ) {
 	$show_content = true;
 	$format_output = '';
 	$meta = get_post_format_meta( $post->ID );
+	// passed by ref in preg_match()
+	$matches = array();
 
 	switch ( $format ) {
 		case 'link':
@@ -365,34 +367,21 @@ function post_formats_compat( $content, $id = 0 ) {
 			break;
 
 		case 'gallery':
-			preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches );
-			if ( ! empty( $matches ) && isset( $matches[2] ) ) {
-				foreach ( (array) $matches[2] as $match ) {
-					if ( 'gallery' === $match )
-						break 2; // foreach + case
-				}
-			}
-
-			if ( ! empty( $meta['gallery'] ) ) {
+			if ( ! has_shortcode( $post->post_content, $format ) && ! empty( $meta['gallery'] ) )
 				$format_output .= $meta['gallery'];
-			}
 			break;
 
 		case 'video':
 		case 'audio':
-			$shortcode_regex = '/' . get_shortcode_regex() . '/s';
-			$matches = preg_match( $shortcode_regex, $content );
-			if ( ! $matches || $format !== $matches[2] ) {
-				if ( ! empty( $meta['media'] ) ) {
-					// the metadata is a shortcode or an embed code
-					if ( preg_match( $shortcode_regex, $meta['media'] ) || preg_match( '#<[^>]+>#', $meta['media'] ) ) {
-						$format_output .= $meta['media'];
-					} elseif ( ! stristr( $content, $meta['media'] ) ) {
-						// attempt to embed the URL
-						$format_output .= sprintf( '[embed]%s[/embed]', $meta['media'] );
-					}
+			if ( ! has_shortcode( $post->post_content, $format ) && ! empty( $meta['media'] ) ) {
+				// the metadata is a shortcode or an embed code
+				if ( preg_match( '/' . get_shortcode_regex() . '/s', $meta['media'] ) || preg_match( '#<[^>]+>#', $meta['media'] ) ) {
+					$format_output .= $meta['media'];
+				} elseif ( ! stristr( $content, $meta['media'] ) ) {
+					// attempt to embed the URL
+					$format_output .= sprintf( '[embed]%s[/embed]', $meta['media'] );
 				}
-			}
+			}
 			break;
 		default:
 			return $content;
diff --git wp-includes/script-loader.php wp-includes/script-loader.php
index 84b76d3..bf3e4fb 100644
--- wp-includes/script-loader.php
+++ wp-includes/script-loader.php
@@ -277,6 +277,9 @@ function wp_default_scripts( &$scripts ) {
 
 	$scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.8', 1 );
 
+	$scripts->add( 'mediaelement', "/wp-includes/js/mediaelement/mediaelement-and-player$suffix.js", array('jquery'), '2.10.1', 1 );
+	$scripts->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement.js", array('mediaelement'), false, 1 );
+
 	$scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array('jquery'), false, 1 );
 	did_action( 'init' ) && $scripts->localize( 'password-strength-meter', 'pwsL10n', array(
 		'empty' => __('Strength indicator'),
@@ -543,6 +546,9 @@ function wp_default_styles( &$styles ) {
 	$styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons' ) );
 	$styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" );
 
+	$styles->add( 'mediaelement', "/wp-includes/js/mediaelement/mediaelementplayer$suffix.css" );
+	$styles->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement.css", array( 'mediaelement' ) );
+
 	foreach ( $rtl_styles as $rtl_style ) {
 		$styles->add_data( $rtl_style, 'rtl', true );
 		if ( $suffix && ! in_array( $rtl_style, $no_suffix ) )
diff --git wp-includes/shortcodes.php wp-includes/shortcodes.php
index bdc3f9b..b7a0b1b 100644
--- wp-includes/shortcodes.php
+++ wp-includes/shortcodes.php
@@ -128,6 +128,44 @@ function remove_all_shortcodes() {
 }
 
 /**
+ * Whether a registered shortcode exists named $tag
+ *
+ * @since 3.6.0
+ *
+ * @global array $shortcode_tags
+ * @param string $tag
+ * @return boolean
+ */
+function shortcode_exists( $tag ) {
+	global $shortcode_tags;
+	return array_key_exists( $tag, $shortcode_tags );
+}
+
+/**
+ * Whether the passed content contains the specified shortcode
+ *
+ * @since 3.6.0
+ *
+ * @global array $shortcode_tags
+ * @param string $tag
+ * @return boolean
+ */
+function has_shortcode( $content, $tag ) {
+	if ( shortcode_exists( $tag ) ) {
+		$matches = array();
+		preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
+		if ( empty( $matches ) )
+			return false;
+
+		foreach ( $matches as $shortcode ) {
+			if ( $tag === $shortcode[2] )
+				return true;
+		}
+	}
+	return false;
+}
+
+/**
  * Search content for shortcodes and filter shortcodes through their hooks.
  *
  * If there are no shortcode tags defined, then the content will be returned
