File: /home/mmickelson/theflexguys.com/baronconstruct/wp-content/plugins/video/video.php
<?php
/**
* @package video
* @category video
* @author Automattic Inc
* @link http://automattic.com/wordpress-plugins/#videopress VideoPress
* @version 1.3
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
/*
Plugin Name: VideoPress
Plugin URI: http://wordpress.org/extend/plugins/video/
Description: Upload new videos to <a href="http://videopress.com/">VideoPress</a>, edit metadata, and easily insert VideoPress videos into posts and pages using shortcodes. Requires a <a href="http://wordpress.com/">WordPress.com</a> account and a WordPress.com blog with the <a href="http://en.wordpress.com/products/#videopress">VideoPress upgrade</a>.
Author: Automattic, Niall Kennedy, Joseph Scott
Contributor: Hailin Wu
Author URI: http://automattic.com/wordpress-plugins/#videopress
Version: 1.3
Stable tag: 1.2.2
License: GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
include_once( dirname(__FILE__) . '/settings.php' );
add_action( 'media_buttons', 'videopress_media_buttons', 999 );
/**
* Add a video button to the post composition screen
* @since 0.1.0
*/
function videopress_media_buttons( ) {
echo '<a href="https://public-api.wordpress.com/videopress-plugin.php?page=video-plugin&video_plugin=1&iframe&TB_iframe=true" id="add_video" class="thickbox" title="VideoPress"><img src="';
echo esc_url( plugins_url( ) . '/' . dirname( plugin_basename( __FILE__ ) ) . '/camera-video.png' );
echo '" alt="VideoPress" width="16" height="16" /></a>';
}
//allow either [videopress xyz] or [wpvideo xyz] for backward compatibility
add_shortcode( 'videopress', 'videopress_shortcode' );
add_shortcode( 'wpvideo', 'videopress_shortcode' );
/**
* Validate user-supplied guid values against expected inputs
*
* @since 1.1
* @param string $guid video identifier
* @return bool true if passes validation test
*/
function __videopress_is_valid_guid( $guid ) {
if ( !empty($guid) && ctype_alnum($guid))
return true;
else
return false;
}
/**
* Search a given content string for VideoPress shortcodes. Return an array of shortcodes with guid and attribute values.
*
* @see do_shortcode()
* @param string $content post content string
* @return array Array of shortcode data. GUID as the key and other customization parameters as value. empty array if no matches found.
*/
function find_all_videopress_shortcodes( $content ) {
$r = preg_match_all( '/(.?)\[(wpvideo)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)/s', $content, $matches, PREG_SET_ORDER );
if ( $r === false || $r === 0 )
return array();
$guids = array();
foreach ( $matches as $m ) {
// allow [[foo]] syntax for escaping a tag
if ( $m[1] == '[' && $m[6] == ']' )
continue;
$attr = shortcode_parse_atts( $m[3] );
if ( __videopress_is_valid_guid( $attr[0] ) ) {
$guid = $attr[0];
unset( $attr[0] );
$guids[$guid] = $attr;
}
}
return $guids;
}
/**
* Insert video handlers into HTML <head> if posts with video shortcodes exist.
* If video posts are present then queue VideoPress JavaScript files.
* If a video is present and is single post or page then add Open Graph protocol markup for first video found
*/
function videopress_embed_head() {
global $posts;
if ( is_feed() || !is_array($posts) )
return;
$guid = '';
foreach ($posts as $post) {
$guids = find_all_videopress_shortcodes( $post->post_content );
if ( !empty($guids) ) {
$guid = trim( key($guids) );
break;
}
unset( $guids );
}
if ( !empty($guid) ) {
add_action( 'wp_enqueue_scripts', 'videopress_embed_load_scripts', 20 );
}
return;
}
add_action( 'wp_head', 'videopress_embed_head', -1 ); // load before enqueue_scripts
/**
* Add VideoPress JavaScript files to the script queue.
*
* @uses wp_enqueue_script()
*/
function videopress_embed_load_scripts() {
$scheme = is_ssl() ? 'https://' : 'http://';
wp_enqueue_script( 'swfobject', $scheme . 'ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js', false. '2.2' );
wp_enqueue_script( 'jquery' );
if ( is_ssl() )
$vpjs = 'https://v0.wordpress.com/js/videopress.js';
else
$vpjs = 'http://s0.videopress.com/js/videopress.js';
wp_enqueue_script( 'videopress', $vpjs, array('jquery'), '1.03' );
}
/**
* Extract the site's host domain for statistics and comparison against an allowed site list in the case of restricted embeds.
*
* @since 1.2
* @param string $url absolute URL
* @return bool|string host component of the URL, or false if none found
*/
function videopress_host( $url ) {
if ( empty($url) || !function_exists('parse_url') )
return false;
if ( version_compare(PHP_VERSION, '5.1.2', '>=') ) {
return parse_url($url, PHP_URL_HOST);
} else {
$url_parts = parse_url($url);
if ( $url_parts!==false && isset($url_parts['host']) )
return $url_parts['host'];
}
}
/**
* Prepare key-value pairs for inclusion as an URI's query parameters
* Emulate http_build_query if current version of PHP does not include the function.
*
* @since 1.2
* @uses build_http_query if present
* @param array $args key-value pairs to include as query parameters
* @return string prepped query parameter string
*/
function videopress_http_build_query( $args ) {
if ( function_exists('http_build_query') ) {
return http_build_query( $args, '', '&' );
}
else {
$str_builder = array();
foreach ( $args as $key => $value ) {
$str_builder[] = urlencode($key) . '=' . urlencode($value);
}
return implode('&', $str_builder);
}
}
/**
* Only allow legitimate Flash parameters and their values
*
* @since 1.2
* @link http://kb2.adobe.com/cps/127/tn_12701.html Flash object and embed attributes
* @link http://kb2.adobe.com/cps/133/tn_13331.html devicefont
* @link http://kb2.adobe.com/cps/164/tn_16494.html allowscriptaccess
* @link http://www.adobe.com/devnet/flashplayer/articles/full_screen_mode.html full screen mode
* @link http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00001079.html allownetworking
* @param array $flash_params Flash parameters expressed in key-value form
* @return array validated Flash parameters
*/
function videopress_esc_flash_params( $flash_params ) {
static $allowed_params = array(
'swliveconnect' => array('true', 'false'),
'play' => array('true', 'false'),
'loop' => array('true', 'false'),
'menu' => array('true', 'false'),
'quality' => array('low', 'autolow', 'autohigh', 'medium', 'high', 'best'),
'scale' => array('default', 'noorder', 'exactfit'),
'align' => array('l', 'r', 't'),
'salign' => array('l', 'r', 't', 'tl', 'tr', 'bl', 'br'),
'wmode' => array('window', 'opaque', 'transparent'),
'devicefont' => array('_sans', '_serif', '_typewriter'),
'allowscriptaccess' => array('always', 'samedomain', 'never'),
'allownetworking' => array('all','internal', 'none'),
'seamlesstabbing' => array('true', 'false'),
'allowfullscreen' => array('true', 'false'),
'base',
'bgcolor',
'flashvars'
);
$allowed_params_keys = array_keys( $allowed_params );
$filtered_params = array();
foreach( $flash_params as $param=>$value ) {
if ( empty($param) || empty($value) )
continue;
$param = strtolower($param);
if ( in_array($param, $allowed_params_keys) ) {
if ( isset( $allowed_params[$param] ) && is_array( $allowed_params[$param] ) ) {
$value = strtolower($value);
if ( in_array( $value, $allowed_params[$param] ) )
$filtered_params[$param] = $value;
} else {
$filtered_params[$param] = $value;
}
}
}
unset( $allowed_params_keys );
/**
* Flash specifies sameDomain, not samedomain. change from lowercase value for preciseness
*/
if ( isset( $filtered_params['allowscriptaccess'] ) && $filtered_params['allowscriptaccess'] === 'samedomain' )
$filtered_params['allowscriptaccess'] = 'sameDomain';
return $filtered_params;
}
/**
* Request information for the given VideoPress guid and optional desired width from VideoPress servers
*
* @param string $guid VideoPress identifier
* @param int $maxwidth Maximum desired video width, or 0 if no width specified.
* @return
*/
function videopress_remote_video_info( $guid, $maxwidth=0 ) {
$blog_domain = videopress_host( get_bloginfo('url') );
if ( empty($blog_domain) )
return;
$maxwidth = absint( $maxwidth );
$request_params = array('guid'=>$guid, 'domain'=>$blog_domain, 'ssl' => (string) is_ssl() );
if ( $maxwidth > 0 )
$request_params['maxwidth'] = $maxwidth;
if ( is_ssl() )
$url = 'https://v.wordpress.com/data/wordpress.json';
else
$url = 'http://videopress.com/data/wordpress.json';
$response = wp_remote_get( $url . '?' . videopress_http_build_query( $request_params ) );
unset( $request_params );
$response_body = wp_remote_retrieve_body( $response );
if ( is_wp_error($response) ) {
if ( in_array( 'http_request_failed', $response->get_error_codes() ) ) {
if ( $response->get_error_message('http_request_failed') === '403: Forbidden' )
return new WP_Error( 'http403', __videopress_error_placeholder( __('Embed error', 'video'), '<div>' . sprintf( __('<strong>%s</strong> is not an allowed embed site.', 'video'), esc_html($blog_domain) ) . '</div><div>' . __('Publisher limits playback of video embeds.', 'video') . '</div>' ) );
}
return;
} elseif ( wp_remote_retrieve_response_code( $response ) != 200 || empty( $response_body ) ) {
return;
}
return json_decode( $response_body );
}
/**
* Replaces wpvideo shortcode and customization parameters with full HTML markup for video playback
*
* @since 0.1.0
* @link http://codex.wordpress.org/Shortcode_API
*
* @param array $attr an array of attributes: video guid, width (w), height (h), freedom, and autoplay
* @return string HTML markup enabling video playback for the given video, or empty string if incorrect syntax
*/
function videopress_shortcode( $attr ) {
global $content_width;
// Version for manifest returned by videopress_remote_video_info().
$manifest_version = "1.3";
$guid = $attr[0];
if ( !__videopress_is_valid_guid($guid) )
return '';
extract( shortcode_atts( array(
'w'=>0,
'h'=>0,
'freedom'=>false,
'flashonly'=>false,
'autoplay'=>false
), $attr ) );
$width = absint($w);
unset($w);
$height = absint($h);
unset($h);
$freedom = (bool) $freedom;
$autoplay = (bool) $autoplay;
$force_flash = (bool) $flashonly;
unset( $flashonly );
if ( isset($content_width) && $width > $content_width )
$width = $height = 0;
if ( $width === 0 && isset($content_width) && $content_width > 0 )
$width = $content_width;
$key = "video-info-by-$guid-$width-$manifest_version";
$cached_video = wp_cache_get( $key, 'video-info' );
if ( empty($cached_video) ) {
$video = videopress_remote_video_info( $guid, $width );
if ( is_wp_error($video) ) {
if ( current_user_can('edit_posts') )
return $video->get_error_message();
else
return '';
} elseif( !empty($video) ) {
wp_cache_set( $key, serialize($video), 'video_info', 24*60*60 );
}
} else {
$video = unserialize($cached_video);
}
if ( empty($video) )
return '';
$video->guid = $guid;
/**
* Width and/or height may be provided in the shortcode or in the response
* Maintain aspect ratio of the original video unless shortcode specifies both a width and a height
*/
if ( 0 === $width && 0 === $height ) {
$width = $video->width;
$height = $video->height;
}
if ( 0 == $width )
$width = (int) ( ( $video->width * $height ) / $video->height );
elseif (0 == $height)
$height = (int) ( ( $video->height * $width ) / $video->width );
if ( $width %2 === 1 )
$width--;
if ( $height %2 === 1 )
$height--;
$para = array( 'guid' => $guid,
'width' => $width,
'height' => $height,
'freedom' => $freedom,
'force_flash' => $force_flash,
'autoplay' => $autoplay,
'info' => $video
);
$results = videopress_embed( $para );
return $results;
}
/**
* Checks for various states of a video and displays associated notices
* Use ajax to query and update display
*
* @since 2.0
* @param array $args format, context, just_inner, width, height, ins_id
* @return string HTML code for displaying a video
* @todo batcache settings for incomplete videos
*/
function videopress_embed( array $args ) {
global $wpdb, $content_width;
static $embed_seq = 0, $jah_included = false;
$defaults = array( 'just_inner' => false, 'width' => null, 'height' => null, 'ins_id' => null );
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
if ( empty( $guid ) )
return '';
list( $width, $height ) = videopress_calc_embed_dimensions( $width, $height, $info->width, $info->height );
if ( isset($content_width) && $content_width > 0 && ( $width < 60 || $height < 60 || $width > $content_width ) )
list( $width, $height ) = videopress_calc_embed_dimensions( $content_width, 0, $info->width, $info->height );
return videopress_embed_player( $info, $width, $height, is_feed(), $freedom, array( 'autoplay'=>$autoplay, 'force_flash'=>$force_flash ) );
}
/**
* Generate HTML and JavaScript to enable video playback
*
* @since 2.0
* @param stdClass $info VideoPress database row
* @param int $width width of the video playback element
* @param int $height height of the video playback element
* @param bool $restricted_embed should the embed be restricted to the non-standard <embed> HTML element?
* @param bool $freedom publisher preference for only Freedom-loving formats
* @param array $options runtime options including HD by default and autoplay
* @return string HTML markup for video playback element
* @todo batcache uniqueness for is_bot and regular views
*/
function videopress_embed_player( stdClass $info, $width, $height, $restricted_embed = false, $freedom=false, array $options=array() ) {
$guid = $info->guid;
$video_container_id = 'v-' . $guid;
$title = str_replace( ' ', ' ', $info->title );
$force_flash = false;
if ( ( isset($options['force_flash']) && $options['force_flash']===true ) || !in_the_loop() )
$force_flash = true;
unset( $options['force_flash'] );
$video_player = new VideoPress_Player( $info, $video_container_id, $video_container_id . '-video', $guid, trim($title), absint($width), absint($height), (bool)$freedom, $options );
$is_gated = false;
if ( $is_gated )
$style = 'min-width:' . $width . 'px;min-height:' . $height . 'px';
else
$style = 'width:' . $width . 'px;height:' . $height . 'px';
$html = '<div id="' . esc_attr($video_container_id) . '" class="video-player" style="' . esc_attr($style) . '">' . PHP_EOL;
unset( $style );
if ( !isset( $info->display_embed ) )
$info->display_embed = true;
// Dynamic loader
if ( (bool)$info->display_embed === false || $force_flash===true ) {
/* force Flash player if playback restricted or publisher preference specified in shortcode
* @todo display_embed replace with allowed_embed_domains() check for embedding blog URI
* @todo check display_embed in JavaScript if video page is being framed; test top document domain against list of allowed domains
*/
$html .= $video_player->flash_object();
} elseif ( $freedom === true ) {
$html .= $video_player->html5_static();
} elseif ( $restricted_embed===true ) {
// feed readers such as Google Reader require embed markup
$html .= $video_player->flash_embed();
} else {
$html .= $video_player->html5_dynamic();
}
$html .= '</div>';
return $html;
}
/**
* Display a VideoPress error message if an embed is unsuccessful
*
* @param string $text main error display plaintext
* @param string $subtext additional information about the error. may include HTML.
* @param string $text_type type of the text message display
* @param int $width width of the error display element
* @param int $height height of the error display element
*/
function __videopress_error_placeholder( $text='', $subtext='', $text_type='error', $width=400, $height=300, $context='blog' ) {
$text = esc_html( $text ); // escape text for inclusion in HTML
if ($text_type == 'error' )
$text = "<span class='video-plh-error'>$text</span>";
$class = $width >= 380? 'video-plh-full' : 'video-plh-thumb';
if ( $context == 'blog' ) {
$align = 'center';
$margin = 'margin:auto';
}
else {
$align = 'left';
$margin = '';
}
$mid_width = $width - 16;
$res = '';
if ( !is_feed() ) {
$res = <<<STYLE
<style type="text/css">
.video-plh {font-family:Trebuchet MS, Arial, sans-serif;text-align:$align;margin:3px;}
.video-plh-notice {background-color:black;color:white;display:table;#position:relative;line-height:1.0em;text-align:$align;$margin;}
.video-plh-mid {text-align:$align;display:table-cell;#position:absolute;#top:50%;#left:0;vertical-align:middle;padding: 8px;}
.video-plh-text {#position:relative;#top:-50%;text-align:center;line-height:35px;}
.video-plh-sub {}
.video-plh-full {font-size:28px;}
.video-plh-full .video-plh-sub {font-size:14px;}
.video-plh-thumb {font-size:18px;}
.video-plh-thumb .video-plh-sub {font-size:12px;}
.video-plh-sub {line-height: 120%; margin-top:1em;}
.video-plh-error {color:#f2643d;}
</style>
STYLE;
}
$res .= <<<BODY
<div class="video-plh $class">
<div class="video-plh-notice" style='width:{$width}px;height:{$height}px;'>
<div class="video-plh-mid" style='width:{$mid_width}px;'>
<div class="video-plh-text">
$text
<div class="video-plh-sub">$subtext</div>
</div>
</div>
</div>
</div>
BODY;
return $res;
}
/**
* Wrap all types of VideoPress player HTML markup into a single class.
*
* @since 3.2
*/
class VideoPress_Player {
/**
* Video info structure as returned from videopress_remote_video_info().
* @var stdClass
* @since 3.2
*/
protected $info;
/**
* DOM identifier of the video container
* @var string
* @since 3.2
*/
protected $video_container_id;
/**
* DOM identifier of the video element (video, object, embed)
*
* @var string
* @since 3.2
*/
protected $video_id;
/**
* VideoPress unique identifier
* @var string
* @since 3.2
*/
protected $guid;
/**
* Title of the video
* @var string
* @since 3.2
*/
protected $title;
/**
* Desired width of the video player
* @var string
* @since 3.2
*/
protected $width;
/**
* Desired height of the video player
* @var int
* @since 3.2
*/
protected $height;
/**
* Restrict video playback to Freedom-loving containers and codecs
* @var bool
* @since 3.2
*/
protected $freedom;
/**
* Array of playback options. Example: autoplay or HD by default
* @var array
* @since 3.2
*/
protected $options;
/**
* Initialize class
*/
public function __construct( $info, $video_container_id, $video_id, $guid, $title, $width, $height, $freedom=false, array $options=array() ) {
$this->info = $info;
$this->video_container_id = $video_container_id;
$this->video_id = $video_id;
$this->guid = $guid;
if ( empty($title) )
$this->title = '';
else
$this->title = trim($title);
$this->width = absint($width);
$this->height = absint($height);
if ( $freedom === true )
$this->freedom = true;
else
$this->freedom = false;
$this->options = $options;
}
/**
* is the requested video set to automatically play?
*/
private function isAutoplay() {
if ( isset($this->options) && isset($this->options['autoplay']) && $this->options['autoplay']===true )
return true;
else
return false;
}
/**
* Runtime configuration for HTML5 dynamic player.
*
* @return array associative array
*/
private function getPlayerConfig() {
$obj = '{';
$obj .= 'width:' . json_encode($this->width) . ',';
$obj .= 'height:' . json_encode($this->height) . ',';
if ( $this->freedom===true )
$obj .= 'freedom:"true",';
$obj .= 'container:jQuery(' . json_encode('#' . $this->video_container_id) . ')';
$obj .= '}';
return $obj;
}
/**
* Text direction and language of the source video may differ from the embedding site. Express this difference in markup.
*
* @param int blog_id parent blog of the given video
*/
private function language_attributes( $blog_id = '' ) {
$attrs = array( 'dir'=>'ltr' );
if ( get_bloginfo('text_direction')==='rtl' )
$attrs['dir'] = 'rtl';
$lang = get_bloginfo('language');
if ( !empty($lang) )
$attrs['lang'] = $lang;
unset($lang);
return $attrs;
}
/**
* Ask a viewer to verify his or her age before a video is shown.
*
* @since 3.2
* @return string HTML output
*/
private function age_gate( $rtl=false ) {
$text_align = 'left';
if ( $rtl===true )
$text_align = 'right;';
$html = '<div class="videopress-age-gate" style="margin:0 60px">';
$html .= '<p class="instructions" style="color: rgb(255, 255, 255);font-size: 21px;padding-top: 60px;padding-bottom: 20px;text-align: ' . $text_align . '">' . esc_html( __('This video is intended for mature audiences.') ) . '<br />' . esc_html( __('Please verify your birthday.') ) . '</p>';
$html .= '<fieldset id="birthday" style="border: 0pt none;text-align:' . $text_align . ';padding:0;">';
$inputs_style = 'border:1px solid #444;margin-';
if ( $rtl===true )
$inputs_style .= 'left';
else
$inputs_style .= 'right';
$inputs_style .= ': 10px;background-color: rgb(0, 0, 0); font-size: 14px; color: rgb(255, 255, 255); padding: 4px 6px; line-height: 2em; vertical-align: middle';
/**
* Display a list of months in the Gregorian calendar.
* Set values to 0-based to match JavaScript Date.
* @link https://developer.mozilla.org/en/JavaScript/Reference/global_objects/date Mozilla JavaScript Reference: Date
*/
$html .= '<select name="month" style="' . $inputs_style . '">';
$months = array( __('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December') );
for( $i=0; $i<12; $i++ ) {
$html .= '<option value="' . esc_attr( $i ) . '">' . esc_html($months[$i]) . '</option>';
}
$html .= '</select>';
unset( $months );
/**
* todo: numdays variance by month
*/
$html .= '<select name="day" style="' . $inputs_style . '">';
for ( $i=1; $i<32; $i++ ) {
$html .= '<option>' . $i . '</option>';
}
$html .= '</select>';
/**
* Current record for human life is 122. Go back 130 years and no one is left out.
* Don't ask infants younger than 2 for their birthday
* Default to 13
*/
$html .= '<select name="year" style="' . $inputs_style . '">';
$start_year = date('Y') - 2;
$default_year = $start_year - 11;
$end_year = $start_year - 128;
for ( $year=$start_year; $year>$end_year; $year-- ) {
$html .= '<option';
if ( $year===$default_year )
$html .= ' selected="selected"';
$html .= '>' . $year . '</option>';
}
unset( $start_year );
unset( $default_year );
unset( $end_year );
$html .= '</select>';
$html .= '<input type="submit" value="' . __('Submit') . '" style="cursor:pointer;border-radius: 1em;border:1px solid #333;background-color: #333;background: -webkit-gradient( linear, left top, left bottom, color-stop(0.0, #444), color-stop(1, #111) ); background: -moz-linear-gradient( center top, #444 0%, #111 100% ); font-size: 13px; padding: 4px 10px 5px; line-height: 1em; vertical-align: top; color: white; text-decoration: none; margin: 0pt" />';
$html .= '</fieldset>';
$html .= '<p style="padding-top: 20px; padding-bottom: 60px;text-align:' . $text_align . ';"><a rel="nofollow" href="http://videopress.com/" style="color:rgb(128,128,128); text-decoration: underline; font-size: 15px">' . __('More information') . '</a></p>';
$html .= '</div>';
return $html;
}
/**
* Return HTML5 video static markup for the given video parameters.
* Use default browser player controls.
* No Flash fallback.
*
* @since 3.1
* @link http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html HTML5 video
* @return string HTML5 video element and children
*/
public function html5_static() {
$thumbnail = esc_url( $this->info->posterframe );
$html = "<video id=\"{$this->video_id}\" width=\"{$this->width}\" height=\"{$this->height}\" poster=\"$thumbnail\" controls=\"true\" ";
if ( isset($this->options['autoplay']) && $this->options['autoplay']===true )
$html .= 'autoplay="true"';
else
$html .= 'preload="metadata"';
$language_attributes = $this->language_attributes();
foreach( $language_attributes as $attr=>$value ) {
$html .= ' ' . $attr . '="' . esc_attr($value) . '"';
}
$html .= '>';
if ( $this->freedom===false ) {
$mp4_high = $this->info->mp4->url;
if (!empty($mp4_high))
$html .= '<source src="' . esc_url($mp4_high) . '" type="video/mp4; codecs="avc1.64001E, mp4a.40.2"" />';
unset( $mp4_high );
}
$ogg = $this->info->ogv->url;
if ( !empty($ogg) )
$html .= '<source src="' . esc_url($ogg) . '" type="video/ogg; codecs="theora, vorbis"" />';
unset( $ogg );
$html .= '<div><img ';
if ( !empty($this->title) )
$html .= 'alt="' . esc_attr($this->title) . '" ';
$html .= 'src="' . $thumbnail . '" width="' . $this->width . '" height="' . $this->height . '" /></div>';
if ( $this->freedom === true )
$html .= '<p class="robots-nocontent">' . sprintf( __('You do not have sufficient <a rel="nofollow" href="%s">freedom levels</a> to view this video.'), 'http://www.gnu.org/philosophy/free-sw.html') . '</p>';
elseif (!empty($title))
$html .= "<p>$title</p>";
$html .= '</video>';
return $html;
}
/**
* Display a video poster frame with lightweight video player markup. Activate best player match onclick -- ogv, mp4, flash -- with a noscript fallback.
*
* @since 3.2
* @return String HTML markup for dynamic HTML5 playback
* @todo frame-aware domain whitelisting
* @todo guid page collisions
* @todo no HTML age gate if player type = Flash
*/
public function html5_dynamic() {
$rtl = is_rtl();
$language_attributes = $this->language_attributes();
$video_placeholder = $this->video_container_id . '-placeholder';
$poster = $this->info->posterframe;
$watermark = videopress_staticize( 'http://nktester.wordpress.com/wp-content/plugins/video/assets/i/videopress.png' );
$background_color = get_option( 'video_player_barcolor' );
$ogv = $this->info->ogv->url;
$mp4 = $this->info->mp4->url;
$is_gated = false;
if ( $is_gated===true )
$style_dimensions = 'min-width:' . $this->width . 'px;min-height:' . $this->height . 'px';
else
$style_dimensions = 'width:' . $this->width . 'px;height:' . $this->height . 'px';
$html = '<div id="' . $video_placeholder . '" class="videopress-placeholder" style="' . esc_attr($style_dimensions) . ';display:none;cursor: pointer! important;position: relative;background-color: ';
unset( $style_dimensions );
if ( empty( $background_color ) )
$html .= 'rgb(0, 0, 0)';
else
$html .= esc_attr( '#' . $background_color );
$html .= ';font-family: \'Helvetica Neue\',Arial,Helvetica,\'Nimbus Sans L\',sans-serif;font-weight:bold;font-size: 18px">' . PHP_EOL;
/**
* Do not display a poster frame, title, or any other content hints for mature content.
*/
if ( $is_gated === false ) {
if ( !empty($this->title) ) {
$html .= '<div class="videopress-title" style="display:inline;position:absolute;margin: 20px 20px 0 20px;padding: 4px 8px;vertical-align: top;text-align:';
if ( $rtl === true )
$html .= 'right" dir="rtl"';
else
$html .= 'left" dir="ltr"';
if ( isset($language_attributes['lang']) )
$html .= ' lang="' . esc_attr( $language_attributes['lang'] ) . '"';
$html .= '><span style="padding:3px 0;line-height:1.5em;background-color:';
if ( empty( $background_color ) )
$html .= 'rgba(0,0,0,0.8)';
else
$html .= esc_attr( '#' . $background_color );
$html .= ';color: rgb(255, 255, 255)">' . esc_html($this->title) . '</span></div>';
}
$html .= '<img class="videopress-poster" ';
if ( !empty($this->title) )
$html .= 'alt="' . esc_attr($this->title) . '" title="' . esc_attr( sprintf(__('Watch: %s'), $this->title ) ) . '" ';
$html .= 'src="' . esc_url( $poster, array('http','https') ) . '" width="' . $this->width . '" height="' . $this->height . '" />' . PHP_EOL;
/*
* style a play button hovered over the poster frame
*/
$html .= '<div class="play-button"><span style="z-index: 2; display: block; position: absolute; top: 50%; left: 50%; text-align: center; vertical-align: middle; color: rgb(255, 255, 255); opacity: 0.9; margin: 0 0 0 -0.45em; padding: 0pt; line-height: 0; font-size: 500%; text-shadow: 0 0 40px rgba(0,0,0,0.5)">▶</span></div>' . PHP_EOL;
$html .= '<div style="position: relative; margin-top: -40px; height: 25px;margin-bottom: 35px;';
if ( $rtl === true )
$html .= 'margin-left: 20px; text-align: left;';
else
$html .= 'margin-right: 20px; text-align: right;';
$html .= 'vertical-align: bottom; z-index: 3"><img alt="" src="' . esc_url($watermark, array('http','https')) . '" width="90" height="13" style="background-color:transparent;background-image:none;background-repeat:no-repeat;border:none;margin:0;padding:0"/>';
$html .= '</div>' . PHP_EOL;
}
$data = array(
'blog' => absint( $this->info->blog_id ),
'post' => absint( $this->info->post_id ),
'duration'=> absint( $this->info->duration ),
'poster' => $poster
);
$jq_container = json_encode('#' . $this->video_container_id);
$jq_placeholder = json_encode('#' . $video_placeholder);
if ( !empty($mp4) )
$data['mp4'] = array( 'size'=>$this->info->mp4->format, 'uri'=>$mp4 );
if ( !empty($ogv) )
$data['ogv'] = array( 'size'=>'std','uri'=>$ogv );
$data = array_merge( $data, array('locale'=>$this->language_attributes() ) );
$html .= '<script type="text/javascript">' . PHP_EOL;
$html .= 'jQuery.VideoPress.data[' . json_encode($this->guid) . ']=' . json_encode($data) . ';' . PHP_EOL;
unset( $data );
$html .= 'jQuery(' . $jq_placeholder . ').show(0,function(){jQuery.VideoPress.analytics.impression( ' . json_encode($this->guid) . ' )});' . PHP_EOL;
if ( $is_gated===true ) {
$html .= 'if ( jQuery.VideoPress.support.flash() ) {' . PHP_EOL;
//$html .= 'if ( false ) {';
/**
* @link http://code.google.com/p/swfobject/wiki/api#swfobject.embedSWF(swfUrlStr,_replaceElemIdStr,_widthStr,_height
*/
$html .= 'swfobject.embedSWF(' . implode( ',', array(
'jQuery.VideoPress.video.flash.player_uri', // VideoPress SWF player location. should be equal to video_flash_player_url() in flash.php
json_encode( $this->video_container_id ),
json_encode( $this->width ),
json_encode( $this->height ),
'jQuery.VideoPress.video.flash.min_version', // currently 10.0
'jQuery.VideoPress.video.flash.expressinstall', // attempt to upgrade the Flash player if less than min_version. requires a 310x137 container or larger but we will always try to include
'{guid:' . json_encode($this->guid) . '}', // FlashVars
'jQuery.VideoPress.video.flash.params',
'null', // no attributes
'jQuery.VideoPress.video.flash.embedCallback' // error fallback
) ) . ');';
$html .= '} else {' . PHP_EOL;
$html .= 'if ( jQuery.VideoPress.video.prepare( ' . json_encode($this->guid) . ', ' . $this->getPlayerConfig() . ' ) ) {' . PHP_EOL;
$html .= 'if ( jQuery(' . $jq_container . ').data( "player" ) === "flash" ){jQuery.VideoPress.video.play(jQuery(' . json_encode('#' . $this->video_container_id) . '));}else{';
$html .= 'jQuery(' . $jq_placeholder . ').html(' . json_encode( $this->age_gate( $rtl ) ) . ');' . PHP_EOL;
$html .= 'jQuery(' . json_encode( '#' . $video_placeholder . ' input[type=submit]' ) . ').one("click", function(event){jQuery.VideoPress.requirements.isSufficientAge(jQuery(' . $jq_container . '),' . absint($min_age) . ')});' . PHP_EOL;
$html .= '}}}' . PHP_EOL;
} else {
$html .= 'if ( jQuery.VideoPress.video.prepare( ' . json_encode($this->guid) . ', ' . $this->getPlayerConfig() . ' ) ) {' . PHP_EOL;
if ( $this->isAutoplay() === true )
$html .= 'jQuery.VideoPress.video.play(jQuery(' . $jq_container . '));';
else
$html .= 'jQuery(' . $jq_placeholder . ').one("click",function(){jQuery.VideoPress.video.play(jQuery(' . $jq_container . '))});';
$html .= '}';
}
$html .= '</script>' . PHP_EOL;
unset( $jq_placeholder );
unset( $jq_container );
$html .= '</div>'; // close placeholder
/*
* JavaScript required
*/
$noun = 'this video';
if ( $is_gated===false ) {
$vid_type = '';
if ( $this->freedom===true && !empty($ogv) )
$vid_type = 'ogv';
elseif ( !empty($mp4) )
$vid_type = 'mp4';
elseif ( !empty($ogv) )
$vid_type = 'ogv';
if ( !empty($vid_type) ) {
$noun = '<a ';
if ( isset( $language_attributes['lang'] ) )
$noun .= 'hreflang="' . esc_attr( $language_attributes['lang'] ) . '" ';
if ( $vid_type==='mp4' )
$noun .= 'type="video/mp4" href="' . esc_url($mp4);
elseif ( $vid_type==='ogv' )
$noun .= 'type="video/ogv" href="' . esc_url($ogv);
$noun .= '">';
if ( !empty($this->title) )
$noun .= esc_html( $this->title );
else
$noun .= 'this video';
$noun .= '</a>';
} elseif ( !empty($this->title) ) {
$noun = esc_html( $this->title );
}
unset( $vid_type );
}
$html .= '<noscript><p>' . sprintf( __('JavaScript required to play %s.'), $noun ) . '</p></noscript>';
unset( $noun );
return $html;
}
/**
* Flash player markup in a HTML embed element.
*
* @since 3.2
* @link http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#the-embed-element embed element
* @link http://www.google.com/support/reader/bin/answer.py?answer=70664 Google Reader markup support
* @return string HTML markup. Embed element with no children
*/
public function flash_embed() {
$info = $this->info;
$embed = array(
'id' => $this->video_id,
'src' => esc_url_raw( $info->swf->url . '&' . http_build_query( videopress_flash_vars($this->guid, $this->options) ) , array('http', 'https') ),
'type' => 'application/x-shockwave-flash',
'width' => $this->width,
'height' => $this->height
);
if ( !empty($this->title) )
$embed['title'] = $this->title;
$embed = array_merge( $embed, videopress_flash_params() );
$html = '<embed';
foreach ($embed as $attribute=>$value) {
$html .= ' ' . esc_html($attribute) . '="' . esc_attr($value) . '"';
}
unset( $embed );
$html .= '></embed>';
return $html;
}
/**
* Double-baked Flash object markup for Internet Explorer and more standards-friendly consuming agents.
*
* @since 3.2
* @return HTML markup. Object and children.
*/
public function flash_object() {
$info = $this->info;
$thumbnail = '<img alt="' . esc_attr($this->title) . '" src="' . esc_url( $info->posterframe, array('http','https') ) . '" width="' . $this->width . '" height="' . $this->height . '" />';
$flash_vars = videopress_flash_vars($this->guid, $this->options);
$flash_vars['javascriptid'] = $this->video_id;
$flash_vars = esc_attr( http_build_query($flash_vars) );
$flash_params = '';
foreach ( videopress_flash_params() as $attribute=>$value ) {
$flash_params .= '<param name="' . esc_attr($attribute) . '" value="' . esc_attr($value) . '" />';
}
$flash_help = sprintf( __('This movie requires <a rel="nofollow" href="%s">Adobe Flash</a> for playback.'), 'http://www.adobe.com/go/getflashplayer');
$flash_player_url = esc_url( $info->swf->url, array('http', 'https') );
$description = '';
if ( empty($this->title) ) {
$standby = __('Loading video...');
} else {
$standby = $this->title;
$description = '<p><strong>' . esc_html($this->title) . '</strong></p>';
}
$standby = ' standby="' . esc_attr($standby) . '"';
$express_install = esc_js( videopress_staticize( 'http://nktester.wordpress.com/wp-content/plugins/video/assets/expressInstall.swf' ) );
$min_version = videopress_flash_min_version();
return <<<OBJECT
<script type="text/javascript">if( typeof swfobject!=="undefined"){swfobject.registerObject("{$this->video_id}", "{$min_version}", "{$express_install}");}</script>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="{$this->width}" height="{$this->height}" id="{$this->video_id}"{$standby}>
<param name="movie" value="{$flash_player_url}" />
{$flash_params}
<param name="flashvars" value="{$flash_vars}" />
<!--[if !IE]>-->
<object type="application/x-shockwave-flash" data="{$flash_player_url}" width="{$this->width}" height="{$this->height}"{$standby}>
{$flash_params}
<param name="flashvars" value="{$flash_vars}" />
<!--<![endif]-->
{$thumbnail}{$description}<p class="robots-nocontent">{$flash_help}</p>
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
OBJECT;
}
}
/**
* Centralize default FlashVars behavior to pass into SWF via FlashVars or query string
*
* @param string $guid globally unique video identifier
* @param array optional configuration options
* @return array SWF runtime configuration variables
*/
function videopress_flash_vars($guid, $options=array()) {
$flash_vars = array(
'guid' => $guid
// 'isDynamicSeeking' => 'true' // does the current player support dynamic seeking of MP4 files? default: false
);
/**
* Switch to higher-quality version of video by default.
*/
if ( isset($options['hd']) && $options['hd']===true )
$flash_vars['hd'] = 'true';
/**
* Automatically begin download a video and initiate playback on successful player load.
*/
if ( isset($options['autoplay']) && $options['autoplay']===true )
$flash_vars['autoPlay'] = 'true';
// lang
/**
* Pick from a predefined list of AMF gateways for testing purposes.
*
* 3 : HTTPS gateway at v.wordpress.com
* 2 : HTTP gateway at v.wordpress.com
* 1 : Sandbox gateway at Niall's sandbox (nktester.wordpress.com)
*
* Any other value, or no value will trigger default gateway URL behavior based on http(s) SWF URL
*/
//serviceGateway = 3;
return $flash_vars;
}
/**
* Centralize definition of Flash plugin paramters for VideoPress player
*
* @link http://livedocs.adobe.com/flash/9.0/UsingFlash/help.html?content=WSd60f23110762d6b883b18f10cb1fe1af6-7ba7.html Custom parameters supported by Flash 9
* @return array default Flash parameters used by VideoPress player
*/
function videopress_flash_params() {
$params = array(
'wmode' => 'transparent', // override default window mode, matching plugin component display to parent page element
'seamlesstabbing' => 'true', // set the ActiveX control to perform seamless tabbing, so that the user can tab out of a Flash application. default true
'allowfullscreen' => 'true', // allow full-screen mode
'allowscriptaccess' => 'always', // allow ExternalInterface connections for on-page JavaScript
'overstretch' => 'true'
);
return videopress_esc_flash_params( apply_filters( 'video_flash_params', $params, 10, 1 ) );
}
/**
* Minimum required Flash player version
*
* @return String Minimum required Flash Player version in the format major.minor.release
*/
function videopress_flash_min_version() {
return '10.0.0';
}
/**
* Serve static VideoPress HTTP small objects from their short, CDN-fronted URI
* Similar to staticize_subdomain() but specific to VideoPress
*
* @since 3.2
* @param string $url
* @return string Equivalent resource served from CDN if URL hosted on WordPress.com and current blog context is not a developer sandbox
*/
function videopress_staticize( $url ) {
$url_parts = parse_url( $url );
if ( empty($url_parts) || !isset($url_parts['host']) )
return $url;
$base_path = '/wp-content/plugins/video/assets/';
if ( !empty($url_parts) && isset($url_parts['path']) && ( 0 === strpos( $url_parts['path'], $base_path ) ) ) {
$short_path = substr( $url_parts['path'], strlen($base_path) );
if ( !empty( $short_path ) ) {
$domain = 'http://s0.videopress.com';
if ( is_ssl() )
$domain = 'https://v0.wordpress.com';
$url = $domain . '/' . $short_path;
unset( $short_path );
unset( $domain );
if ( isset( $url_parts['query'] ) )
$url .= '?' . $url_parts['query'];
}
}
return $url;
}
/**
* Given user specified dimensions, and the real dimensions calculate the display width and height
*
* @since 2.0
* @param int $specified_width specified width of the video playback element
* @param int $specified_height specified height of the video playback element
* @param int $real_width width of the original uploaded video
* @param int $real_height height of the original uploaded video
* @return array width and height of video playback element
*/
function videopress_calc_embed_dimensions( $specified_width, $specified_height, $real_width, $real_height ) {
global $content_width;
// handle null value resulting from db errors
if ( empty($real_width) || empty($real_height) ){
$real_width = 400;
$real_height = 300;
}
$width = absint( $specified_width );
$height = absint( $specified_height );
if ( $width == 0 && $height == 0 ) {
if ( isset( $content_width ) && $content_width > 0 ) // scale to theme width
$width = $content_width;
else
$width = 400;
}
if ( $width == 0 ) {
$width = (int)( ( $real_width*$height ) / $real_height );
if ( $width %2 == 1 )
$width--; //in sync with transcoder logic
} elseif ($height == 0) {
$height = (int)( ( $real_height*$width ) / $real_width );
if ( $height %2 == 1 )
$height--; //in sync with transcoder logic
}
return array( $width, $height );
}
?>