diff --git wp-admin/includes/ajax-actions.php wp-admin/includes/ajax-actions.php
index bd4d5b9..b0f2c0c 100644
--- wp-admin/includes/ajax-actions.php
+++ wp-admin/includes/ajax-actions.php
@@ -2030,6 +2030,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 );
@@ -2086,7 +2088,7 @@ function wp_ajax_heartbeat() {
 		$screen_id = sanitize_key($_POST['screenid']);
 	else
 		$screen_id = 'site';
-	
+
 	if ( ! empty($_POST['data']) ) {
 		$data = wp_unslash( (array) $_POST['data'] );
 		// todo: how much to sanitize and preset and what to leave to be accessed from $data or $_POST..?
diff --git wp-includes/functions.php wp-includes/functions.php
index cbd7925..5ac68c7 100644
--- wp-includes/functions.php
+++ wp-includes/functions.php
@@ -3883,4 +3883,24 @@ function wp_is_stream( $path ) {
  */
 function wp_checkdate( $month, $day, $year, $source_date ) {
 	return apply_filters( 'wp_checkdate', checkdate( $month, $day, $year ), $source_date );
+}
+
+/**
+ * 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..1b5f844 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,70 @@
 			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':
+					shortcode.mp3 = props.linkUrl;
+					break;
+				case 'audio/ogg':
+					shortcode.ogg = props.linkUrl;
+					break;
+				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/webm':
+					shortcode.webm = props.linkUrl;
+					break;
+				case 'video/ogg':
+					shortcode.ogv = props.linkUrl;
+					break;
+				case 'video/asf':
+					shortcode.wmv = props.linkUrl;
+					break;
+				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 +640,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 f1f3737..07b3fc1 100644
--- wp-includes/media.php
+++ wp-includes/media.php
@@ -803,6 +803,168 @@ function gallery_shortcode($attr) {
 }
 
 /**
+ * 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 = get_post();
+
+	static $instances = 0;
+	$instances++;
+
+	$audio = null;
+
+	$defaults = array(
+		'mp3' => '',
+		'ogg' => '',
+		'wma' => ''
+	);
+	extract( shortcode_atts( $defaults, $attr ) );
+
+	$primary = false;
+	foreach ( array_keys( $defaults ) 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;
+
+		$type = wp_check_filetype( $src );
+		if ( ! in_array( $type['ext'], array_keys( $defaults ) ) ) {
+			printf( '<a href="%1$s">%1$s</a>', $src );
+			return;
+		}
+		$defaults['src'] = '';
+	}
+
+	wp_enqueue_style( 'wp-mediaelement' );
+	wp_enqueue_script( 'wp-mediaelement' );
+
+	$atts = array(
+		sprintf( 'class="%s"', apply_filters( 'audio_shortcode_class', 'wp-audio-shortcode' ) ),
+		sprintf( 'id="audio-%d-%d"', $post->ID, $instances ),
+	);
+
+	$html = sprintf( '<audio %s controls="controls" preload="none">', join( ' ', $atts ) );
+
+	$source = '<source type="%s" src="%s" />';
+	foreach ( array_keys( $defaults ) as $fallback ) {
+		if ( ! empty( $$fallback ) ) {
+			$type = wp_check_filetype( $$fallback );
+			$html .= sprintf( $source, $type['type'], $$fallback );
+		}
+	}
+
+	$html .= '</audio>';
+
+	return apply_filters( 'audio_shortcode', $html, $src, $audio, $post );
+}
+add_shortcode( 'audio', 'wp_audio_shortcode' );
+
+/**
+ * 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 = get_post();
+
+	static $instances = 0;
+	$instances++;
+
+	$video = null;
+
+	$default_types = array( 'mp4', 'webm', 'ogv', 'wmv', 'flv' );
+
+	extract( shortcode_atts( array(
+		'width' => empty( $content_width ) ? 640 : $content_width,
+		'height' => 360,
+		'poster' => '',
+	), $attr ) );
+
+	$primary = false;
+	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;
+
+		$type = wp_check_filetype( $src );
+		if ( ! in_array( $type['ext'], $default_types ) ) {
+			printf( '<a href="%1$s">%1$s</a>', $src );
+			return;
+		}
+
+		array_unshift( $default_types, 'src' );
+	}
+
+	wp_enqueue_style( 'wp-mediaelement' );
+	wp_enqueue_script( 'wp-mediaelement' );
+
+	$atts = array(
+		sprintf( 'class="%s"', apply_filters( '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 ) );
+
+	$source = '<source type="%s" src="%s" />';
+	foreach ( $default_types as $fallback ) {
+		if ( ! empty( $$fallback ) ) {
+			$type = wp_check_filetype( $$fallback );
+			$html .= sprintf( $source, $type['type'], $$fallback );
+		}
+	}
+
+	$html .= '</video>';
+
+	return apply_filters( 'video_shortcode', $html, $src, $video, $post );
+}
+add_shortcode( 'video', 'wp_video_shortcode' );
+
+/**
  * Display previous image link that has the same post parent.
  *
  * @since 2.5.0
@@ -1542,3 +1704,185 @@ 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;
+}
+
+/**
+ * Check the content blob for an <audio>, <object>, <embed>, or <iframe>, in that order
+ * If no HTML tag is found, check the first line of the post for a URL
+ *
+ * @param string $content A string which might contain audio data.
+ * @param boolean $remove Whether to remove the found URL from the passed content.
+ * @return string The found data
+ */
+function get_content_audio( &$content, $remove = false ) {
+	$html = $matches = '';
+	foreach ( array( 'audio', 'object', 'embed', 'iframe' ) as $tag ) {
+		if ( preg_match( '#' . get_tag_regex( $tag ) . '#', $content, $matches ) ) {
+			$html = $matches[1];
+			if ( $remove )
+				$content = str_replace( $matches[0], '', $content );
+
+			return $html;
+		}
+	}
+
+	$lines = explode( "\n", trim( $content ) );
+	$line = trim( array_shift( $lines  ) );
+
+	if ( 0 === stripos( $line, 'http' ) ) {
+		if ( $remove )
+			$content = join( "\n", $lines );
+
+		return $line;
+	}
+}
+
+/**
+ * Return the found audio data for the passed post
+ *
+ * @since 3.6.0
+ *
+ * @param int $id Optional. Post ID
+ */
+function get_the_audio( $id = 0 ) {
+	$post = empty( $id ) ? get_post() : get_post( $id );
+	if ( empty( $post ) )
+		return;
+
+	if ( shortcode_exists( 'audio' ) )
+		return do_shortcode( '[audio /]' );
+
+	$data = get_content_audio( $post->post_content );
+	if ( ! empty( $data ) )
+		return $data;
+
+	$audios = get_post_audio( $post->ID );
+	if ( empty( $audios ) )
+		return;
+
+	$audio = reset( $audios );
+	return wp_get_attachment_url( $audio->ID );
+}
+
+/**
+ * Output the found audio data for the current post
+ *
+ * @since 3.6.0
+ */
+function the_audio() {
+	echo apply_filters( 'the_audio', get_the_audio() );
+}
+
+/**
+ * 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;
+}
+
+/**
+ * Check the content blob for a <video>, <object>, <embed>, or <iframe>, in that order
+ * If no HTML tag is found, check the first line of the post for a URL
+ *
+ * @param string $content A string which might contain video data.
+ * @param boolean $remove Whether to remove the found URL from the passed content.
+ * @return string The found data
+ */
+function get_content_video( &$content, $remove = false ) {
+	$html = $matches = '';
+	foreach ( array( 'video', 'object', 'embed', 'iframe' ) as $tag ) {
+		if ( preg_match( '#' . get_tag_regex( $tag ) . '#', $content, $matches ) ) {
+			$html = $matches[1];
+			if ( $remove )
+				$content = str_replace( $matches[0], '', $content );
+
+			return $html;
+		}
+	}
+
+	$lines = explode( "\n", trim( $content ) );
+	$line = trim( array_shift( $lines  ) );
+
+	if ( 0 === stripos( $line, 'http' ) ) {
+		if ( $remove )
+			$content = join( "\n", $lines );
+
+		return $line;
+	}
+}
+
+/**
+ * Return the found video data for the passed post
+ *
+ * @since 3.6.0
+ *
+ * @param int $id Optional. Post ID
+ */
+function get_the_video( $id = 0 ) {
+	$post = empty( $id ) ? get_post() : get_post( $id );
+	if ( empty( $post ) )
+		return;
+
+	if ( shortcode_exists( 'video' ) )
+		return do_shortcode( '[video /]' );
+
+	$data = get_content_video( $post->post_content );
+	if ( ! empty( $data ) )
+		return $data;
+
+	$videos = get_post_video( $post->ID );
+	if ( empty( $videos ) )
+		return;
+
+	$video = reset( $videos );
+	return wp_get_attachment_url( $video->ID );
+}
+
+/**
+ * Output the found video data for the current post
+ *
+ * @since 3.6.0
+ */
+function the_video() {
+	echo apply_filters( 'the_video', get_the_video() );
+}
\ No newline at end of file
diff --git wp-includes/post-formats.php wp-includes/post-formats.php
index 6d32aea..fa1f38b 100644
--- wp-includes/post-formats.php
+++ wp-includes/post-formats.php
@@ -386,7 +386,8 @@ function post_formats_compat( $content, $id = 0 ) {
 		case 'video':
 		case 'audio':
 			$shortcode_regex = '/' . get_shortcode_regex() . '/s';
-			$matches = preg_match( $shortcode_regex, $content );
+			preg_match( $shortcode_regex, $content, $matches );
+
 			if ( ! $matches || $format !== $matches[2] ) {
 				if ( empty( $meta['media'] ) && ! empty( $compat[$format] ) ) {
 					$format_output .= $compat[$format];
@@ -398,6 +399,50 @@ function post_formats_compat( $content, $id = 0 ) {
 						// attempt to embed the URL
 						$format_output .= sprintf( '[embed]%s[/embed]', $meta['media'] );
 					}
+				} elseif ( empty( $meta['media'] ) ) {
+					$data = '';
+					// attempt to grab an embed code or URL from the content
+					if ( 'audio' === $format ) {
+						$data = get_content_audio( $content, true );
+					} elseif ( 'video' === $format ) {
+						$data = get_content_video( $content, true );
+					}
+
+					if ( ! empty( $data ) ) {
+						// attempt to embed the URL
+						if ( 0 === stripos( $data, 'http' ) )
+							$format_output .= sprintf( '[embed]%s[/embed]', $data );
+						else // data is probably an embed code
+							$format_output .= $data;
+					} elseif ( 'audio' === $format ) {
+						// get attached audio URL
+						$audios = get_post_audio( $post->ID );
+						if ( ! empty( $audios ) ) {
+							$audio = reset( $audios );
+							$url = wp_get_attachment_url( $audio->ID );
+							// core or plugin support for [audio]
+							if ( shortcode_exists( 'audio' ) ) {
+								$format_output .= sprintf( '[audio src="%s"/]', $url );
+							} else {
+								// no support detected, just add URL
+								$format_output .= sprintf( '<a href="%1$s">%1$s</a>', $url );
+							}
+						}
+					} elseif ( 'video' === $format ) {
+						// get attached video URL
+						$videos = get_post_video( $post->ID );
+						if ( ! empty( $videos ) ) {
+							$video = reset( $videos );
+							$url = wp_get_attachment_url( $video->ID );
+							// core or plugin support for [video]
+							if ( shortcode_exists( 'video' ) ) {
+								$format_output .= sprintf( '[video src="%s"/]', $url );
+							} else {
+								// no support detected, just add URL link
+								$format_output .= sprintf( '<a href="%1$s">%1$s</a>', $url );
+							}
+						}
+					}
 				}
 			}
 			break;
diff --git wp-includes/script-loader.php wp-includes/script-loader.php
index cfb865e..2e5e527 100644
--- wp-includes/script-loader.php
+++ wp-includes/script-loader.php
@@ -274,6 +274,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'),
@@ -538,6 +541,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 2dfc277..716dae4 100644
--- wp-includes/shortcodes.php
+++ wp-includes/shortcodes.php
@@ -128,6 +128,20 @@ 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 );
+}
+
+/**
  * Search content for shortcodes and filter shortcodes through their hooks.
  *
  * If there are no shortcode tags defined, then the content will be returned
