function _populateDefaults()
 {
     parent::_populateDefaults();
     $this->_configDefaults['PathWaveformGenerator'] = array('value' => 'PATH', 'description' => "Path to wav2png program for generating waveforms", 'default' => 'wav2png');
     foreach (MovieMasher_Coder_Encoder::$defaultOptions as $k => $a) {
         $this->_optionsDefaults[$k] = $a;
     }
 }
 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;
 }