Example #1
0
 function _receiveJob()
 {
     $result = '';
     $dir_jobs_queued = $this->_options['DirJobsQueued'];
     if (!$dir_jobs_queued) {
         throw new UnexpectedValueException('Configuration option DirJobsQueued required');
     }
     $path = end_with_slash($dir_jobs_queued);
     $job_id = '';
     if (file_exists($path) && is_dir($path)) {
         if ($dh = opendir($path)) {
             while (($file = readdir($dh)) !== false) {
                 if (substr($file, 0, 1) != '.') {
                     $xml = file_get($path . $file);
                     $this->_jobID = substr($file, 0, strpos($file, '.'));
                     $xml = @simplexml_load_string($xml);
                     if (!$xml) {
                         throw new RuntimeException('Could not parse job XML');
                     }
                     $this->_jobXML = $xml;
                     break;
                     // just do one
                 }
             }
             closedir($dh);
         }
     }
 }
Example #2
0
 function _post($type)
 {
     $dir_jobs_queued = $this->_options['DirJobsQueued'];
     $job_id = empty($this->_options['JobID']) ? '' : $this->_options['JobID'];
     // make sure needed configuration is there
     if (!$dir_jobs_queued) {
         throw new UnexpectedValueException('Configuration option DirJobsQueued required');
     }
     // if no JobID configuration option was set make up an ID
     if (!$job_id) {
         $job_id = unique_id($type . 'job');
     }
     $path = end_with_slash($dir_jobs_queued);
     $path .= $job_id . '.xml';
     // make sure we have a directory to write the job xml file to
     if (!safe_path($path)) {
         throw new RuntimeException('Could not create path: ' . $path);
     }
     // build job xml and write to file
     $xml_str = $this->_xmlBody($type);
     if (!@file_put_contents($path, $xml_str)) {
         throw new RuntimeException('Could not create file: ' . $path);
     }
     return $job_id;
 }
 function _get($type, $job_id)
 {
     $dir_cache = $this->getOption('DirCache');
     if (!$dir_cache) {
         throw new UnexpectedValueException('Configuration option DirCache required');
     }
     $path = end_with_slash($dir_cache) . $job_id . '/media.xml';
     $raw_xml = file_get($path);
     $result = '';
     //$progress = -1;
     $status = 'Progress or PercentDone tags not found in response';
     $progress = 10;
     // now if there is any problem we set the percent back to one and retry later
     if (!$raw_xml) {
         $status = 'Queued';
     } else {
         $raw_xml = '<moviemasher>' . $raw_xml . '</moviemasher>';
         $xml = $this->_parseResponse($raw_xml);
         if (!empty($xml->Progress) && is_object($xml->Progress)) {
             $data = $xml->Progress[sizeof($xml->Progress) - 1];
             if (!empty($data->PercentDone)) {
                 $progress = (string) $data->PercentDone;
                 if (!empty($data->Status)) {
                     $status = (string) $data->Status;
                 } else {
                     $progress = 10;
                     $status = 'Status tag empty';
                 }
             } else {
                 $status = 'PercentDone tag empty';
             }
         } else {
             $status = 'Progress tag empty';
         }
     }
     if (strpos($status, 'empty') !== FALSE) {
         $this->log($status . ' in response: ' . $raw_xml);
     }
     $result = array('percent' => $progress, 'status' => $status);
     return $result;
 }
 function MovieMasher($config = array())
 {
     $this->_options = array();
     reset($config);
     foreach ($config as $k => $v) {
         $this->_options[$k] = $v;
     }
     $this->_populateDefaults();
     foreach ($this->_configDefaults as $k => $v) {
         if (!isset($this->_options[$k])) {
             $this->_options[$k] = isset($v['default']) ? $v['default'] : '';
         }
     }
     foreach ($this->_optionsDefaults as $k => $v) {
         if (!isset($this->_options[$k])) {
             $this->_options[$k] = isset($v['default']) ? $v['default'] : '';
         }
     }
     // make sure paths have trailing slashes
     $this->_options['DirLog'] = end_with_slash($this->_options['DirLog']);
     $this->_options['DirCache'] = end_with_slash($this->_options['DirCache']);
     $this->_options['DirHost'] = end_with_slash($this->_options['DirHost']);
     $this->_options['DirTemporary'] = end_with_slash($this->_options['DirTemporary']);
 }
Example #5
0
 function _post($type)
 {
     $result = FALSE;
     $headers = array();
     $rest_endpoint = $this->_options['RESTEndPoint'];
     $rest_key_private = $this->_options['RESTKeyPrivate'];
     $job_id = empty($this->_options['JobID']) ? '' : $this->_options['JobID'];
     // make sure we have an endpoint to post to
     if (!$rest_endpoint) {
         throw new UnexpectedValueException('Configuration option RESTEndPoint required');
     }
     // generate the job xml
     $xml_req = $this->_xmlBody($type);
     if (!empty($rest_key_private)) {
         // generate headers with signature
         $gmd = gmdate('D, d M Y H:i:s O');
         $sig = array();
         $params = $this->_jobParameters($type);
         ksort($params);
         foreach ($params as $k => $v) {
             $sig[] = "{$k}={$v}";
         }
         $sig = $gmd . join('&', $sig);
         $sig = private_signature($rest_key_private, $sig);
         if (!$sig) {
             throw new RuntimeException('Could not sign request');
         }
         $headers[] = 'X-Moviemasher-Date: ' . $gmd;
         $headers[] = 'Authorization: ' . $sig;
     }
     $url = end_with_slash($rest_endpoint) . 'mm.' . $this->getVersion() . '/rest/' . $type . '/';
     if (!empty($this->_options['LogRequests'])) {
         $this->log('SENDING REST Request: ' . $xml_req);
     }
     $xml_string = http_post_xml($url, $xml_req, $headers);
     // make sure we got a response, log it and parse into SimpleXML object
     if (!$xml_string) {
         throw new RuntimeException('Could not post xml to: ' . $url . ' ' . $xml_req);
     }
     if (!empty($this->_options['LogResponses'])) {
         $this->log('RECEIVING REST Response ' . $xml_string);
     }
     $xml = $this->_parseResponse($xml_string);
     // determine job ID and return
     if (!empty($xml->JobID)) {
         $result = (string) $xml->JobID;
     } else {
         if (!empty($job_id)) {
             $result = $job_id;
         }
     }
     return $result;
 }
 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;
 }
    } elseif (!is_uploaded_file($file['tmp_name'])) {
        $err = 'Not an uploaded file';
    }
}
// make sure file extension is valid
if (!$err) {
    $file_name = $file['name'];
    $file_ext = file_extension($file_name);
    if ($file_ext != 'tgz') {
        $err = 'Unsupported extension: ' . $file_ext;
    }
}
// extract the archive to temp directory
if (!$err) {
    set_time_limit(0);
    $tmp_dir = end_with_slash($tmp_dir);
    $tmp_path = $tmp_dir . unique_id('archive');
    $archive_dir = $tmp_path . '/' . $filename . '/';
    if (!extract_archive($file['tmp_name'], $archive_dir)) {
        $err = 'Could not extract to ' . $archive_dir;
    }
}
// move select files from the archive to media directory
if (!$err) {
    switch ($type) {
        case 'audio':
        case 'video':
            // move any soundtrack
            $frag = 'media/audio.' . $encoder_audio_extension;
            $media_path = $media_dir . $frag;
            $archive_path = $archive_dir . $frag;
function url_file_path($url, $dir_path = '')
{
    $result = FALSE;
    if ($url) {
        $result = end_with_slash($dir_path) . md5($url) . '/';
        $extension = file_extension($url);
        if ($extension) {
            $result .= 'media.' . $extension;
        }
    }
    return $result;
}
Example #9
0
 function put($options = array())
 {
     $result = FALSE;
     $url = empty($options['url']) ? '' : $options['url'];
     $path = empty($options['path']) ? '' : $options['path'];
     if (!($url && $path)) {
         throw new InvalidArgumentException('Send array with url and path keys as first argument');
     }
     $ignore = empty($options['ignore']) ? array() : $options['ignore'];
     $is_folder = is_dir($url);
     $urls = array();
     if ($is_folder) {
         $path = end_with_slash($path);
         $urls = MovieMasher_File::files($url);
     } else {
         $urls[] = $url;
     }
     $z = sizeof($urls);
     //if ($this->getOption('Verbose')) $this->log(__METHOD__ . ' putting ' . $z . ' file' . (($z == 1) ? '' : 's') . ': ' . join("\n", $urls));
     $errors = 0;
     // TODO: these could be config options
     $max_errors = 3;
     $wait_seconds = 30;
     for ($i = 0; $i < $z; $i++) {
         $options['url'] = $urls[$i];
         if (in_array($options['url'], $ignore)) {
             continue;
         }
         if ($is_folder) {
             $options['path'] = $path . substr($options['url'], strlen(end_with_slash($url)));
         }
         try {
             $this->_put($options);
             $errors = 0;
             // one success resets error and result
             $result = TRUE;
         } catch (Exception $ex) {
             $result = FALSE;
             $errors++;
             if ($errors > $max_errors) {
                 throw $ex;
             }
             $i--;
             $this->log(__METHOD__ . ' waiting ' . $wait_seconds . ' seconds after error ' . $errors . ': ' . $ex->getMessage());
             sleep($wait_seconds);
         }
     }
     return $result;
 }
function remove_dir_and_files($path)
{
    $result = FALSE;
    if ($path && file_exists($path) && is_dir($path)) {
        $path = end_with_slash($path);
        if ($handle = opendir($path)) {
            $result = TRUE;
            while ($result && FALSE !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    if (is_dir($path . $file)) {
                        $result = remove_dir_and_files($path . $file);
                    } else {
                        $result = @unlink($path . $file);
                    }
                }
            }
            closedir($handle);
        }
        if ($result) {
            $result = @rmdir($path);
        }
    }
    return $result;
}
Example #11
0
 function MovieMasher_Daemon($config)
 {
     parent::MovieMasher($config);
     $this->_options['DirPID'] = end_with_slash($this->_options['DirPID']);
     $this->_options['DirJobsQueued'] = end_with_slash($this->_options['DirJobsQueued']);
 }