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; }
} if (!$err) { $extension = $media_extension; switch ($type) { case 'video': $extension = 'jpg'; // otherwise use image's original extension (eg. png) // otherwise use image's original extension (eg. png) case 'image': if ($type == 'image') { $encoder_fps = '1'; } // move any frames $archive_path = frame_file_path($archive_dir, $encoder_dimensions, $encoder_fps); if (file_exists($archive_path)) { $media_path = frame_file_path($media_dir, $encoder_dimensions, $encoder_fps); if (!move_files_having_extension($extension, $archive_path, $media_path)) { $err = 'Could not move ' . $extension . ' files from ' . $archive_path . ' to ' . $media_path; } } else { $moviemasher_client->log('Path does not exist: ' . $archive_path); } break; } } if (!$err) { // move any meta data $frag = 'meta/'; $archive_path = $archive_dir . $frag; if (file_exists($archive_path)) { $media_path = $media_dir . $frag;
function __buildImage($file_path) { $this->_progressStep('EncodeImage', 5, 'Encoding Image'); $ext = file_extension($file_path); $parent_dir = dir_path($file_path); $tmp_file = $file_path; $orig_dimensions = get_file_info('dimensions', $file_path); if (!$orig_dimensions) { throw new RuntimeException('Could not read image: ' . $file_path); } $cmd = ''; $target_dimensions = scale_proud($orig_dimensions, $this->_options['EncoderDimensions']); if ($target_dimensions) { $cmd .= ' -size ' . $orig_dimensions; $cmd .= ' -resize ' . $target_dimensions; } else { $target_dimensions = $this->_options['EncoderDimensions']; } $frame_path = frame_file_path($file_path, $this->_options['EncoderDimensions'], 1); $file = $frame_path . '0.' . $this->_options['EncoderExtension']; if (!safe_path($file)) { throw new RuntimeException('Could not create path: ' . $file); } if ($cmd || $this->_options['EncoderExtension'] != substr($tmp_file, -strlen($this->_options['EncoderExtension']))) { $cmd = $this->_options['PathCropper'] . $cmd . ' ' . $tmp_file; $cmd .= ' -quality ' . $this->_options['EncoderImageQuality']; $cmd .= ' -type TrueColor'; switch ($this->_options['EncoderExtension']) { case 'ping': case 'png': case 'giff': case 'gif': $cmd .= 'Matte -depth 32'; } $cmd .= ' ' . $file; $shell_result = $this->_shellExecute($cmd); if ($shell_result) { throw new RuntimeException('Could not create image: ' . $shell_result); } } else { copy($tmp_file, $file); } if (!file_exists($file)) { throw new RuntimeException('Failed to create image: ' . $file . ' ' . $cmd); } $this->_progressStep('EncodeImage', 100, 'Encoded Image'); }
function cache_file_frames($vid_file_path, $fps, $start = 0, $duration = -1, $options = array(), $switches = array(), $ffmpeg = '') { $result = FALSE; if ($vid_file_path && $fps && $duration && file_exists($vid_file_path)) { $media_dimensions = get_file_info('dimensions', $vid_file_path, $ffmpeg); // target frame size, if different from video if (empty($options['dimensions'])) { $options['dimensions'] = $media_dimensions; } // video duration, for convenience if (empty($options['duration'])) { $options['duration'] = get_file_info('duration', $vid_file_path, $ffmpeg); } $dimensions = scale_even($options['dimensions']); $size = explode('x', $dimensions); if (empty($options['dimensions_dir'])) { $options['dimensions_dir'] = $dimensions; } $build_dir = frame_file_path($vid_file_path, $options['dimensions_dir'], $fps); $media_duration = $options['duration']; if ($build_dir && $media_duration && $media_dimensions && safe_path($build_dir)) { $orig_size = explode('x', $media_dimensions); if ($duration == -1) { $duration = $media_duration; if ($duration && $start) { $duration -= $start; } } $fps = floatval($fps); $start = floatval($start); $start_frame = ceil($fps * $start); $duration = floatval($duration); $media_duration = floatval($media_duration); $media_frames = floor($media_duration * $fps); $digits = strlen($media_frames); $frames = 2 + ceil($fps * $duration); $files = array(); $need_files = FALSE; $stop_frame = $start_frame + $frames; // print 'cacheVideoFileFrames: ' . $start_frame . ' to ' . $stop_frame . "\n"; for ($i = $start_frame; $i <= $stop_frame; $i++) { $seq_file = $build_dir . str_pad(1 + $i, $digits, '0', STR_PAD_LEFT) . '.jpg'; $files[] = $seq_file; if (!$need_files && !file_exists($seq_file)) { $need_files = TRUE; } } $result = array(); $result['files'] = $files; $err = FALSE; if ($need_files) { $cmd = ''; $cmd .= $ffmpeg; if ($start) { $cmd .= ' -ss ' . $start; } $cmd .= ' -s ' . $orig_size[0] . 'x' . $orig_size[1]; $cmd .= ' -i ' . $vid_file_path; $cmd .= ' -s ' . join('x', scale_proud($orig_size, $size)); if ($switches) { $cmd .= ' ' . stringFromSwitches($switches); } if (empty($switches['b']) && !empty($options['bitrate'])) { $cmd .= ' -b ' . $options['bitrate'] . 'K'; } $cmd .= ' -an -r ' . $fps . ' -vframes ' . $frames . ' ' . $build_dir . 'build%d.jpg'; $result['command'] = $cmd; //print $cmd; $response = shell_command($cmd); $result['result'] = $response; if ($response) { $last_file = ''; for ($i = 0; $i <= $frames; $i++) { $frame_file = $build_dir . 'build' . (1 + $i) . '.jpg'; if (!file_exists($frame_file)) { // ffmpeg doesn't always write every last frame if ($last_file) { // so we copy the last one repeatedly if (!@copy($last_file, $frame_file)) { $err = TRUE; } } else { $err = TRUE; } } if (!$err) { $seq_file = $files[$i]; $last_file = $seq_file; if (!@rename($frame_file, $seq_file)) { $err = TRUE; } } if ($err) { break; } } } } /* if (! $err) { $result['duration'] = $frames / $fps; $result['orig_dimensions'] = join('x', $orig_size); $result['orig_extension'] = file_extension($vid_file_path); $result['dimensions'] = join('x', $size); $result['type'] = 'video'; $result['zeropadding'] = $digits; $result['fps'] = $fps; $result['orig_fps'] = get_file_info('fps', $vid_file_path, $ffmpeg); $result['pattern'] = '%.jpg'; $result['icon'] = str_pad(1 + $start_frame + floor($frames / 2), $digits, '0', STR_PAD_LEFT) . '.jpg'; } */ if ($err) { $result['files'] = ''; } } } return $result; }
} // add media data to existing media.xml file if (!$err) { $duration = get_file_info('duration', $media_dir); $label = get_file_info('label', $media_dir); // start with an unattributed media tag document $media_xml = simplexml_load_string('<moviemasher><media /></moviemasher>'); // add required attributes $media_xml->media->addAttribute('type', $type); $media_xml->media->addAttribute('id', $id); // add standard attributes $media_xml->media->addAttribute('label', $label); $media_xml->media->addAttribute('group', $type); // add required for rendering $media_xml->media->addAttribute('source', $partial_media_path . $id . '/media.' . $media_extension); $frame_path = frame_file_path($partial_media_path . $id . '/', $encoder_dimensions, $encoder_fps); $audio = 1; $did_icon = 0; switch ($type) { case 'image': $frame_path .= '0.' . $encoder_extension; $media_xml->media->addAttribute('url', $frame_path); $media_xml->media->addAttribute('icon', $frame_path); break; case 'video': $frames = floor($duration * $encoder_fps); $zero_padding = strlen($frames); $media_xml->media->addAttribute('url', $frame_path); $media_xml->media->addAttribute('fps', $encoder_fps); $media_xml->media->addAttribute('pattern', '%.' . $encoder_extension); $media_xml->media->addAttribute('zeropadding', $zero_padding);