예제 #1
0
 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;
 }
예제 #2
0
 function __buildSequence($file_path)
 {
     $this->_progressStep('EncodeVideo', 5, 'Encoding Video');
     if (isset($this->_options['EncoderExtension'])) {
         $options = array();
         $orig_dimensions = get_file_info('dimensions', $file_path);
         if (!$orig_dimensions) {
             throw new RuntimeException('Could not read dimensions: ' . $file_path);
         }
         $target_dimensions = scale_proud($orig_dimensions, $this->_options['EncoderDimensions']);
         if (!$target_dimensions) {
             $target_dimensions = $this->_options['EncoderDimensions'];
         }
         $target_size = explode('x', $target_dimensions);
         $options['bitrate'] = round($this->_options['EncoderImageQuality'] / 100 * ($target_size[0] * $target_size[1] * 3 * $this->_options['EncoderFPS'] / 1024));
         $options['dimensions'] = $target_dimensions;
         $options['dimensions_dir'] = $this->_options['EncoderDimensions'];
         $switches = switchesFromString($this->_options['EncoderSwitches']);
         $cached_frames = cache_file_frames($file_path, $this->_options['EncoderFPS'], 0, -1, $options, $switches, $this->_options['PathFFmpeg']);
         if (!$cached_frames) {
             throw new RuntimeException('Could not prepare to cache image sequence: ' . $file_path);
         }
         if (!empty($this->_options['Verbose']) && !empty($cached_frames['command'])) {
             $this->log($cached_frames['command'] . "\n" . $cached_frames['result']);
         }
         if (!$cached_frames['files']) {
             throw new RuntimeException('Could not cache image sequence: ' . $file_path);
         }
         $this->_progressStep('EncodeVideo', 100, 'Encoded Video');
     }
 }