function __buildVisuals($start, $stop) { $path = $this->_options['CoderBaseURL']; $result = array(); $clips = MovieMasher_Coder_Decoder::videoBetween($this->__mashData['clips'], $start, $stop); $fps = floatval($this->_options['DecoderFPS']); $z = sizeof($clips); for ($i = 0; $i < $z; $i++) { $clip = $clips[$i]; // id, type, tag, start, stop, duration (as floats) $clip_trim = $this->__clipTrim($clip, $start, $stop, $fps); if (!$clip_trim) { throw new UnexpectedValueException('Could not determine clip trim: ' . $clip['id']); } $media_tag = $this->__mashData['media'][$clip['id']]; $cmd = ''; $cmd .= $this->_options['PathFFmpeg']; $dims = explode('x', $this->_options['DecoderDimensions']); $url = (string) $media_tag['source']; if (!$url) { $url = (string) $media_tag['url']; } $url = absolute_url(end_with_slash($this->_options['CoderBaseURL']), $url); $url = MovieMasher_Coder::cleanURL($url); switch ($clip['type']) { case 'image': $file_path = cache_url($url, $this->_options['DirCache']); if (!$file_path) { throw new RuntimeException('Could not cache image: ' . $url); } $orig_dims = get_file_info('dimensions', $file_path, $this->_options['PathFFmpeg']); if (!$orig_dims) { throw new RuntimeException('Could not determine image dimensions: ' . $url); } $orig_dims = explode('x', $orig_dims); $switches = scale_switches($orig_dims, $dims, $clip['fill']); $cmd .= ' -loop_input -vframes ' . floor($fps * $clip_trim['trimlength']); $cmd .= ' -s ' . $orig_dims[0] . 'x' . $orig_dims[1]; $cmd .= ' -i ' . $file_path; if ($switches) { $cmd .= ' ' . stringFromSwitches($switches); } else { $cmd .= ' -s ' . $this->_options['DecoderDimensions']; } break; case 'video': $video = (string) $media_tag['source']; $video = MovieMasher_Coder::cleanURL($video); if ($video) { $url = absolute_url(end_with_slash($this->_options['CoderBaseURL']), $video); } $ext = file_extension($url); if ($ext) { // grab the video file $input_path = $file_path = cache_url($url, $this->_options['DirCache']); if (!$file_path) { throw new RuntimeException('Could not cache video: ' . $url); } } else { // grab image sequence - very untested $clip_fps = floatval((string) $media_tag['fps']); $fps_secs = floatval(1) / $clip_fps; $clip_trim['trimstart'] = floor($clip_trim['trimstart'] / $fps_secs) * $fps_secs; $cmd .= ' -r ' . $clip_fps; $file_path = url_file_path($url, $this->_options['DirCache']); $orig_dims = get_file_info('dimensions', $file_path, $this->_options['PathFFmpeg']); if (!$orig_dims) { throw new RuntimeException('Could not determine image sequence dimensions: ' . $url); } $input_path = frame_file_path($file_path, $orig_dims, $clip_fps); $input_path .= '%' . intval($media_tag['zeropadding']) . 'd.jpg'; $fps = $clip_fps; } $orig_dims = get_file_info('dimensions', $file_path, $this->_options['PathFFmpeg']); if (!$orig_dims) { throw new RuntimeException('Could not determine dimensions: ' . $file_path . ' ' . $this->_options['PathFFmpeg']); } $orig_dims = explode('x', $orig_dims); $switches = scale_switches($orig_dims, $dims, $clip['fill']); $cmd .= ' -vframes ' . floor($fps * $clip_trim['trimlength']); $cmd .= ' -s ' . $orig_dims[0] . 'x' . $orig_dims[1]; $cmd .= ' -i ' . $input_path; if ($clip_trim['trimstart']) { $cmd .= ' -ss ' . $clip_trim['trimstart']; } $cmd .= ' -an'; // no audio if ($switches) { $cmd .= ' ' . stringFromSwitches($switches); } else { $cmd .= ' -s ' . $this->_options['DecoderDimensions']; } break; } $cmd .= ' -t ' . $clip_trim['trimlength']; $result[] = $cmd; } return $result; }
function cache_sequence($url, $fps, $clip_fps, $start, $duration, $dir_path, $options = array()) { // TODO: support $speed != 1 $result = FALSE; $url = end_with_slash($url); $cache_path = url_file_path($url, $dir_path); if (empty($options['zeropadding'])) { $options['zeropadding'] = 0; } if (empty($options['duration'])) { $options['duration'] = str_repeat('9', max(1, $options['zeropadding'])) / $clip_fps; } if (empty($options['zeropadding'])) { $options['zeropadding'] = strlen(floor($options['duration'] * $clip_fps)); } if (empty($options['pattern'])) { $options['pattern'] = '%.jpg'; } if (!isset($options['begin'])) { $options['begin'] = 1; } if (empty($options['increment'])) { $options['increment'] = 1; } if (empty($options['dimensions'])) { $options['dimensions'] = get_file_info('dimensions', $cache_path); } $one = floatval(1); $clip_frame_seconds = $one / $clip_fps; $frame_seconds = $one / $fps; if ($duration == -1) { $duration = $options['duration']; } $stop = $start + $duration; $stop = min($stop, $options['duration']); $frames = array(); for ($i = $start; !floatgtre($i, $stop); $i += $clip_frame_seconds) { $frame = floor($i * $clip_fps); $frame_key = 'frame' . $frame; if (!isset($frames[$frame_key])) { $frames[$frame_key] = $frame; } } if ($frames) { $highest_frame = 0; $build_dir = $cache_path; if ($options['dimensions']) { $build_dir = frame_file_path($cache_path, $options['dimensions'], $clip_fps); } asort($frames); $frames = array_values($frames); $z = sizeof($frames); $highest_frame = $frames[$z - 1]; $err = FALSE; for ($i = 0; $i < $z; $i++) { $frame = $frames[$i]; $frame *= $options['increment']; $frame += $options['begin']; $s = (string) $frame; if ($options['zeropadding']) { $s = str_pad($s, $options['zeropadding'], '0', STR_PAD_LEFT); } $file_name = str_replace('%', $s, $options['pattern']); $file_url = $url . $file_name; $file_path = $build_dir . $file_name; $download = TRUE; if ($build_dir != $cache_path) { if (file_exists($file_path) && filesize($file_path)) { $download = FALSE; } } if ($download) { $mime = http_get_file($file_url, $file_path); if (!$mime) { $err = 'Could not download: ' . $file_url . ' ' . $file_path; } else { if ($build_dir == $cache_path) { $data = @getimagesize($file_path); if ($data && $data[0] && $data[1]) { $options['dimensions'] = $data[0] . 'x' . $data[1]; set_file_info($cache_path, 'dimensions', $options['dimensions']); set_file_info($cache_path, 'duration', $options['duration']); set_file_info($cache_path, 'Content-Type', 'video/sequence'); $build_dir = frame_file_path($cache_path, $options['dimensions'], $clip_fps); if (!safe_path($build_dir)) { $err = 'Could not get safe path: ' . $build_dir; } elseif (!@rename($file_path, $build_dir . $file_name)) { $err = 'Could not rename: ' . $file_path . ' ' . $build_dir . $file_name; } else { $file_path = $build_dir . $file_name; } } else { $err = 'Could not get image size: ' . $file_path; } } } } if ($err) { break; } $frames[$i] = $file_path; } if (!$err) { for ($i = 1; $i < $highest_frame; $i++) { $s = (string) $i; if ($options['zeropadding']) { $s = str_pad($s, $options['zeropadding'], '0', STR_PAD_LEFT); } } // ffmpeg needs at least one file starting with zero, having zeropadding digits $options['files'] = $frames; $result = $options; } } return $result; }