Do not try to parse stderr data + check if we really have an URL
[playVideoOnDreamboxProxy.git] / www / play.php
1 <?php
2 $youtubedlPath = '/usr/bin/youtube-dl';
3 $dreamboxHost  = 'dreambox';
4
5 $cfgFile = __DIR__ . '/../data/config.php';
6 if (file_exists($cfgFile)) {
7     include $cfgFile;
8 }
9
10 $pageUrl  = getPageUrl();
11 $videoUrl = extractVideoUrl($pageUrl, $youtubedlPath);
12 header('Video-URL: ' . $videoUrl);
13 playVideoOnDreambox($videoUrl, $dreamboxHost);
14
15 function getPageUrl()
16 {
17     global $argv, $argc;
18     if (php_sapi_name() == 'cli') {
19         if ($argc < 2) {
20             errorInput('No URL given as command line parameter');
21         }
22         $pageUrl = $argv[1];
23     } else {
24         if (!isset($_SERVER['CONTENT_TYPE'])) {
25             errorInput('Content type header missing');
26         } else if ($_SERVER['CONTENT_TYPE'] != 'text/plain') {
27             errorInput('Content type is not text/plain but ' . $_SERVER['CONTENT_TYPE']);
28         }
29         $pageUrl = file_get_contents('php://input');
30     }
31     $parts = parse_url($pageUrl);
32     if ($parts === false) {
33         errorInput('Invalid URL in POST data');
34     } else if (!isset($parts['scheme'])) {
35         errorInput('Invalid URL in POST data: No scheme');
36     } else if ($parts['scheme'] !== 'http' && $parts['scheme'] !== 'https') {
37         errorInput('Invalid URL in POST data: Non-HTTP scheme');
38     }
39     return $pageUrl;
40 }
41
42 function extractVideoUrl($pageUrl, $youtubedlPath)
43 {
44     $cmd = $youtubedlPath
45         . ' --quiet'
46         . ' --dump-json'
47         . ' ' . escapeshellarg($pageUrl)
48         . ' 2> /dev/null';
49
50     $lastLine = exec($cmd, $output, $exitCode);
51     if ($exitCode !== 0) {
52         if (strpos($lastLine, 'Unsupported URL') !== false) {
53             errorOut(
54                 'Unsupported URL  at ' . $pageUrl,
55                 '406 Unsupported URL (No video found)'
56             );
57         } else {
58             errorOut('youtube-dl error: ' . $lastLine);
59         }
60     }
61
62     $json = implode("\n", $output);
63     $data = json_decode($json);
64
65     $url = null;
66     foreach ($data->formats as $format) {
67         //dreambox 7080hd does not play hls files
68         if (strpos($format->format, 'hls') !== false) {
69             continue;
70         }
71         $url = $format->url;
72     }
73
74     if ($url === null) {
75         //use URL chosen by youtube-dl
76         $url = $data->url;
77     }
78
79     if ($url == '') {
80         errorOut(
81             'No video URL found',
82             '406 No video URL found'
83         );
84     }
85     return $url;
86 }
87
88 function playVideoOnDreambox($videoUrl, $dreamboxHost)
89 {
90     ini_set('track_errors', 1);
91     $xml = @file_get_contents('http://' . $dreamboxHost . '/web/session');
92     if ($xml === false) {
93         errorOut('Failed to fetch dreambox session token: ' . $php_errormsg);
94     }
95     $sx = simplexml_load_string($xml);
96     $token = (string) $sx;
97
98     $playUrl = 'http://' . $dreamboxHost
99         . '/web/mediaplayerplay'
100         . '?file=4097:0:1:0:0:0:0:0:0:0:'
101         . str_replace('%3A', '%253A', rawurlencode($videoUrl));
102
103     $ctx = stream_context_create(
104         array(
105             'http' => array(
106                 'method'  => 'POST',
107                 'header'  => 'Content-type: application/x-www-form-urlencoded',
108                 'content' => 'sessionid=' . $token,
109                 //'ignore_errors' => true
110             )
111         )
112     );
113     $ret = file_get_contents($playUrl, false, $ctx);
114     if ($ret !== false) {
115         header('HTTP/1.0 200 OK');
116         echo "Video play request sent to dreambox\n";
117         exit(0);
118     } else {
119         errorOut(
120             'Failed to send video play request to dreambox: ' . $php_errormsg
121         );
122     }
123 }
124
125 function errorInput($msg)
126 {
127     header('HTTP/1.0 400 Bad Request');
128     header('Content-type: text/plain');
129     echo $msg . "\n";
130     syslog(LOG_ERR, 'playVideoOnDreamboxProxy: ' . $httpStatus . ':' .  $msg);
131     exit(1);
132 }
133
134 function errorOut($msg, $httpStatus = '500 Internal Server Error')
135 {
136     header('HTTP/1.0 ' . $httpStatus);
137     header('Content-type: text/plain');
138     echo $msg . "\n";
139     syslog(LOG_ERR, 'playVideoOnDreamboxProxy: ' . $httpStatus . ': ' . $msg);
140     exit(2);
141 }
142 ?>