X-Git-Url: https://git.cweiske.de/playVideoOnDreamboxProxy.git/blobdiff_plain/34daea5a682bd5b5a95e22964d3fa1e1a3e7837b..27d22297323eb1422463d8df44a8a5f5b7ddd447:/www/functions.php diff --git a/www/functions.php b/www/functions.php index 36aacec..617724a 100644 --- a/www/functions.php +++ b/www/functions.php @@ -7,14 +7,21 @@ function getPageUrl() errorInput('No URL given as command line parameter'); } $pageUrl = $argv[1]; - } else { - if (!isset($_SERVER['CONTENT_TYPE'])) { - errorInput('Content type header missing'); - } else if ($_SERVER['CONTENT_TYPE'] != 'text/plain') { - errorInput('Content type is not text/plain but ' . $_SERVER['CONTENT_TYPE']); - } + } else if (!isset($_SERVER['CONTENT_TYPE'])) { + errorInput('Content type header missing'); + } else if ($_SERVER['CONTENT_TYPE'] == 'text/plain') { + //Android app $pageUrl = file_get_contents('php://input'); + } else if ($_SERVER['CONTENT_TYPE'] == 'application/x-www-form-urlencoded') { + //Web form + if (!isset($_POST['url'])) { + errorInput('"url" POST parameter missing'); + } + $pageUrl = $_POST['url']; + } else { + errorInput('Content type is not text/plain but ' . $_SERVER['CONTENT_TYPE']); } + $parts = parse_url($pageUrl); if ($parts === false) { errorInput('Invalid URL in POST data'); @@ -32,28 +39,47 @@ function getYoutubeDlJson($pageUrl, $youtubedlPath) . ' --no-playlist'//would otherwise cause multiple json blocks . ' --quiet' . ' --dump-json' - . ' ' . escapeshellarg($pageUrl) - . ' 2> /dev/null'; + . ' ' . escapeshellarg($pageUrl); - $lastLine = exec($cmd, $output, $exitCode); - if ($exitCode !== 0) { - if ($exitCode === 127) { - errorOut( - 'youtube-dl not found at ' . $youtubedlPath, - '500 youtube-dl not found' - ); - } else if (strpos($lastLine, 'Unsupported URL') !== false) { - errorOut( - 'Unsupported URL at ' . $pageUrl, - '406 Unsupported URL (No video found)' - ); - } else { - errorOut('youtube-dl error: ' . $lastLine); - } + $descriptors = [ + 1 => ['pipe', 'w'],//stdout + 2 => ['pipe', 'w'],//stderr + ]; + $proc = proc_open($cmd, $descriptors, $pipes); + if ($proc === false) { + errorOut('Error running youtube-dl'); + } + $stdout = stream_get_contents($pipes[1]); + $stderr = stream_get_contents($pipes[2]); + + $exitCode = proc_close($proc); + + if ($exitCode === 0) { + //stdout contains the JSON data + return $stdout; + } + + if (strlen($stderr)) { + $lines = explode("\n", trim($stderr)); + $lastLine = end($lines); + } else { + $lines = explode("\n", trim($stdout)); + $lastLine = end($lines); } - $json = implode("\n", $output); - return $json; + if ($exitCode === 127) { + errorOut( + 'youtube-dl not found at ' . $youtubedlPath, + '500 youtube-dl not found' + ); + } else if (strpos($lastLine, 'Unsupported URL') !== false) { + errorOut( + 'Unsupported URL at ' . $pageUrl, + '406 Unsupported URL (No video found)' + ); + } + + errorOut('youtube-dl error: ' . $lastLine); } function extractVideoUrlFromJson($json) @@ -63,17 +89,36 @@ function extractVideoUrlFromJson($json) errorOut('Cannot decode JSON: ' . json_last_error_msg()); } - $url = null; + $safeFormats = []; foreach ($data->formats as $format) { if (strpos($format->format, 'hls') !== false) { //dreambox 7080hd does not play hls files continue; } + if (strpos($format->format, 'vp9') !== false) { + //dreambox 7080hd does not play VP9 video streams + continue; + } if ($format->protocol == 'http_dash_segments') { //split up into multiple small files continue; } + if ($format->ext == 'flv') { + //Internal data flow error + continue; + } + $safeFormats[] = $format; + } + + $url = null; + + //filter: best quality + usort($safeFormats, function ($a, $b) { + return ($b->quality ?? 0) - ($a->quality ?? 0); + }); + foreach ($safeFormats as $format) { $url = $format->url; + break; } if ($url === null) { @@ -90,11 +135,18 @@ function extractVideoUrlFromJson($json) return $url; } -function playVideoOnDreambox($videoUrl, $dreamboxHost) +function playVideoOnDreambox($videoUrl, $dreamboxUrl) { ini_set('track_errors', 1); - $xml = @file_get_contents('http://' . $dreamboxHost . '/web/session'); + $xml = @file_get_contents($dreamboxUrl . '/web/session'); if ($xml === false) { + if (!isset($http_response_header)) { + errorOut( + 'Error fetching dreambox web interface token: ' + . $GLOBALS['lastError'] + ); + } + list($http, $code, $message) = explode( ' ', $http_response_header[0], 3 ); @@ -114,7 +166,7 @@ function playVideoOnDreambox($videoUrl, $dreamboxHost) $sx = simplexml_load_string($xml); $token = (string) $sx; - $playUrl = 'http://' . $dreamboxHost + $playUrl = $dreamboxUrl . '/web/mediaplayerplay' . '?file=4097:0:1:0:0:0:0:0:0:0:' . str_replace('%3A', '%253A', rawurlencode($videoUrl)); @@ -142,4 +194,11 @@ function playVideoOnDreambox($videoUrl, $dreamboxHost) ); } } + +function errorHandlerStore($number, $message, $file, $line) +{ + $GLOBALS['lastError'] = $message; + return false; +} +$GLOBALS['lastError'] = null; ?>