| #!/usr/bin/env php |
| |
| <?php |
| |
| // This script is based on the work done by gadgetguru |
| // <david@vuistbijl.nl> at |
| // https://github.com/gadgetguru/PHP-Streaming-Audio and released |
| // under the Public Domain. |
| |
| |
| // This script creates, overwriting if needed, the "metadata.json" |
| // file used by scripts such as "serve-video.py". |
| // |
| // For creating or updating an existing file you have to run |
| // the file as an executable, passing a single argument which |
| // is the name of the file we are accessing to get the media |
| // directory |
| // |
| // With this, a new "metadaba.json" file will be create in the |
| // directory containing the referred file. In this example, the |
| // database will be created at: |
| // |
| // $ LayoutTests/media/content/metadata.json |
| |
| |
| function tmpdir($dir=FALSE, $prefix='php') |
| { |
| if ($dir) { |
| $tmpFile = tempnam($dir, $prefix); |
| } else { |
| if (!sys_get_temp_dir()) |
| return FALSE; |
| $tmpFile = tempnam(sys_get_temp_dir(), $prefix); |
| } |
| |
| if (!file_exists($tmpFile)) |
| return FALSE; |
| unlink($tmpFile); |
| mkdir($tmpFile); |
| if (!is_dir($tmpFile)) |
| return FALSE; |
| |
| return $tmpFile; |
| } |
| |
| |
| function rrmdir($dir) |
| { |
| if (is_dir($dir)) { |
| $objects = array_diff(scandir($dir), array(".", "..")); |
| foreach ($objects as $object) |
| (is_dir($dir . "/" . $object)) ? rrmdir($dir . "/" . $object) : unlink($dir . "/" . $object); |
| reset($objects); |
| rmdir($dir); |
| } |
| } |
| |
| |
| function rcopy($src, $dst) |
| { |
| if (file_exists($dst)) |
| rrmdir($dst); |
| if (is_dir($src)) { |
| mkdir($dst); |
| $files = array_diff(scandir($src), array(".", "..")); |
| foreach ($files as $file) |
| rcopy("$src/$file", "$dst/$file"); |
| } else if (file_exists($src)) { |
| copy($src, $dst); |
| } |
| } |
| |
| |
| function first_dir($name, $dir=FALSE) |
| { |
| $result = FALSE; |
| $root = $dir ? $dir : "./"; |
| $queue = array(realpath($root)); |
| |
| while (sizeof($queue)) { |
| $vertex = array_pop($queue); |
| $objects = array_diff(scandir($vertex), array(".", "..")); |
| foreach ($objects as $object) { |
| $fullPath = $vertex . "/" . $object; |
| if (is_dir($fullPath)) { |
| if ($name == basename($fullPath)) { |
| $result = $fullPath; |
| return $result; |
| } else { |
| array_unshift($queue, $fullPath); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| // 500 on errors |
| $httpStatus = "500 Internal Server Error"; |
| $htmlMessage = ""; |
| |
| if (sizeof($argv) < 2) { |
| trigger_error("You have not specified a 'name' parameter.", E_USER_WARNING); |
| goto answering; |
| } |
| $mediaDirectory = dirname($argv[1]); |
| |
| if (!is_dir($mediaDirectory)) { |
| trigger_error("The provided directory path doesn't exist.", E_USER_WARNING); |
| goto answering; |
| } |
| $databaseFile = realpath($mediaDirectory) . "/metadata.json"; |
| |
| if (file_exists($databaseFile)) { |
| unlink($databaseFile); |
| $htmlMessage = $htmlMessage . "<p/>Deleted previously existing db file at: '" . $databaseFile . "'"; |
| } |
| |
| // We don't have getid3 in WebKit. If not currently present, we |
| // will try to download it now before making use of it. |
| // |
| // getid3 is available at http://getid3.sourceforge.net |
| |
| $getId3DestDir = "getid3"; |
| if (!file_exists($getId3DestDir)) { |
| |
| $tmpDir = tmpdir(FALSE, "php"); |
| if (!is_dir($tmpDir)) { |
| trigger_error("Impossible to create temporal directory.", E_USER_WARNING); |
| goto answering; |
| } |
| |
| $id3DestPath = $tmpDir . "/getid3.zip"; |
| $phpVersion = explode(".", PHP_VERSION); |
| if (($phpVersion[0] > 4) && ($phpVersion[1] > 0)) |
| $id3Url = "http://sourceforge.net/projects/getid3/files/getID3%28%29%201.x/1.9.7/getID3-1.9.7.zip/download"; |
| else |
| $id3Url = "http://sourceforge.net/projects/getid3/files/getID3%28%29%201.x/1.7.10/getid3-1.7.10-20090426.zip/download"; |
| $htmlMessage = $htmlMessage . "<p/>getId3 not in the system.<p/>Downloading from: '" . $id3Url . "'"; |
| |
| $ctxtOpts = array("http" => |
| array( |
| "method" => "GET", |
| "timeout" => 60, |
| ) |
| ); |
| $ctxt = stream_context_create($ctxtOpts); |
| $src = fopen($id3Url, "rb", false, $ctxt); |
| $dest = fopen($id3DestPath, "wb"); |
| $copied = stream_copy_to_stream($src, $dest); |
| fclose($src); |
| fclose($dest); |
| if ($copied == 0) { |
| trigger_error("Impossible to copy the latest getid3 zip release file.", E_USER_WARNING); |
| goto answering; |
| } |
| $htmlMessage = $htmlMessage . "<p/>getId3 downloaded to: '" . $id3DestPath . "'"; |
| |
| if (!exec("unzip " . $id3DestPath . " -d " . $tmpDir)) { |
| trigger_error("Impossible to extract the downloaded zip file.", E_USER_WARNING); |
| goto answering; |
| } |
| $htmlMessage = $htmlMessage . "<p/>Zip file successfully extracted."; |
| |
| $getId3SourceDir = first_dir($getId3DestDir, $tmpDir); |
| if (!$getId3SourceDir) { |
| trigger_error("Impossible to find the getid3 directory with the PHP code to copy.", E_USER_WARNING); |
| goto answering; |
| } |
| $htmlMessage = $htmlMessage . "<p/>getId3 directory to copy found at: '" . $getId3SourceDir . "'"; |
| |
| |
| rcopy($getId3SourceDir, $getId3DestDir); |
| $htmlMessage = $htmlMessage . "<p/>getId3 directory copied to its final destination at: '" . realpath($getId3SourceDir) . "'"; |
| |
| rrmdir($tmpDir); |
| $htmlMessage = $htmlMessage . "<p/>Deleted all temporal files at: '" . $tmpDir . "'"; |
| } |
| |
| |
| // getid3 downloaded. Let's create the database file. |
| require_once("getid3/getid3.php"); |
| $getID3 = new getID3; |
| |
| $id3FileNames = array_diff(scandir($mediaDirectory), array(".", "..")); |
| |
| foreach ($id3FileNames as $id3FileName) { |
| $id3 = $getID3->analyze($mediaDirectory . "/" . $id3FileName); |
| $playfile = array( |
| "fileName" => $id3["filename"], |
| "fileSize" => $id3["filesize"], |
| "playTime" => $id3["playtime_seconds"], |
| "audioStart" => $id3["avdataoffset"], |
| "audioEnd" => $id3["avdataend"], |
| "audioLength" => $id3["avdataend"] - $id3["avdataoffset"], |
| "artist" => $id3["tags"]["id3v2"]["artist"][0], |
| "title" => $id3["tags"]["id3v2"]["title"][0], |
| "bitRate" => $id3["audio"]["bitrate"], |
| "mimeType" => $id3["mime_type"], |
| "fileFormat" => $id3["fileformat"], |
| ); |
| if (empty($playfile["artist"]) || empty($playfile["title"])) |
| list($playfile["artist"], $playfile["title"]) = explode(" - ", substr($playfile["fileName"], 0 , -4)); |
| $playFiles[] = $playfile; |
| } |
| |
| if (!file_put_contents($databaseFile, json_decode($playFiles))) { |
| trigger_error("Impossible to write the getid3 db.", E_USER_WARNING); |
| goto answering; |
| } |
| $htmlMessage = $htmlMessage . "<p/>Written new database file at: '" . $databaseFile . "'"; |
| |
| |
| // Database created, everything OK. |
| $httpStatus = "200 OK"; |
| |
| |
| answering: |
| |
| header("Status: " . $httpStatus); |
| header("HTTP/1.1 " . $httpStatus); |
| header("Connection: close"); |
| header("Content-Type: text/html"); |
| |
| $htmlMessage = "<html><body><h1>" . $httpStatus . "</h1>" . $htmlMessage; |
| |
| if ($httpStatus == "500 Internal Server Error") { |
| if (function_exists("error_get_last")) { |
| $errorArray = error_get_last(); |
| if ($errorArray) { |
| $htmlMessage = sprintf("%s<p/>Error type: %d<p/>Error message: %s<p/>". |
| "Error file: %s<p/>Error line: %d", |
| $htmlMessage, $errorArray["type"], $errorArray["message"], |
| $errorArray["file"], $errorArray["line"]); |
| } |
| } |
| } |
| $htmlMessage = $htmlMessage . "</body><html>"; |
| |
| print($htmlMessage); |
| flush(); |
| exit; |
| ?> |