function __buildVideo() { $extension = $this->_options['DecoderVideoExtensionInter']; $video_path = $this->_buildDir . 'build.' . $extension; $pre_cmds = array(); $cmds = array(); $switches = switchesFromString($this->_options['DecoderSwitchesInter']); // override any video codec set, since we're using intermediate video format //if (! empty($switches['vcodec'])) unset($switches['vcodec']); $options = ''; $options .= ' -r ' . $this->_options['DecoderFPS']; //if (empty($switches['vcodec'])) $options .= ' -vcodec ' . $this->_options['DecoderVideoCodec']; if (empty($switches['b'])) { $options .= ' -b ' . (empty($this->_options['DecoderVideoBitrateInter']) ? $this->_options['DecoderVideoBitrate'] : $this->_options['DecoderVideoBitrateInter']) . 'k'; } if ($switches) { $options .= ' ' . stringFromSwitches($switches); } $zero = floatval(0); $cur_time = $zero; $z = sizeof($this->__mashData['timespans']); for ($i = 0; $i < $z; $i++) { if (floatgtr($this->__mashData['timespans'][$i][0], $cur_time)) { // first timespan doesn't start where the last left off, so there is something between $visual_cmds = $this->__buildVisuals($cur_time, $this->__mashData['timespans'][$i][0]); $this->log('building visuals ' . print_r($visual_cmds, 1)); $cmds = array_merge($cmds, $visual_cmds); } $cmd = ''; $cmd .= $this->_options['PathFFmpeg']; $cur_time = $this->__mashData['timespans'][$i][1]; $cmd .= ' -i ' . $this->_buildDir . 'build/' . $i . '-%' . strlen($this->__mashData['timespan_frame_count']) . 'd.jpg'; $cmd .= ' -t ' . ($this->__mashData['timespans'][$i][1] - $this->__mashData['timespans'][$i][0]); $cmds[] = $cmd; //$this->log('building flash ' . $cmd); } if (!floatcmp($cur_time, $this->__mashData['duration'])) { // last timespan doesn't end the mash, so there is stuff after it $visual_cmds = $this->__buildVisuals($cur_time, $this->__mashData['duration']); //$this->log('building trailing visuals ' . print_r($visual_cmds, 1)); $cmds = array_merge($cmds, $visual_cmds); } $options .= ' -f ' . $this->_options['DecoderVideoFormatInter']; $options .= ' -vcodec ' . $this->_options['DecoderVideoCodecInter']; $options .= ' -an '; $z = sizeof($pre_cmds); for ($i = 0; $i < $z; $i++) { $cmd = $pre_cmds[$i]; $result = $this->_shellExecute($cmd); $this->_progressStep('BuildFile', round(($i + 1) * 50 / $z), 'Encoding Frames'); } $z = sizeof($cmds); $files = array(); for ($i = 0; $i < $z; $i++) { $result = ''; $file_name = $this->_buildDir . 'video_' . $i . '.' . $extension; $cmd = $cmds[$i]; $files[] = $file_name; /* // single pass $cmd .= $options . ' -y ' . $file_name; $result .= $this->_shellExecute($cmd); */ // double pass $cmd .= $options . ' -pass {pass} -passlogfile ' . $this->_buildDir . 'FFMPEG2passInter.txt -y ' . $file_name; $cmd1 = str_replace('{pass}', '1', $cmd); $cmd2 = str_replace('{pass}', '2', $cmd); $result .= $this->_shellExecute($cmd1); $result .= $this->_shellExecute($cmd2); if (!file_exists($file_name) || !@filesize($file_name)) { throw new RuntimeException('Could not execute build command: ' . $cmd . "\n" . $result); } // make sure intermediate file is the right dimensions $cmd = ''; $cmd .= $this->_options['PathFFmpeg'] . ' -f ' . $this->_options['DecoderVideoFormatInter']; // need to supply codec hint $cmd .= ' -vcodec ' . $this->_options['DecoderVideoCodecInter']; $cmd .= ' -i ' . $file_name; $response = $this->_shellExecute($cmd); if (!$response) { throw new RuntimeException('Could not create intermediate file ' . $i . ': ' . $cmd); } $int_dims = ffmpeg_info_from_string('dimensions', $response); if (!$int_dims) { throw new RuntimeException('Could not determing intermediate file dimensions ' . $i . ': ' . $cmd . "\n" . $response); } if ($this->_options['DecoderDimensions'] != $int_dims) { throw new RuntimeException('Inter dimensions do not equal output dimensions ' . $i . ' ' . $int_dims); } $this->_progressStep('BuildFile', round(($i + 1) * 50 / $z), 'Encoding Video'); } if ($files) { // concat the files if (sizeof($files) > 1) { $cmd = 'cat ' . join(' ', $files) . ' > ' . $video_path; $result = $this->_shellExecute($cmd, ' 2>&1', 1); if (!file_exists($video_path)) { throw new RuntimeException('Could not merge intermediate files: ' . $cmd . "\n" . $result); } } else { rename($files[0], $video_path); } } return $video_path; }
function get_file_info($type, $file_path, $ffmpeg = '') { $result = FALSE; if ($file_path) { $info_file = meta_file_path($type, $file_path); $result = file_get($info_file); if (!$result) { if (file_exists($file_path)) { $check = array(); switch ($type) { case 'type': // do nothing if file doesn't already exist // do nothing if file doesn't already exist case 'http': case 'ffmpeg': break; case 'Server': // HTTP header data // HTTP header data case 'ETag': case 'Date': case 'Last-Modified': case 'Content-Length': case 'Content-Type': $check['http'] = TRUE; break; case 'dimensions': if (get_file_type($file_path) == 'image') { // we can get dimensions of images with php $check['php'] = TRUE; break; } case 'duration': /* for when we can get duration of audio from php if (get_file_type($file_path) == 'audio') { $check['php'] = TRUE; break; } */ /* for when we can get duration of audio from php if (get_file_type($file_path) == 'audio') { $check['php'] = TRUE; break; } */ case 'fps': // only from FFMPEG // only from FFMPEG case 'audio': $check['ffmpeg'] = TRUE; break; default: // something other than http info needed switch (get_file_type($file_path)) { case 'image': case 'video': case 'audio': break; default: // couldn't get media type or type unrecognizable $check['http'] = TRUE; } } if (!empty($check['php'])) { // for now just images supported $data = @getimagesize($file_path); if ($data && $data[0] && $data[1]) { $result = $data[0] . 'x' . $data[1]; } } if (!empty($check['ffmpeg'])) { $data = get_file_info('ffmpeg', $file_path); if (!$data) { if ($ffmpeg) { $cmd = $ffmpeg; $cmd .= ' -i ' . $file_path; $data = shell_command($cmd); set_file_info($file_path, 'ffmpeg', $data); } } if ($data) { $result = ffmpeg_info_from_string($type, $data); } } if (!empty($check['http'])) { $data = get_file_info('http', $file_path); if ($data) { $data = http_info_from_string($type, $data); if ($data) { $result = $data; } } } // try to cache the data for next time set_file_info($file_path, $type, $result); } } } return $result; }