--- /dev/null
+<?php
+set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../src/');
+$fullUri = $_SERVER['REQUEST_URI'];
+if (isset($_SERVER['REDIRECT_URL'])) {
+ $path = $_SERVER['REDIRECT_URL'];
+} else {
+ $path = '/';
+}
+$dataDir = __DIR__ . '/../data/';
+$varDir = realpath(__DIR__ . '/../var') . '/';
+$cacheDir = __DIR__ . '/../www/cache/';
+$host1 = 'http://radio567.vtuner.com/';
+$host2 = 'http://radio5672.vtuner.com/';
+if ($_SERVER['HTTP_HOST'] !== '') {
+ $host1 = 'http://' . $_SERVER['HTTP_HOST'] . '/';
+ $host2 = 'http://' . $_SERVER['HTTP_HOST'] . '/';
+}
+$cacheDirUrl = $host1 . 'cache/';
+$cfgFile = $dataDir . 'config.php';
+if (file_exists($cfgFile)) {
+ include $cfgFile;
+}
+?>
$itemUrl = $item->url;
if ($di->mimetype !== 'audio/mpeg') {
//noxon iRadio cube does not want to play .ogg files
- $itemUrl = $host1 . 'transcode'
- . '?mtParentId=' . $container->id
- . '&mtItemTitle=' . urlencode($item->title);
+ $itemUrl = $host1 . 'transcode-nocache.php'
+ . '?url=' . urlencode($itemUrl);
}
$listItems[] = getEpisodeItem(
$item->title,
sendListItems($listItems);
}
-
-function transcodeMediatombItem($parentId, $title)
-{
- global $mediatomb, $host1, $cacheDir, $cacheDirUrl;
-
- if (!is_writable($cacheDir)) {
- sendMessage('Cache dir not writable');
- return;
- }
-
- extract($mediatomb);
- try {
- $smt = new Services_MediaTomb($user, $pass, $host, $port);
- $item = $smt->getSingleItem((int) $parentId, $title, false);
-
- $filename = $item->id . '.mp3';
- $cacheFilePath = $cacheDir . $filename;
- if (!file_exists($cacheFilePath)) {
- transcodeUrlToMp3($item->url, $cacheFilePath);
- }
- if (!file_exists($cacheFilePath)) {
- sendMessage('Error: No mp3 file found');
- return;
- }
- $cacheFileUrl = $cacheDirUrl . $filename;
- header('Location: ' . $cacheFileUrl);
- } catch (Exception $e) {
- sendMessage('Mediatomb error: ' . $e->getMessage());
- }
-}
-
-function transcodeUrlToMp3($url, $mp3CacheFilePath)
-{
- $tmpfile = tempnam(sys_get_temp_dir(), 'transcode');
- exec(
- 'wget --quiet '
- . escapeshellarg($url)
- . ' -O ' . escapeshellarg($tmpfile),
- $output,
- $retval
- );
- if ($retval !== 0) {
- throw new Exception('Error downloading URL');
- }
-
- exec(
- 'ffmpeg'
- . ' -i ' . escapeshellarg($tmpfile)
- . ' ' . escapeshellarg($mp3CacheFilePath)
- . ' 2>&1',
- $output,
- $retval
- );
- unlink($tmpfile);
- if ($retval !== 0) {
- if (file_exists($mp3CacheFilePath)) {
- unlink($mp3CacheFilePath);
- }
- //var_dump($tmpfile, $output);
- throw new Exception('Error transcoding file');
- }
-}
?>
<?php
-set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../src/');
-$fullUri = $_SERVER['REQUEST_URI'];
-if (isset($_SERVER['REDIRECT_URL'])) {
- $path = $_SERVER['REDIRECT_URL'];
-} else {
- $path = '/';
-}
-$dataDir = __DIR__ . '/../data/';
-$varDir = realpath(__DIR__ . '/../var') . '/';
-$cacheDir = __DIR__ . '/../www/cache/';
-$host1 = 'http://radio567.vtuner.com/';
-$host2 = 'http://radio5672.vtuner.com/';
-if ($_SERVER['HTTP_HOST'] !== '') {
- $host1 = 'http://' . $_SERVER['HTTP_HOST'] . '/';
- $host2 = 'http://' . $_SERVER['HTTP_HOST'] . '/';
-}
-$cacheDirUrl = $host1 . 'cache/';
-$cfgFile = $dataDir . 'config.php';
-if (file_exists($cfgFile)) {
- include $cfgFile;
-}
+require_once __DIR__ . '/../src/header.php';
if (strtolower($fullUri) == '/setupapp/radio567/asp/browsexpa/loginxml.asp?token=0'
|| $fullUri == '/RadioNativeLogin.php'
} else if ($path == '/RadioNativeFavorites.php') {
//Favorites, defined via web interface
sendMessage('Unsupported');
-} else if ($path == '/transcode') {
- require_once 'mediatomb.php';
- transcodeMediatombItem($_GET['mtParentId'], $_GET['mtItemTitle']);
- exit();
}
handleRequest(ltrim($path, '/'));
--- /dev/null
+<?php
+/**
+ * Transcode audio file URLs to .mp3, cache them and stream them while
+ * transcoding is in progress.
+ */
+require_once __DIR__ . '/../src/header.php';
+
+if (!isset($_GET['url'])) {
+ errorOut('url parameter missing');
+}
+$parts = parse_url($_GET['url']);
+if ($parts === false || !isset($parts['scheme'])) {
+ errorOut('Invalid URL');
+}
+if ($parts['scheme'] !== 'http' && $parts['scheme'] !== 'https') {
+ errorOut('URL is neither http nor https');
+}
+$url = $_GET['url'];
+
+if (!is_dir($cacheDir)) {
+ errorOut('Cache dir does not exist');
+}
+if (!is_writable($cacheDir)) {
+ errorOut('Cache dir not writable');
+}
+
+$cacheFileName = str_replace(array(':', '/'), '-', $url) . '.mp3';
+$cacheFilePath = $cacheDir . $cacheFileName;
+
+if (file_exists($cacheFilePath)) {
+ header('HTTP/1.0 302 Moved Temporarily');
+ header('Location: ' . $cacheDirUrl . urlencode($cacheFileName));
+ exit(1);
+}
+
+$cmd = 'ffmpeg'
+ . ' -loglevel error'
+ . ' -i ' . escapeshellarg($url)
+ . ' -f mp3'
+ . ' -';
+
+$descriptorspec = array(
+ 1 => array('pipe', 'w'),// stdout is a pipe that the child will write to
+ 2 => array('pipe', 'w')//stderr
+);
+
+register_shutdown_function('shutdown');
+
+$process = proc_open($cmd, $descriptorspec, $pipes);
+if (is_resource($process)) {
+ $tmpCacheFile = tempnam(sys_get_temp_dir(), 'transcode-cache-');
+ $cacheHdl = fopen($tmpCacheFile, 'wb');
+ header('Content-type: audio/mpeg');
+ while ($data = fread($pipes[1], 1000)) {
+ //write cache
+ fwrite($cacheHdl, $data);
+ //output to browser
+ echo $data;
+ //TODO: maybe flush() and ob_flush();
+ }
+
+ $errors = stream_get_contents($pipes[2]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ $retval = proc_close($process);
+
+ fclose($cacheHdl);
+ if ($retval === 0) {
+ rename($tmpCacheFile, $cacheFilePath);
+ } else {
+ header('HTTP/1.0 500 Internal Server Error');
+ header('Content-type: text/plain');
+ echo "Error transcoding\n";
+ echo $errors . "\n";
+ unlink($tmpCacheFile);
+ }
+}
+
+function shutdown()
+{
+ global $process, $pipes, $tmpCacheFile;
+
+ if (connection_aborted()) {
+ //end ffmpeg and clean temp file
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_terminate($process);
+ unlink($tmpCacheFile);
+ }
+}
+
+function errorOut($msg)
+{
+ header('HTTP/1.0 400 Bad request');
+ header('Content-type: text/plain');
+ echo $msg . "\n";
+ exit(1);
+}
+?>
--- /dev/null
+<?php
+/**
+ * Transcode audio file URLs to .mp3 and stream it while
+ * transcoding is in progress.
+ */
+//require_once __DIR__ . '/../src/header.php';
+
+if (!isset($_GET['url'])) {
+ errorOut('url parameter missing');
+}
+$parts = parse_url($_GET['url']);
+if ($parts === false || !isset($parts['scheme'])) {
+ errorOut('Invalid URL');
+}
+if ($parts['scheme'] !== 'http' && $parts['scheme'] !== 'https') {
+ errorOut('URL is neither http nor https');
+}
+$url = $_GET['url'];
+
+$cmd = 'ffmpeg'
+ . ' -loglevel error'
+ . ' -i ' . escapeshellarg($url)
+ . ' -f mp3'
+ . ' -';
+
+$descriptorspec = array(
+ 1 => array('pipe', 'w'),// stdout is a pipe that the child will write to
+ 2 => array('pipe', 'w')//stderr
+);
+
+register_shutdown_function('shutdown');
+
+$process = proc_open($cmd, $descriptorspec, $pipes);
+if (is_resource($process)) {
+ header('Content-type: audio/mpeg');
+ while ($data = fread($pipes[1], 10000)) {
+ //output to browser
+ echo $data;
+ //TODO: maybe flush() and ob_flush();
+ }
+
+ $errors = stream_get_contents($pipes[2]);
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ $retval = proc_close($process);
+
+ if ($retval !== 0) {
+ header('HTTP/1.0 500 Internal Server Error');
+ header('Content-type: text/plain');
+ echo "Error transcoding\n";
+ echo $errors . "\n";
+ }
+}
+
+function shutdown()
+{
+ global $process, $pipes;
+
+ if (connection_aborted()) {
+ //end ffmpeg and clean temp file
+ fclose($pipes[1]);
+ fclose($pipes[2]);
+ proc_terminate($process);
+ }
+}
+
+function errorOut($msg)
+{
+ header('HTTP/1.0 400 Bad request');
+ header('Content-type: text/plain');
+ echo $msg . "\n";
+ exit(1);
+}
+?>