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;
    }
}
Exemple #2
0
    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;
}