function spawn_transcoder($source, $config_file = 'default', $timeout = 20) { // Because we employ "AllowEncodedSlashes NoDecode", the local file must only have slashes encoded in the filename $source_escaped = str_replace("/", "%2f", $source); // In the substitution, we must ensure that the hls_segment_filename value is percent-escaped as it represents a sprintf string $source_escaped_pct_escaped = str_replace("%", "%%", $source_escaped); $exec_subst = array('[SOURCE]' => $source, '[SOURCE-ESCAPED]' => $source_escaped, '[SOURCE-ESCAPED-PCT-ESCAPED]' => $source_escaped_pct_escaped, '[BASEURL]' => baseurl() . '/data/'); if (!($exec = @file_get_contents($config_file, FILE_USE_INCLUDE_PATH))) { if (!($exec = file_get_contents($config_file . '.conf', FILE_USE_INCLUDE_PATH))) { header(HTTP_CUSTOM_HEADER_RESPONDING_TO . urlencode($config_file)); http_response_code(400); return FALSE; } } $exec = trim(preg_replace('/\\s+/', ' ', $exec)); // the exec command should not have newlines in it $exec = str_replace(array_keys($exec_subst), array_values($exec_subst), $exec); // to allow token substitution $process = new MyBackgroundProcess($exec); $process->run(); // first check to see if we have obvious error coming back from the job spawn null; // if not, wait for the creation of the playlist file $filename = dirname($_SERVER["SCRIPT_FILENAME"]) . "/data/{$source_escaped}.m3u8"; // sleep in EXEC_TIMEOUT_POLL_MS millisecond increments as we wait for exec to start output... for ($waits = $timeout * 1000000; $waits > 0 && !file_exists($filename); $waits = $waits - EXEC_TIMEOUT_POLL_MS) { usleep(EXEC_TIMEOUT_POLL_MS); } if (file_exists($filename)) { passthru_m3u8($filename, $filename); return $process; } else { $process->stop(); header(HTTP_CUSTOM_HEADER_RESPONDING_TO . urlencode($exec)); http_response_code(408); return FALSE; } }
case 'print': // reveal all jobs $format = isset($_REQUEST['format']) && !empty($_REQUEST['format']) ? $_REQUEST['format'] : DEFAULT_PRINT_FORMAT; $j->print_r_jobs($format); break; case 'ping': // touch the job associated with the passed source // the following seems to work with the mod_action handler for existing m3u8 files. If the .htaccess file is rearchitected, this will need servicing too. $source_file = basename($_SERVER['REQUEST_URI']); // scrape all up to the final .m3u8, and ditch any parameters appended to the spec // WAS: $source_url = preg_replace('/(.*).m3u8(\?.*)$/i', '\1', urldecode($source_file)); $source_url = preg_replace('/(.*)(.m3u8.*)$/i', '\\1', urldecode($source_file)); if ($job = $j->job_of_source($source_url)) { $j->ping_job($job); } passthru_m3u8($_SERVER['PATH_TRANSLATED'], $source_file); break; case 'spawn': // spawn and register an encoder since caller asked for an m3u8 file that does not yet exist $source = $_REQUEST['source']; $conf = DEFAULT_CONFIG_DIR . (isset($_REQUEST['conf']) && !empty($_REQUEST['conf']) ? $_REQUEST['conf'] : DEFAULT_CONFIG_FILE); //echo "source=" . $source . " and conf=" . $conf . "\n"; die(0); if (!(count($j->get_jobs()) <= $config['max_jobs'])) { http_response_code(408); } elseif ($process = spawn_transcoder($source, $conf, $config['spawn_transcoder_timeout'])) { $j->register_this_job($process, $source, $conf); } break; default: break; }