Catch mediatomb browse errors
[noxon-gateway.git] / src / mediatomb.php
index 11ffe5ad42f64a1171edda74df4f9bd0166998c1..33b9bd87305fbeedf076e65d341c4a3cbd72223e 100644 (file)
 <?php
 require_once 'Services/MediaTomb.php';
 
-function handleRequestMediatomb($fullPath, $prefix)
+function handleMediatomb($action, $fullPath, $prefix)
 {
-    global $mediatomb, $host1;
+    global $mediatomb;
 
     extract($mediatomb);
     try {
         $smt = new Services_MediaTomb($user, $pass, $host, $port);
-
-        $path = substr($fullPath, strlen($prefix));
-        $container = $smt->getContainerByPath($path);
-        $listItems = array();
-        addPreviousItem($listItems, $fullPath);
-
-        foreach ($container->getContainers() as $subContainer) {
-            $listItems[] = getDirItem(
-                $subContainer->title,
-                pathEncode($fullPath . $subContainer->title) . '/'
-            );
-        }
-
-        foreach ($container->getItemIterator(false) as $item) {
-            $di = $item->getDetailedItem();
-            $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);
-            }
-            $listItems[] = getEpisodeItem(
-                $item->title,
-                $itemUrl,
-                '',
-                'MP3'
-            );
+        if ($action == 'browse') {
+            mediatombBrowse($smt, $fullPath, $prefix);
+        } else if ($action == 'single') {
+            mediatombSingle($smt, $fullPath, $prefix);
         }
     } catch (Exception $e) {
         sendMessage('Mediatomb error: ' . $e->getMessage());
         return;
     }
-
-    sendListItems($listItems);
 }
 
-function transcodeMediatombItem($parentId, $title)
+function mediatombBrowse(Services_MediaTomb $smt, $fullPath, $prefix)
 {
-    global $mediatomb, $host1, $cacheDir, $cacheDirUrl;
+    global $mediatomb;
 
-    if (!is_writable($cacheDir)) {
-        sendMessage('Cache dir not writable');
+    $path = substr($fullPath, strlen($prefix));
+    $container = $smt->getContainerByPath($path);
+    if ($container === null) {
+        sendMessage('Error accessing ' . $fullPath);
         return;
     }
 
-    extract($mediatomb);
-    try {
-        $smt = new Services_MediaTomb($user, $pass, $host, $port);
-        $item = $smt->getSingleItem((int) $parentId, $title, false);
+    $listItems = array();
 
-        $filename = $item->id . '.mp3';
-        $cacheFilePath = $cacheDir . $filename;
-        if (!file_exists($cacheFilePath)) {
-            transcodeUrlToMp3($item->url, $cacheFilePath);
+    $it = $container->getItemIterator(false);
+    $it->rewind();
+    $hasFiles = $it->valid();
+    if ($hasFiles && is_array($mediatomb['singleFileDirectories'])) {
+        $enableSingle = false;
+        foreach ($mediatomb['singleFileDirectories'] as $dir) {
+            if (substr($fullPath, 0, strlen($dir)) == $dir) {
+                $enableSingle = true;
+            }
         }
-        if (!file_exists($cacheFilePath)) {
-            sendMessage('Error: No mp3 file found');
-            return;
+        if ($enableSingle) {
+            $listItems[] = getDirItem(
+                'Einzeln',
+                pathEncode('.mt-single/' . $path)
+            );
         }
-        $cacheFileUrl = $cacheDirUrl . $filename;
-        header('Location: ' . $cacheFileUrl);
-    } catch (Exception $e) {
-        sendMessage('Mediatomb error: ' . $e->getMessage());
     }
+
+    foreach ($container->getContainers() as $subContainer) {
+        $listItems[] = getDirItem(
+            $subContainer->title,
+            pathEncode($fullPath . $subContainer->title) . '/'
+        );
+    }
+
+    foreach ($container->getItemIterator(false) as $item) {
+        mediatombAddFile($listItems, $item);
+    }
+
+    sendListItems($listItems, buildPreviousItem($fullPath));
 }
 
-function transcodeUrlToMp3($url, $mp3CacheFilePath)
+function mediatombAddFile(&$listItems, $item)
 {
-    $tmpfile = tempnam(sys_get_temp_dir(), 'transcode');
-    exec(
-        'wget --quiet '
-        . escapeshellarg($url)
-        . ' -O ' . escapeshellarg($tmpfile),
-        $output,
-        $retval
+    global $host1;
+
+    $di = $item->getDetailedItem();
+    $itemUrl = $item->url;
+    if (!clientSupportsType($di->mimetype)) {
+        //client wants transcoded file
+        //noxon iRadio cube does not want to play .ogg files
+        if (isset($GLOBALS['cacheDir']) && $GLOBALS['cacheDir'] != '') {
+            $itemUrl = $host1 . 'transcode-cache.php'
+                . '?url=' . urlencode($itemUrl);
+        } else {
+            $itemUrl = $host1 . 'transcode-nocache.php'
+                . '?url=' . urlencode($itemUrl);
+        }
+    }
+    $listItems[] = getEpisodeItem(
+        $item->title,
+        $itemUrl,
+        '',
+        'MP3'
     );
-    if ($retval !== 0) {
-        throw new Exception('Error downloading URL');
+}
+
+function clientSupportsType($mimetype)
+{
+    if ($mimetype === 'audio/mpeg') {
+        return true;
+    }
+    $ip = $_SERVER['REMOTE_ADDR'];
+    if (isset($GLOBALS['clientSupport'][$ip][$mimetype])
+        && $GLOBALS['clientSupport'][$ip][$mimetype] === true
+    ) {
+        return true;
     }
+    return false;
+}
 
-    exec(
-        'ffmpeg'
-        . ' -i ' . escapeshellarg($tmpfile)
-        . ' ' . escapeshellarg($mp3CacheFilePath)
-        . ' 2>&1',
-        $output,
-        $retval
-    );
-    unlink($tmpfile);
-    if ($retval !== 0) {
-        if (file_exists($mp3CacheFilePath)) {
-            unlink($mp3CacheFilePath);
+/**
+ * Single file mode - shows directories that only have a single file in them.
+ * Each audio file gets its own virtual directory, containing only the
+ * audio file itself.
+ *
+ * Useful children who want to listen a single story before sleeping,
+ * but the noxon's auto switch-off timer is not exactly at the end of
+ * the story. So the next story starts already, and the kid complains
+ * that it wanted to listen to that as well...
+ */
+function mediatombSingle(Services_MediaTomb $smt, $fullPath, $prefix)
+{
+    $path = substr($fullPath, strlen($prefix));
+
+    $parts = explode('/', $path);
+    $fileMode = false;
+    if (substr(end($parts), 0, 5) == 'file-') {
+        $fileMode = true;
+        $fileTitle = substr(end($parts), 5);
+        $path = substr($path, 0, -strlen($fileTitle) - 5);
+    }
+
+    $container = $smt->getContainerByPath($path);
+    $listItems = array();
+
+    $previous = null;
+    if ($fileMode) {
+        //show single file to play
+        $previous = buildPreviousItem(pathEncode($fullPath));
+        $item = $smt->getSingleItem($container, $fileTitle, false);
+        mediatombAddFile($listItems, $item);
+    } else {
+        $previous = buildPreviousItem(pathEncode('internetradio/' . $path . '/dummy'));
+
+        //browse directory
+        foreach ($container->getItemIterator(false) as $item) {
+            $listItems[] = getDirItem(
+                $item->title,
+                pathEncode($fullPath . 'file-' . $item->title)
+            );
         }
-        //var_dump($tmpfile, $output);
-        throw new Exception('Error transcoding file');
     }
+
+    sendListItems($listItems, $previous);
 }
 ?>