| 1 |
<?php |
| 2 |
/* FV Player - HTML5 video player |
| 3 |
Copyright (C) 2013 Foliovision |
| 4 |
|
| 5 |
This program is free software: you can redistribute it and/or modify |
| 6 |
it under the terms of the GNU General Public License as published by |
| 7 |
the Free Software Foundation, either version 3 of the License, or |
| 8 |
(at your option) any later version. |
| 9 |
|
| 10 |
This program is distributed in the hope that it will be useful, |
| 11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 |
GNU General Public License for more details. |
| 14 |
|
| 15 |
You should have received a copy of the GNU General Public License |
| 16 |
along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 17 |
*/ |
| 18 |
|
| 19 |
class FV_Player_Checker { |
| 20 |
|
| 21 |
|
| 22 |
var $is_cron = false; |
| 23 |
|
| 24 |
|
| 25 |
function __construct() { |
| 26 |
add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) ); |
| 27 |
add_action( 'fv_flowplayer_checker_event', array( $this, 'checker_cron' ) ); |
| 28 |
add_action( 'init', array( $this, 'cron_init' ) ); |
| 29 |
} |
| 30 |
|
| 31 |
|
| 32 |
|
| 33 |
public static function check_headers( $headers, $remotefilename, $random, $args = false ) { |
| 34 |
$args = wp_parse_args( $args, array( 'talk_bad_mime' => 'Video served with a bad mime type' , 'wrap'=>'p' ) ); |
| 35 |
|
| 36 |
$sOutput = ''; |
| 37 |
|
| 38 |
$video_errors = array(); |
| 39 |
|
| 40 |
$bFatal = false; |
| 41 |
if( $headers && $headers['response']['code'] == '404' ) { |
| 42 |
$video_errors[] = 'File not found (HTTP 404)!'; |
| 43 |
$bFatal = true; |
| 44 |
} else if( $headers && $headers['response']['code'] == '403' ) { |
| 45 |
$video_errors[] = 'Access to video forbidden (HTTP 403)!'; |
| 46 |
$bFatal = true; |
| 47 |
} else if( $headers && $headers['response']['code'] != '200' && $headers['response']['code'] != '206' ) { |
| 48 |
$video_errors[] = 'Can\'t check the video (HTTP '.$headers['response']['code'].')!'; |
| 49 |
$bFatal = true; |
| 50 |
} else { |
| 51 |
|
| 52 |
if( |
| 53 |
( !isset($headers['headers']['accept-ranges']) || $headers['headers']['accept-ranges'] != 'bytes' ) && |
| 54 |
!isset($headers['headers']['content-range']) |
| 55 |
) { |
| 56 |
$video_errors[] = 'Server does not support HTTP range requests! Please check <a href="http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer/faq#getting-error-about-range-requests">our FAQ</a>.'; |
| 57 |
} |
| 58 |
|
| 59 |
if( |
| 60 |
( stripos( $remotefilename, '.mp4' ) !== FALSE && $headers['headers']['content-type'] != 'video/mp4' ) || |
| 61 |
( stripos( $remotefilename, '.m4v' ) !== FALSE && $headers['headers']['content-type'] != 'video/x-m4v' ) || |
| 62 |
( stripos( $remotefilename, '.webm' ) !== FALSE && $headers['headers']['content-type'] != 'video/webm' ) || |
| 63 |
( stripos( $remotefilename, '.mov' ) !== FALSE && $headers['headers']['content-type'] != 'video/mp4' ) |
| 64 |
) { |
| 65 |
if( stripos( $remotefilename, '.mov' ) !== FALSE ) { |
| 66 |
$meta_note_addition = ' Firefox on Windows does not like MOV files with video/quicktime mime type.'; |
| 67 |
} else if( stripos( $remotefilename, '.webm' ) !== FALSE ) { |
| 68 |
$meta_note_addition = ' Older Firefox versions don\'t like WEBM files with mime type other than video/webm.'; |
| 69 |
} else { |
| 70 |
$meta_note_addition = ' Some web browsers may experience playback issues in HTML5 mode (Internet Explorer 9 - 10).'; |
| 71 |
/*if( $fv_fp->conf['engine'] == 'default' ) { |
| 72 |
$meta_note_addition .= ' Currently you are using the "Default (mixed)" <a href="'.site_url().'/wp-admin/admin.php?page=fvplayer">Preferred Flowplayer engine</a> setting, so IE will always use Flash and will play fine.'; |
| 73 |
}*/ |
| 74 |
} |
| 75 |
|
| 76 |
$fix = '<div class="fix-meta-'.$random.'" style="display: none; "> |
| 77 |
<p>If the video is hosted on Amazon S3:</p> |
| 78 |
<blockquote>Using your Amazon AWS Management Console, you can go though your videos and find file content type under the "Metadata" tab in an object\'s "Properties" pane and fix it to "video/mp4" for MP4, "video/x-m4v" for M4V files, "video/mp4" for MOV files and "video/webm" for WEBM files.</blockquote> |
| 79 |
<p>If the video is hosted on your server, put this into your .htaccess:</p> |
| 80 |
<pre>AddType video/mp4 .mp4 |
| 81 |
AddType video/webm .webm |
| 82 |
AddType video/ogg .ogv |
| 83 |
AddType application/x-mpegurl .m3u8 |
| 84 |
AddType video/x-m4v .m4v |
| 85 |
AddType video/mp4 .mov |
| 86 |
# hls transport stream segments: |
| 87 |
AddType video/mp2t .ts</pre> |
| 88 |
<p>If you are using Microsoft IIS, you need to use the IIS manager. Check our <a href="http://foliovision.com/wordpress/plugins/fv-wordpress-flowplayer/faq#video-doesnt-play-internet-explorer" target="_blank">FAQ</a> for more info.</p> |
| 89 |
</div>'; |
| 90 |
|
| 91 |
$sOutput = ( $args['wrap'] ) ? '<'.$args['wrap'].'>' : ''; |
| 92 |
$sOutput .= '<strong>Bad mime type</strong>: '.$args['talk_bad_mime'].' <tt>'.$headers['headers']['content-type'].'</tt>!'.$meta_note_addition.' (<a href="#" onclick="jQuery(\'.fix-meta-'.$random.'\').toggle(); return false">show fix</a>)'; |
| 93 |
$sOutput .= ( $args['wrap'] ) ? '</'.$args['wrap'].'>' : ''; |
| 94 |
$sOutput .= $fix; |
| 95 |
$video_errors[] = $sOutput; |
| 96 |
} |
| 97 |
} |
| 98 |
|
| 99 |
return array( $video_errors, (isset($headers['headers']['content-type'])) ? $headers['headers']['content-type'] : '', $bFatal ); |
| 100 |
} |
| 101 |
|
| 102 |
|
| 103 |
|
| 104 |
|
| 105 |
public function check_mimetype( $URLs = false, $meta = array(), $force_is_cron = false ) { |
| 106 |
|
| 107 |
// If we create new player in FV Player Coconut in coconut-ajax.php, there will be no wp_remote_get function or WP_Http class, so we cannot check the video. |
| 108 |
if ( ! function_exists( 'wp_remote_get' ) || ! class_exists( 'WP_Http' ) ) { |
| 109 |
return false; |
| 110 |
} |
| 111 |
|
| 112 |
$error = false; |
| 113 |
$tStart = microtime(true); |
| 114 |
|
| 115 |
global $fv_wp_flowplayer_ver, $fv_fp; |
| 116 |
|
| 117 |
if( !empty($meta) ) { |
| 118 |
extract( $meta, EXTR_SKIP ); |
| 119 |
} |
| 120 |
|
| 121 |
if( defined('DOING_AJAX') && DOING_AJAX && isset( $_POST['media'] ) && stripos( sanitize_url( $_SERVER['HTTP_REFERER'] ), home_url() ) === 0 ) { |
| 122 |
$URLs = json_decode( stripslashes( trim( wp_strip_all_tags( $_POST['media'] ) ) ) ); |
| 123 |
} |
| 124 |
|
| 125 |
if( isset($URLs) ) { |
| 126 |
$all_sources = $URLs; |
| 127 |
|
| 128 |
foreach( $all_sources AS $source ) { |
| 129 |
if( preg_match( '~^https?://~', $source, $match ) ) { |
| 130 |
$media = $source; |
| 131 |
break; |
| 132 |
} |
| 133 |
} |
| 134 |
|
| 135 |
$random = (isset($_POST['hash'])) ? trim( wp_strip_all_tags( sanitize_text_field( $_POST['hash'] ) ) ) : false; |
| 136 |
if( isset($media) ) { |
| 137 |
$remotefilename = $media; |
| 138 |
$remotefilename_encoded = flowplayer::get_encoded_url($remotefilename); |
| 139 |
|
| 140 |
$bValidFile = true; |
| 141 |
|
| 142 |
if ( ! class_exists( 'getID3' ) ) { |
| 143 |
require( ABSPATH . WPINC . '/ID3/getid3.php' ); |
| 144 |
} |
| 145 |
$getID3 = new getID3; |
| 146 |
|
| 147 |
$upload_dir = wp_upload_dir(); |
| 148 |
$localtempfilename = trailingslashit( $upload_dir['basedir'] ).'fv_flowlayer_tmp_'.md5(wp_rand(1,999)).'_'.basename( substr($remotefilename_encoded,0,32) ); |
| 149 |
|
| 150 |
global $wp_filesystem; |
| 151 |
|
| 152 |
if ( is_null( $wp_filesystem ) ) { |
| 153 |
require_once ABSPATH . '/wp-admin/includes/file.php'; |
| 154 |
WP_Filesystem(); |
| 155 |
} |
| 156 |
|
| 157 |
$real_file_size = 0; |
| 158 |
$analysis_size = 8 * 1024 * 1024; |
| 159 |
|
| 160 |
$remotefilename_encoded = $fv_fp->get_video_src( $remotefilename_encoded, array( 'dynamic' => true ) ); |
| 161 |
|
| 162 |
$res = wp_remote_get( $remotefilename_encoded, array( |
| 163 |
'headers' => array( |
| 164 |
'range' => 'bytes=0-' . $analysis_size, |
| 165 |
'referer' => home_url() |
| 166 |
), |
| 167 |
'timeout' => !$this->is_cron && !$force_is_cron ? apply_filters( 'fv_flowplayer_checker_timeout_quick', 2 ) : 20, |
| 168 |
'user-agent' => 'FV Player video checker/' . $fv_wp_flowplayer_ver |
| 169 |
) ); |
| 170 |
|
| 171 |
if ( ! is_wp_error( $res ) ) { |
| 172 |
|
| 173 |
// Get the real file size out of Content-length: 0-8388608/{full file size here} |
| 174 |
if ( $content_range = wp_remote_retrieve_header( $res, 'content-range' ) ) { |
| 175 |
$content_range_parts = explode( '/', $content_range ); |
| 176 |
if ( 2 === count( $content_range_parts ) ) { |
| 177 |
$real_file_size = intval( $content_range_parts[1] ); |
| 178 |
} |
| 179 |
} |
| 180 |
|
| 181 |
$wp_filesystem->put_contents( $localtempfilename, wp_remote_retrieve_body( $res ) ); |
| 182 |
|
| 183 |
if( !empty($res['response']['code']) ) { |
| 184 |
$code = intval($res['response']['code']); |
| 185 |
if( $code == 404 ) { |
| 186 |
$error = 'Video not found'; |
| 187 |
|
| 188 |
} else if( $code == 403 ) { |
| 189 |
$error = 'Access denied'; |
| 190 |
|
| 191 |
} else if( $code > 399 ) { |
| 192 |
$error = 'HTTP '.$code; |
| 193 |
if( !empty($res['response']['message']) ) { |
| 194 |
$error .= ': '.$res['response']['message']; |
| 195 |
} |
| 196 |
} |
| 197 |
} |
| 198 |
|
| 199 |
list( $aVideoErrors, $sContentType, $bFatal ) = $this->check_headers( $res, $remotefilename, $random ); |
| 200 |
if( $bFatal ) { |
| 201 |
$bValidFile = false; |
| 202 |
} |
| 203 |
|
| 204 |
if( $bValidFile ) { |
| 205 |
$ThisFileInfo = $getID3->analyze( $localtempfilename ); |
| 206 |
} |
| 207 |
|
| 208 |
$wp_filesystem->delete( $localtempfilename ); |
| 209 |
|
| 210 |
} else { |
| 211 |
$bValidFile = false; |
| 212 |
} |
| 213 |
|
| 214 |
/* |
| 215 |
Only check file length |
| 216 |
*/ |
| 217 |
|
| 218 |
if( (isset($meta_action) && $meta_action == 'check_time') || $force_is_cron ) { |
| 219 |
$time = false; |
| 220 |
$width = false; |
| 221 |
$height = false; |
| 222 |
|
| 223 |
if( isset($ThisFileInfo) && isset($ThisFileInfo['playtime_seconds']) ) { |
| 224 |
$time = $ThisFileInfo['playtime_seconds']; |
| 225 |
|
| 226 |
/** |
| 227 |
* MP3 duration check is not reliable if we only check a part of file. |
| 228 |
* So here we multiply the duration by the ratio of the real file size to the analysis size, |
| 229 |
* if it's bigger than the analysis size. |
| 230 |
*/ |
| 231 |
if ( stripos( $remotefilename_encoded, '.mp3' ) !== false ) { |
| 232 |
if ( $real_file_size > $analysis_size ) { |
| 233 |
$time = $time * $real_file_size / $analysis_size; |
| 234 |
} |
| 235 |
} |
| 236 |
} |
| 237 |
if( !empty($ThisFileInfo['video']['resolution_x']) ) { |
| 238 |
$width = intval($ThisFileInfo['video']['resolution_x']); |
| 239 |
} |
| 240 |
if( !empty($ThisFileInfo['video']['resolution_y']) ) { |
| 241 |
$height = intval($ThisFileInfo['video']['resolution_y']); |
| 242 |
} |
| 243 |
|
| 244 |
$is_live = false; |
| 245 |
$is_encrypted = false; |
| 246 |
|
| 247 |
if(preg_match('/.m3u8(\?.*)?$/i', $remotefilename_encoded)){ |
| 248 |
$remotefilename_encoded = apply_filters( 'fv_flowplayer_video_src', $remotefilename_encoded , array('dynamic'=>true) ); |
| 249 |
$request = wp_remote_get( |
| 250 |
$remotefilename_encoded, |
| 251 |
array( |
| 252 |
'headers' => array( |
| 253 |
'referer' => home_url(), |
| 254 |
), |
| 255 |
'timeout' => 15, |
| 256 |
'user-agent' => 'FV Player video checker/' . $fv_wp_flowplayer_ver |
| 257 |
) |
| 258 |
); |
| 259 |
|
| 260 |
$response_code = wp_remote_retrieve_response_code( $request ); |
| 261 |
if( $response_code == 404 ) { |
| 262 |
return array( 'error' => 'Video not found' ); |
| 263 |
|
| 264 |
} else if( $response_code == 403 ) { |
| 265 |
return array( 'error' => 'Access denied' ); |
| 266 |
|
| 267 |
} else if( is_wp_error($request) ) { |
| 268 |
return array( 'error' => $request->get_error_message() ); |
| 269 |
} |
| 270 |
|
| 271 |
$response = wp_remote_retrieve_body( $request ); |
| 272 |
|
| 273 |
$playlist = false; |
| 274 |
$duration = 0; |
| 275 |
$segments = false; |
| 276 |
|
| 277 |
if(preg_match_all('/^#EXTINF:([0-9]+\.?[0-9]*)/im', $response,$segments)){ |
| 278 |
$is_live = stripos( $response, '#EXT-X-ENDLIST' ) === false; |
| 279 |
|
| 280 |
foreach($segments[1] as $segment_item){ |
| 281 |
$duration += $segment_item; |
| 282 |
} |
| 283 |
} else { |
| 284 |
$lines = explode( "\n", $response ); |
| 285 |
|
| 286 |
$streams = array(); |
| 287 |
$had_ext_x_stream_inf = false; |
| 288 |
$resoluton_x_max = 0; |
| 289 |
$resoluton_y_max = 0; |
| 290 |
|
| 291 |
foreach( $lines AS $line ) { |
| 292 |
// last line was starting with #EXT-X-STREAM-INF: |
| 293 |
if( stripos($line,'#') !== 0 && $had_ext_x_stream_inf ) { |
| 294 |
$streams[] = trim($line); |
| 295 |
$had_ext_x_stream_inf = false; |
| 296 |
} |
| 297 |
|
| 298 |
if( stripos($line,'#EXT-X-STREAM-INF:') === 0 ) { |
| 299 |
$had_ext_x_stream_inf = true; |
| 300 |
|
| 301 |
if( stripos($line,'RESOLUTION=') !== false ) { |
| 302 |
if( preg_match( '~RESOLUTION=(\d+)x(\d+)~', $line, $resoluton ) ) { |
| 303 |
if( $resoluton[1] > $resoluton_x_max ) { |
| 304 |
$resoluton_x_max = $resoluton[1]; |
| 305 |
} |
| 306 |
if( $resoluton[2] > $resoluton_y_max ) { |
| 307 |
$resoluton_y_max = $resoluton[2]; |
| 308 |
} |
| 309 |
} |
| 310 |
} |
| 311 |
} |
| 312 |
|
| 313 |
} |
| 314 |
|
| 315 |
$width = $resoluton_x_max; |
| 316 |
$height = $resoluton_y_max; |
| 317 |
|
| 318 |
foreach($streams as $item){ |
| 319 |
$item_url = $item; |
| 320 |
|
| 321 |
// If the stream URL is relative, we need to take the master playlist URL, remove the filename part and put in the stream link |
| 322 |
if( stripos( $item_url, 'http://' ) !== 0 && stripos( $item_url, 'https://' ) !== 0 ) { |
| 323 |
$item_url = preg_replace('/[^\/]*\.m3u8(\?.*)?/i', $item, $remotefilename_encoded); |
| 324 |
} |
| 325 |
if( $secured_url = $fv_fp->get_video_src( $item_url, array( 'dynamic' => true ) ) ) { |
| 326 |
$item_url = $secured_url; |
| 327 |
} |
| 328 |
|
| 329 |
$request = wp_remote_get( |
| 330 |
$item_url, |
| 331 |
array( |
| 332 |
'headers' => array( |
| 333 |
'referer' => home_url() |
| 334 |
), |
| 335 |
'user-agent' => 'FV Player video checker/' . $fv_wp_flowplayer_ver |
| 336 |
) |
| 337 |
); |
| 338 |
|
| 339 |
if( is_wp_error($request) ) { |
| 340 |
return array( 'error' => $request->get_error_message() ); |
| 341 |
} |
| 342 |
|
| 343 |
$playlist_item = wp_remote_retrieve_body( $request ); |
| 344 |
|
| 345 |
if(preg_match_all('/^#EXTINF:([0-9]+\.?[0-9]*)/im', $playlist_item,$segments)){ |
| 346 |
$is_live = stripos( $playlist_item, '#EXT-X-ENDLIST' ) === false; |
| 347 |
$is_encrypted = stripos( $playlist_item, '#EXT-X-KEY' ) !== false; |
| 348 |
|
| 349 |
foreach($segments[1] as $segment_item){ |
| 350 |
$duration += $segment_item; |
| 351 |
} |
| 352 |
} |
| 353 |
if($duration > 0) |
| 354 |
break; |
| 355 |
} |
| 356 |
} |
| 357 |
|
| 358 |
$time = $duration; |
| 359 |
} |
| 360 |
|
| 361 |
$time = apply_filters( 'fv_flowplayer_checker_time', $time, $remotefilename_encoded ); |
| 362 |
$key = flowplayer::get_video_key($remotefilename_encoded); |
| 363 |
|
| 364 |
global $post; |
| 365 |
$fv_flowplayer_meta = array(); |
| 366 |
if( !empty($post) ) { |
| 367 |
$fv_flowplayer_meta = get_post_meta( $post->ID, $key, true ); |
| 368 |
if( !$fv_flowplayer_meta ) $fv_flowplayer_meta = array(); |
| 369 |
} |
| 370 |
|
| 371 |
$fv_flowplayer_meta['error'] = $error; |
| 372 |
$fv_flowplayer_meta['duration'] = $time; |
| 373 |
$fv_flowplayer_meta['width'] = $width; |
| 374 |
$fv_flowplayer_meta['height'] = $height; |
| 375 |
$fv_flowplayer_meta['is_live'] = $is_live; |
| 376 |
$fv_flowplayer_meta['is_encrypted'] = $is_encrypted; |
| 377 |
$fv_flowplayer_meta['etag'] = ! is_wp_error( $res ) && isset($res['headers']['etag']) ? $res['headers']['etag'] : false; // todo: check! |
| 378 |
$fv_flowplayer_meta['date'] = time(); |
| 379 |
$fv_flowplayer_meta['check_time'] = microtime(true) - $tStart; |
| 380 |
|
| 381 |
if( $time > 0 || $error || $this->is_cron ) { |
| 382 |
if( !empty($post) ) { |
| 383 |
update_post_meta( $post->ID, $key, $fv_flowplayer_meta ); |
| 384 |
} |
| 385 |
return $fv_flowplayer_meta; |
| 386 |
} |
| 387 |
|
| 388 |
} |
| 389 |
|
| 390 |
} // end isset($media) |
| 391 |
} |
| 392 |
} |
| 393 |
|
| 394 |
|
| 395 |
|
| 396 |
|
| 397 |
function checker_cron() { |
| 398 |
global $fv_fp; |
| 399 |
if( $fv_fp->_get_option('video_model_db_checked') && $fv_fp->_get_option('video_meta_model_db_checked') ) { |
| 400 |
|
| 401 |
// get all video IDs for which the duration is zero and are not live streams and were not checked in last day |
| 402 |
global $wpdb; |
| 403 |
$aVideos = $wpdb->get_col( "SELECT id FROM `{$wpdb->prefix}fv_player_videos` WHERE duration = 0 AND live = 0 AND DATE_SUB( UTC_TIMESTAMP(), INTERVAL 1 DAY ) > last_check ORDER BY id DESC" ); |
| 404 |
|
| 405 |
if( $aVideos ) { |
| 406 |
global $FV_Player_Db; |
| 407 |
foreach( $aVideos AS $video_id ) { |
| 408 |
$objVideo = new FV_Player_Db_Video( $video_id, array(), $FV_Player_Db ); |
| 409 |
|
| 410 |
$last_check = $objVideo->getLastCheck(); |
| 411 |
|
| 412 |
$check_ttl = 86400; |
| 413 |
|
| 414 |
$is_live = $objVideo->getLive(); |
| 415 |
if( $is_live && FV_Player_YouTube()->is_youtube( $objVideo->getSrc() ) ) { |
| 416 |
$check_ttl = 300; |
| 417 |
} |
| 418 |
|
| 419 |
if( $last_check && intval($last_check) + $check_ttl > time() ) { |
| 420 |
continue; |
| 421 |
} |
| 422 |
|
| 423 |
$error_count = $objVideo->getMetaValue('error_count',true); |
| 424 |
|
| 425 |
if( $error_count && intval($error_count) > 5 ) { |
| 426 |
continue; |
| 427 |
} |
| 428 |
|
| 429 |
// Make sure we do no loose video meta! |
| 430 |
$objVideo->save( array(), true ); |
| 431 |
|
| 432 |
} |
| 433 |
} |
| 434 |
} |
| 435 |
|
| 436 |
// legacy |
| 437 |
if( !$aQueue = self::queue_get() ) return; |
| 438 |
$tStart = microtime(true); |
| 439 |
$this->is_cron = true; |
| 440 |
foreach( $aQueue AS $key => $item ) { |
| 441 |
if( microtime(true) - $tStart > apply_filters( 'fv_flowplayer_checker_cron_time', 20 ) ) { |
| 442 |
break; |
| 443 |
} |
| 444 |
global $post; |
| 445 |
$tmp = $post; |
| 446 |
$post = get_post($key); |
| 447 |
|
| 448 |
do_action( 'fv_flowplayer_checker_cron_post', $key ); |
| 449 |
|
| 450 |
fv_wp_flowplayer_save_post($key); |
| 451 |
$post = $tmp; |
| 452 |
} |
| 453 |
|
| 454 |
} |
| 455 |
|
| 456 |
|
| 457 |
|
| 458 |
|
| 459 |
function cron_init() { |
| 460 |
if ( !wp_next_scheduled( 'fv_flowplayer_checker_event' ) ) { |
| 461 |
wp_schedule_event( time(), '5minutes', 'fv_flowplayer_checker_event' ); |
| 462 |
} |
| 463 |
} |
| 464 |
|
| 465 |
|
| 466 |
|
| 467 |
|
| 468 |
function cron_schedules( $schedules ) { |
| 469 |
$schedules['5minutes'] = array( |
| 470 |
'interval' => 300, |
| 471 |
'display' => __('Every 5 minutes') |
| 472 |
); |
| 473 |
return $schedules; |
| 474 |
} |
| 475 |
|
| 476 |
|
| 477 |
|
| 478 |
|
| 479 |
public static function get_videos( $post_id ) { |
| 480 |
global $fv_fp; |
| 481 |
|
| 482 |
$objPost = get_post($post_id); |
| 483 |
if( $objPost ) { |
| 484 |
$content = $objPost->post_content; |
| 485 |
preg_match_all( '~\[(?:flowplayer|fvplayer).*?\]~', $content, $matches ); |
| 486 |
|
| 487 |
$aMeta = get_post_custom($post_id); |
| 488 |
if( $aMeta && is_array($aMeta) && count($aMeta) > 0) { |
| 489 |
$meta_values = ''; |
| 490 |
foreach( $aMeta AS $values ) { |
| 491 |
$meta_values .= implode("", $values); |
| 492 |
} |
| 493 |
if( preg_match_all( '~\[(?:flowplayer|fvplayer).*?\]~', $meta_values, $meta_matches ) ) { |
| 494 |
$matches[0] = array_merge($matches[0], $meta_matches[0]); |
| 495 |
} |
| 496 |
} |
| 497 |
|
| 498 |
} |
| 499 |
|
| 500 |
$videos = array(); |
| 501 |
if( isset($matches[0]) && count($matches[0]) ) { |
| 502 |
$aPlaylistItems = array(); |
| 503 |
foreach( $matches[0] AS $shortcode ) { |
| 504 |
$aArgs = shortcode_parse_atts( rtrim($shortcode,']') ); |
| 505 |
list( $playlist_items_external_html, $aPlaylistItems ) = $fv_fp->build_playlist( $aArgs, isset($aArgs['src']) ? $aArgs['src'] : false, false, false, false, false, true ); |
| 506 |
|
| 507 |
if( count($aPlaylistItems) > 0 ) { |
| 508 |
foreach( $aPlaylistItems AS $aItem ) { |
| 509 |
if( isset($aItem['sources']) && isset($aItem['sources'][0]) && isset($aItem['sources'][0]['src']) ) { |
| 510 |
$videos[] = $aItem['sources'][0]['src']; |
| 511 |
} |
| 512 |
} |
| 513 |
} |
| 514 |
} |
| 515 |
} |
| 516 |
|
| 517 |
if( count($videos) > 0 ) { |
| 518 |
$videos = array_unique($videos); |
| 519 |
} else { |
| 520 |
$videos = false; |
| 521 |
} |
| 522 |
return $videos; |
| 523 |
} |
| 524 |
|
| 525 |
|
| 526 |
|
| 527 |
|
| 528 |
public static function queue_add( $post_id ) { |
| 529 |
$aQueue = get_option( 'fv_flowplayer_checker_queue' ) ? get_option( 'fv_flowplayer_checker_queue' ) : array(); |
| 530 |
$aQueue[$post_id] = true; |
| 531 |
update_option( 'fv_flowplayer_checker_queue', $aQueue ); |
| 532 |
} |
| 533 |
|
| 534 |
|
| 535 |
|
| 536 |
|
| 537 |
public static function queue_check( $post_id = false ) { |
| 538 |
global $post; |
| 539 |
$post_id = ( isset($post->ID) ) ? $post->ID : $post_id; |
| 540 |
$aQueue = get_option( 'fv_flowplayer_checker_queue' ) ? get_option( 'fv_flowplayer_checker_queue' ) : array(); |
| 541 |
if( in_array($post_id,array_keys($aQueue)) ) { |
| 542 |
return true; |
| 543 |
} |
| 544 |
return false; |
| 545 |
} |
| 546 |
|
| 547 |
|
| 548 |
|
| 549 |
|
| 550 |
public static function queue_get() { |
| 551 |
return get_option( 'fv_flowplayer_checker_queue', array() ); |
| 552 |
} |
| 553 |
|
| 554 |
|
| 555 |
|
| 556 |
|
| 557 |
public static function queue_remove( $post_id ) { |
| 558 |
$aQueue = get_option( 'fv_flowplayer_checker_queue' ) ? get_option( 'fv_flowplayer_checker_queue' ) : array(); |
| 559 |
if( isset($aQueue[$post_id]) ) { |
| 560 |
unset($aQueue[$post_id]); |
| 561 |
} |
| 562 |
update_option( 'fv_flowplayer_checker_queue', $aQueue ); |
| 563 |
} |
| 564 |
|
| 565 |
|
| 566 |
|
| 567 |
|
| 568 |
} |
| 569 |
|