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