From d7a59b4131a8d5ac0bdb588153cf566ca795674a Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Thu, 2 Feb 2017 00:08:29 +0000 Subject: [PATCH 01/15] #100: Start of Ponify import --- app/Commands/UploadTrackCommand.php | 20 +- app/Console/Commands/ImportPonify.php | 316 ++++++++++++++++++++++++++ app/Console/Kernel.php | 3 +- 3 files changed, 334 insertions(+), 5 deletions(-) create mode 100644 app/Console/Commands/ImportPonify.php diff --git a/app/Commands/UploadTrackCommand.php b/app/Commands/UploadTrackCommand.php index 2bbd221b..0648aa77 100644 --- a/app/Commands/UploadTrackCommand.php +++ b/app/Commands/UploadTrackCommand.php @@ -43,6 +43,8 @@ class UploadTrackCommand extends CommandBase private $_version; private $_isReplacingTrack; + public $_file; + /** * @return bool */ @@ -94,7 +96,16 @@ class UploadTrackCommand extends CommandBase */ public function execute() { - $trackFile = Request::file('track', null); + $trackFile = null; + $source = 'direct_upload'; + + if ($this->_file !== null) { + $trackFile = $this->_file; + $source = 'ponify'; + } else { + $trackFile = Request::file('track', null); + } + if (!$this->_isReplacingTrack) { $coverFile = Request::file('cover', null); } @@ -114,7 +125,7 @@ class UploadTrackCommand extends CommandBase $this->_track->user_id = $this->_artist->id; // The title set here is a placeholder; it'll be replaced by ParseTrackTagsCommand // if the file contains a title tag. - $this->_track->title = Request::get('title', pathinfo($trackFile->getClientOriginalName(), PATHINFO_FILENAME)); + $this->_track->title = mb_strimwidth(Request::get('title', pathinfo($trackFile->getClientOriginalName(), PATHINFO_FILENAME)), 0, 100, '...'); // The duration/version of the track cannot be changed until the encoding is successful $this->_track->duration = $audio->getDuration(); $this->_track->current_version = $this->_version; @@ -129,7 +140,8 @@ class UploadTrackCommand extends CommandBase if (!is_dir(Config::get('ponyfm.files_directory').'/queued-tracks')) { mkdir(Config::get('ponyfm.files_directory').'/queued-tracks', 0755, true); } - $trackFile = $trackFile->move(Config::get('ponyfm.files_directory').'/queued-tracks', $this->_track->id . 'v' . $this->_version); + + $trackFile = $trackFile->move(Config::get('ponyfm.files_directory') . '/queued-tracks', $this->_track->id . 'v' . $this->_version); $input = Request::all(); $input['track'] = $trackFile; @@ -183,7 +195,7 @@ class UploadTrackCommand extends CommandBase $this->_track->metadata = json_decode(Request::get('metadata', null)); } $autoPublish = (bool)($input['auto_publish'] ?? $this->_autoPublishByDefault); - $this->_track->source = $this->_customTrackSource ?? 'direct_upload'; + $this->_track->source = $this->_customTrackSource ?? $source; $this->_track->save(); if (!$this->_isReplacingTrack) { diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php new file mode 100644 index 00000000..656671ec --- /dev/null +++ b/app/Console/Commands/ImportPonify.php @@ -0,0 +1,316 @@ +error('Import aborted!'); + $this->error('Resume it from here using: --startAt=' . $this->currentFile); + $this->isInterrupted = true; + } + + /** + * Execute the console command. + * + * @return mixed + */ + public function handle() + { + // Most of this is the same as the old ImportMLPMA.php command with a few tweaks + // to use the new upload system and the newer version of Laravel + + pcntl_signal(SIGINT, [$this, 'handleInterrupt']); + + $ponifyPath = Config::get('ponyfm.files_directory').'/ponify'; + $tmpPath = Config::get('ponyfm.files_directory').'/tmp'; + + if (!File::exists($tmpPath)) { + File::makeDirectory($tmpPath); + } + + //========================================================================================================== + // Get the list of files and artists + //========================================================================================================== + $this->comment('Enumerating Ponify files...'); + $files = File::allFiles($ponifyPath); + $this->info(sizeof($files) . ' files found!'); + + $this->comment('Enumerating artists...'); + $artists = File::directories($ponifyPath); + $this->info(sizeof($artists) . ' artists found!'); + + $this->comment('Importing tracks...'); + + $totalFiles = sizeof($files); + + $fileToStartAt = (int)$this->option('startAt') - 1; + $this->comment("Skipping $fileToStartAt files..." . PHP_EOL); + + $files = array_slice($files, $fileToStartAt); + $this->currentFile = $fileToStartAt; + + foreach ($files as $file) { + $this->currentFile++; + + pcntl_signal_dispatch(); + + if ($this->isInterrupted) { + break; + } + + $this->comment('[' . $this->currentFile . '/' . $totalFiles . '] Importing track [' . $file->getFilename() . ']...'); + + if (in_array($file->getExtension(), $this->ignoredExtensions)) { + $this->comment('This is not an audio file! Skipping...' . PHP_EOL); + continue; + } + + $this->info('Path to file: ' . $file->getRelativePath()); + $path_components = explode(DIRECTORY_SEPARATOR, $file->getRelativePath()); + $artist_name = $path_components[0]; + $album_name = array_key_exists(1, $path_components) ? $path_components[1] : null; + + $this->info('Artist: ' . $artist_name); + $this->info('Album: ' . $album_name); + + //========================================================================================================== + // Analyse the track so we can find the MIME type and album art + //========================================================================================================== + + $getId3 = new getID3; + + // all tags read by getID3, including the cover art + $allTags = $getId3->analyze($file->getPathname()); + + // tags specific to a file format (ID3 or Atom), pre-normalization but with cover art removed + $rawTags = []; + + // normalized tags used by Pony.fm + $parsedTags = []; + + if ($file->getExtension() === 'mp3') { + list($parsedTags, $rawTags) = $this->getId3Tags($allTags); + } else { + if ($file->getExtension() === 'm4a') { + list($parsedTags, $rawTags) = $this->getAtomTags($allTags); + } + } + + //========================================================================================================== + // Create new user for the artist if one doesn't exist + //========================================================================================================== + + $artist = User::where('display_name', '=', $artist_name)->first(); + + if (!$artist) { + $artist = new User; + $artist->display_name = $artist_name; + $artist->email = null; + $artist->is_archived = true; + + $artist->slug = Str::slug($artist_name); + + $slugExists = User::where('slug', '=', $artist->slug)->first(); + if ($slugExists) { + $this->error('Horsefeathers! The slug ' . $artist->slug . ' is already taken!'); + $artist->slug = $artist->slug . '-' . Str::random(4); + } + + $artist->save(); + } + + //========================================================================================================== + // Grab the image and save it so we can pass that along when the track gets uploaded + //========================================================================================================== + + $this->comment('Extracting cover art!'); + $coverId = null; + if (array_key_exists('comments', $allTags) && array_key_exists('picture', $allTags['comments'])) { + $image = $allTags['comments']['picture'][0]; + + if ($image['image_mime'] === 'image/png') { + $extension = 'png'; + } else { + if ($image['image_mime'] === 'image/jpeg') { + $extension = 'jpg'; + } else { + if ($image['image_mime'] === 'image/gif') { + $extension = 'gif'; + } else { + $this->error('Unknown cover art format!'); + } + } + } + // write temporary image file + $imageFilename = $file->getFilename() . ".cover.$extension"; + $imageFilePath = "$tmpPath/" . $imageFilename; + File::put($imageFilePath, $image['data']); + + $imageFile = new UploadedFile($imageFilePath, $imageFilename, $image['image_mime'], null, null, true); + $cover = Image::upload($imageFile, $artist); + $coverId = $cover->id; + } else { + $this->comment('No cover art found!'); + } + + //========================================================================================================== + // Send the track into the upload system like a user just uploaded a track + //========================================================================================================== + + $this->comment('Transcoding the track!'); + Auth::loginUsingId($artist->id); + + $getID3 = new getID3; + $getID3->analyze($file->getPathname()); + + $mime = null; + + if (isset($getID3->info['mime_type'])) $mime = $getID3->info['mime_type']; + + $trackFile = new UploadedFile($file->getPathname(), $file->getFilename(), $mime, null, null, true); + + $upload = new UploadTrackCommand(true); + $upload->_file = $trackFile; + $result = $upload->execute(); + + if ($result->didFail()) { + $this->error(json_encode($result->getValidator()->messages()->getMessages(), JSON_PRETTY_PRINT)); + } else { + $track = Track::find($result->getResponse()['id']); + $track->license_id = 2; + $track->save(); + } + + echo PHP_EOL . PHP_EOL; + } + } + + /** + * @param array $rawTags + * @return array + */ + protected function getId3Tags($rawTags) + { + $tags = $rawTags['tags']['id3v2']; + $comment = null; + + if (isset($tags['comment'])) { + // The "comment" tag comes in with a badly encoded string index + // so its array key has to be used implicitly. + $key = array_keys($tags['comment'])[0]; + + // The comment may have a null byte at the end. trim() removes it. + $comment = trim($tags['comment'][$key]); + + // Replace the malformed comment with the "fixed" one. + unset($tags['comment'][$key]); + $tags['comment'][0] = $comment; + } + + return [ + [ + 'title' => $tags['title'][0], + 'artist' => $tags['artist'][0], + 'band' => isset($tags['band']) ? $tags['band'][0] : null, + 'genre' => isset($tags['genre']) ? $tags['genre'][0] : null, + 'track_number' => isset($tags['track_number']) ? $tags['track_number'][0] : null, + 'album' => isset($tags['album']) ? $tags['album'][0] : null, + 'year' => isset($tags['year']) ? (int)$tags['year'][0] : null, + 'comments' => $comment, + 'lyrics' => isset($tags['unsynchronised_lyric']) ? $tags['unsynchronised_lyric'][0] : null, + ], + $tags + ]; + } + + /** + * @param array $rawTags + * @return array + */ + protected function getAtomTags($rawTags) + { + $tags = $rawTags['tags']['quicktime']; + + $trackNumber = null; + if (isset($tags['track_number'])) { + $trackNumberComponents = explode('/', $tags['track_number'][0]); + $trackNumber = $trackNumberComponents[0]; + } + + return [ + [ + 'title' => $tags['title'][0], + 'artist' => $tags['artist'][0], + 'band' => isset($tags['band']) ? $tags['band'][0] : null, + 'album_artist' => isset($tags['album_artist']) ? $tags['album_artist'][0] : null, + 'genre' => isset($tags['genre']) ? $tags['genre'][0] : null, + 'track_number' => $trackNumber, + 'album' => isset($tags['album']) ? $tags['album'][0] : null, + 'year' => isset($tags['year']) ? (int)$tags['year'][0] : null, + 'comments' => isset($tags['comments']) ? $tags['comments'][0] : null, + 'lyrics' => isset($tags['lyrics']) ? $tags['lyrics'][0] : null, + ], + $tags + ]; + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 1c84903f..d2ef8ff7 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -46,7 +46,8 @@ class Kernel extends ConsoleKernel \Poniverse\Ponyfm\Console\Commands\MergeAccounts::class, \Poniverse\Ponyfm\Console\Commands\SyncPoniverseAccounts::class, \Poniverse\Ponyfm\Console\Commands\FixMLPMAImages::class, - \Poniverse\Ponyfm\Console\Commands\VersionFiles::class + \Poniverse\Ponyfm\Console\Commands\VersionFiles::class, + \Poniverse\Ponyfm\Console\Commands\ImportPonify::class, ]; /** From 35264036616a0ab50a61708b855a4c8a74a24437 Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Thu, 2 Feb 2017 01:35:53 +0000 Subject: [PATCH 02/15] #100: Duplication detection --- app/Console/Commands/ImportPonify.php | 288 ++++++++++++++++++++++++-- 1 file changed, 265 insertions(+), 23 deletions(-) diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 656671ec..1928e98c 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -3,6 +3,7 @@ namespace Poniverse\Ponyfm\Console\Commands; use Auth; +use Carbon\Carbon; use Config; use DB; use File; @@ -139,6 +140,10 @@ class ImportPonify extends Command $getId3 = new getID3; + // Enable file hashing + $getId3->option_md5_data = true; + $getId3->option_md5_data_source = true; + // all tags read by getID3, including the cover art $allTags = $getId3->analyze($file->getPathname()); @@ -148,20 +153,83 @@ class ImportPonify extends Command // normalized tags used by Pony.fm $parsedTags = []; - if ($file->getExtension() === 'mp3') { - list($parsedTags, $rawTags) = $this->getId3Tags($allTags); - } else { - if ($file->getExtension() === 'm4a') { - list($parsedTags, $rawTags) = $this->getAtomTags($allTags); + list($parsedTags, $rawTags) = $this->parseTags($file); + + //========================================================================================================== + // Check to see if we have this track already, if so, compare hashes of the two files + //========================================================================================================== + + $artist = User::where('display_name', '=', $artist_name)->first(); + $artistId = null; + + $this->comment("Checking for duplicates"); + + if ($artist) { + $artistId = $artist->id; + } + + $existingTrack = Track::where('title', '=', $parsedTags['title']) + ->where('user_id', '=', $artistId) + ->first(); + + if ($existingTrack) { + // We got one!! + // Ok, let's not get too excited + // First let's see if we have a matching file type + + $importFormat = $this->getFormat($file->getExtension()); + if ($importFormat == null) { + // No idea what this is, skip file + $this->comment(sprintf("Not an audio file (%s), skipping...", $importFormat)); + continue; } + + $existingFile = null; + + foreach ($existingTrack->trackFiles as $trackFile) { + if ($trackFile->format == $importFormat) { + $existingFile = $trackFile; + } + } + + if ($existingFile === null) { + // Can't find a matching format + // Check to see if we have a better quality file + + } else { + $this->comment("Found existing file"); + + // Found a matching format, are they the same? + $getId3_existing = new getID3; + $getId3_existing->option_md5_data = true; + $getId3_existing->option_md5_data_source = true; + $existingFileTags = $getId3->analyze($existingFile->getFile()); + + $importHash = array_key_exists('md5_data_source', $allTags) ? $allTags['md5_data_source'] : $allTags['md5_data']; + $targetHash = array_key_exists('md5_data_source', $existingFileTags) ? $existingFileTags['md5_data_source'] : $existingFileTags['md5_data']; + + $this->info("Archive hash: " . $importHash); + $this->info("Pony.fm hash: " . $targetHash); + + if ($importHash == $targetHash) { + // Audio is identical, no need to reupload + // We can update the metadata though + // TODO: Update metadata + $this->comment("Versions are the same. Skipping...\n"); + continue; + } else { + // Audio is different. Replace if it came from MLPMA + // TODO: Replace file + } + } + } else { + $this->comment("No duplicates"); } //========================================================================================================== // Create new user for the artist if one doesn't exist //========================================================================================================== - $artist = User::where('display_name', '=', $artist_name)->first(); - if (!$artist) { $artist = new User; $artist->display_name = $artist_name; @@ -220,12 +288,7 @@ class ImportPonify extends Command $this->comment('Transcoding the track!'); Auth::loginUsingId($artist->id); - $getID3 = new getID3; - $getID3->analyze($file->getPathname()); - - $mime = null; - - if (isset($getID3->info['mime_type'])) $mime = $getID3->info['mime_type']; + $mime = $allTags['mime_type']; $trackFile = new UploadedFile($file->getPathname(), $file->getFilename(), $mime, null, null, true); @@ -245,13 +308,81 @@ class ImportPonify extends Command } } + protected function hashAudio($filepath) { + $hash = hash_file('crc32b', $filepath); + $array = unpack('N', pack('H*', $hash)); + return $array[1]; + } + + protected function getFormat($extension) { + foreach(Track::$Formats as $name => $format) { + if ($format['extension'] == $extension) { + return $name; + } + } + + return null; + } + + public function parseTags($file) + { + $audioCodec = $file->getExtension(); + + //========================================================================================================== + // Extract the original tags. + //========================================================================================================== + $getId3 = new getID3; + + // all tags read by getID3, including the cover art + $allTags = $getId3->analyze($file->getPathname()); + + // $rawTags => tags specific to a file format (ID3 or Atom), pre-normalization but with cover art removed + // $parsedTags => normalized tags used by Pony.fm + + if ($audioCodec === 'mp3') { + list($parsedTags, $rawTags) = $this->getId3Tags($allTags); + } elseif (Str::startsWith($audioCodec, ['aac', 'alac'])) { + list($parsedTags, $rawTags) = $this->getAtomTags($allTags); + } elseif (in_array($audioCodec, ['vorbis', 'flac'])) { + list($parsedTags, $rawTags) = $this->getVorbisTags($allTags); + } elseif (Str::startsWith($audioCodec, ['pcm', 'adpcm'])) { + list($parsedTags, $rawTags) = $this->getAtomTags($allTags); + } else { + // Assume the file is untagged if it's in an unknown format. + $parsedTags = [ + 'title' => null, + 'artist' => null, + 'band' => null, + 'genre' => null, + 'track_number' => null, + 'album' => null, + 'year' => null, + 'release_date' => null, + 'comments' => null, + 'lyrics' => null, + ]; + $rawTags = []; + } + + + return [$parsedTags, $rawTags]; + } + /** * @param array $rawTags * @return array */ protected function getId3Tags($rawTags) { - $tags = $rawTags['tags']['id3v2']; + if (array_key_exists('tags', $rawTags) && array_key_exists('id3v2', $rawTags['tags'])) { + $tags = $rawTags['tags']['id3v2']; + } elseif (array_key_exists('tags', $rawTags) && array_key_exists('id3v1', $rawTags['tags'])) { + $tags = $rawTags['tags']['id3v1']; + } else { + $tags = []; + } + + $comment = null; if (isset($tags['comment'])) { @@ -267,15 +398,22 @@ class ImportPonify extends Command $tags['comment'][0] = $comment; } + $trackNumber = 1; + if (isset($tags['track_number'])) { + $trackNumberComponents = explode('/', $tags['track_number'][0]); + $trackNumber = $trackNumberComponents[0]; + } + return [ [ - 'title' => $tags['title'][0], - 'artist' => $tags['artist'][0], + 'title' => isset($tags['title']) ? $tags['title'][0] : null, + 'artist' => isset($tags['artist']) ? $tags['artist'][0] : null, 'band' => isset($tags['band']) ? $tags['band'][0] : null, 'genre' => isset($tags['genre']) ? $tags['genre'][0] : null, - 'track_number' => isset($tags['track_number']) ? $tags['track_number'][0] : null, + 'track_number' => $trackNumber, 'album' => isset($tags['album']) ? $tags['album'][0] : null, - 'year' => isset($tags['year']) ? (int)$tags['year'][0] : null, + 'year' => isset($tags['year']) ? (int) $tags['year'][0] : null, + 'release_date' => isset($tags['release_date']) ? $this->parseDateString($tags['release_date'][0]) : null, 'comments' => $comment, 'lyrics' => isset($tags['unsynchronised_lyric']) ? $tags['unsynchronised_lyric'][0] : null, ], @@ -289,9 +427,57 @@ class ImportPonify extends Command */ protected function getAtomTags($rawTags) { - $tags = $rawTags['tags']['quicktime']; + if (array_key_exists('tags', $rawTags) && array_key_exists('quicktime', $rawTags['tags'])) { + $tags = $rawTags['tags']['quicktime']; + } else { + $tags = []; + } - $trackNumber = null; + $trackNumber = 1; + if (isset($tags['track_number'])) { + $trackNumberComponents = explode('/', $tags['track_number'][0]); + $trackNumber = $trackNumberComponents[0]; + } + + if (isset($tags['release_date'])) { + $releaseDate = $this->parseDateString($tags['release_date'][0]); + } elseif (isset($tags['creation_date'])) { + $releaseDate = $this->parseDateString($tags['creation_date'][0]); + } else { + $releaseDate = null; + } + + return [ + [ + 'title' => isset($tags['title']) ? $tags['title'][0] : null, + 'artist' => isset($tags['artist']) ? $tags['artist'][0] : null, + 'band' => isset($tags['band']) ? $tags['band'][0] : null, + 'album_artist' => isset($tags['album_artist']) ? $tags['album_artist'][0] : null, + 'genre' => isset($tags['genre']) ? $tags['genre'][0] : null, + 'track_number' => $trackNumber, + 'album' => isset($tags['album']) ? $tags['album'][0] : null, + 'year' => isset($tags['year']) ? (int) $tags['year'][0] : null, + 'release_date' => $releaseDate, + 'comments' => isset($tags['comments']) ? $tags['comments'][0] : null, + 'lyrics' => isset($tags['lyrics']) ? $tags['lyrics'][0] : null, + ], + $tags + ]; + } + + /** + * @param array $rawTags + * @return array + */ + protected function getVorbisTags($rawTags) + { + if (array_key_exists('tags', $rawTags) && array_key_exists('vorbiscomment', $rawTags['tags'])) { + $tags = $rawTags['tags']['vorbiscomment']; + } else { + $tags = []; + } + + $trackNumber = 1; if (isset($tags['track_number'])) { $trackNumberComponents = explode('/', $tags['track_number'][0]); $trackNumber = $trackNumberComponents[0]; @@ -299,18 +485,74 @@ class ImportPonify extends Command return [ [ - 'title' => $tags['title'][0], - 'artist' => $tags['artist'][0], + 'title' => isset($tags['title']) ? $tags['title'][0] : null, + 'artist' => isset($tags['artist']) ? $tags['artist'][0] : null, 'band' => isset($tags['band']) ? $tags['band'][0] : null, 'album_artist' => isset($tags['album_artist']) ? $tags['album_artist'][0] : null, 'genre' => isset($tags['genre']) ? $tags['genre'][0] : null, 'track_number' => $trackNumber, 'album' => isset($tags['album']) ? $tags['album'][0] : null, - 'year' => isset($tags['year']) ? (int)$tags['year'][0] : null, + 'year' => isset($tags['year']) ? (int) $tags['year'][0] : null, + 'release_date' => isset($tags['date']) ? $this->parseDateString($tags['date'][0]) : null, 'comments' => isset($tags['comments']) ? $tags['comments'][0] : null, 'lyrics' => isset($tags['lyrics']) ? $tags['lyrics'][0] : null, ], $tags ]; } + + /** + * Parses a potentially-partial date string into a proper date object. + * + * The tagging formats we deal with base their date format on ISO 8601, but + * the timestamp may be incomplete. + * + * @link https://code.google.com/p/mp4v2/wiki/iTunesMetadata + * @link https://wiki.xiph.org/VorbisComment#Date_and_time + * @link http://id3.org/id3v2.4.0-frames + * + * @param string $dateString + * @return null|Carbon + */ + protected function parseDateString(string $dateString) + { + switch (Str::length($dateString)) { + // YYYY + case 4: + try { + return Carbon::createFromFormat('Y', $dateString) + ->month(1) + ->day(1); + } catch (\InvalidArgumentException $e) { + return null; + } + + // YYYY-MM + case 7: + try { + return Carbon::createFromFormat('Y m', str_replace("-", " ", $dateString)) + ->day(1); + } catch (\InvalidArgumentException $e) { + return null; + } + + // YYYY-MM-DD + case 10: + try { + return Carbon::createFromFormat('Y m d', str_replace("-", " ", $dateString)); + } catch (\InvalidArgumentException $e) { + return null; + } + break; + + default: + // We might have an ISO-8601 string in our hooves. + // If not, give up. + try { + return Carbon::createFromFormat(Carbon::ISO8601, $dateString); + } catch (\InvalidArgumentException $e) { + return null; + } + } + } } From 8841bd2dc7dfda55a747c935f14fb0ac01cfbb5f Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Tue, 21 Feb 2017 17:16:29 +0000 Subject: [PATCH 03/15] #100: Progress commit --- app/Console/Commands/ImportPonify.php | 85 +++++++++++++++---- ...2017_02_08_233324_create_ponify_tracks.php | 48 +++++++++++ 2 files changed, 118 insertions(+), 15 deletions(-) create mode 100644 database/migrations/2017_02_08_233324_create_ponify_tracks.php diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 1928e98c..6fb7799a 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -140,10 +140,6 @@ class ImportPonify extends Command $getId3 = new getID3; - // Enable file hashing - $getId3->option_md5_data = true; - $getId3->option_md5_data_source = true; - // all tags read by getID3, including the cover art $allTags = $getId3->analyze($file->getPathname()); @@ -153,7 +149,11 @@ class ImportPonify extends Command // normalized tags used by Pony.fm $parsedTags = []; - list($parsedTags, $rawTags) = $this->parseTags($file); + list($parsedTags, $rawTags) = $this->parseTags($file, $allTags); + + $imageFilename = $file->getFilename() . ".tags.txt"; + $imageFilePath = "$tmpPath/" . $imageFilename; + File::put($imageFilePath, print_r($allTags, true)); //========================================================================================================== // Check to see if we have this track already, if so, compare hashes of the two files @@ -194,18 +194,46 @@ class ImportPonify extends Command if ($existingFile === null) { // Can't find a matching format - // Check to see if we have a better quality file + // Before we do anything, was this from MLPMA? + $mlpmaTrack = DB::table('mlpma_tracks')->where('track_id', '=', $existingTrack->id)->first(); + + if (!is_null($mlpmaTrack)) { + // This was from the archive + // See if we have a higher quality source file + if (Track::$Formats[$importFormat]['is_lossless']) { + // Source is lossless, is the existing track lossy? + if ($existingFile->isMasterLossy()) { + // Cool! Let's replace it + $this->comment('Replacing (' . $existingTrack->id . ') ' . $existingTrack->title); + + $this->replaceTrack($file, $existingTrack, $artist, $allTags['mime_type']); + + continue; + } + } + } + + continue; } else { $this->comment("Found existing file"); // Found a matching format, are they the same? + // Before we check it, see if it came from MLPMA + // We're only replacing tracks with the same format if they're archived + $getId3_source = new getID3; + + $getId3_source->option_md5_data = true; + $getId3_source->option_md5_data_source = true; + + $sourceWithMd5 = $getId3_source->analyze($file->getPathname()); + $getId3_existing = new getID3; $getId3_existing->option_md5_data = true; $getId3_existing->option_md5_data_source = true; - $existingFileTags = $getId3->analyze($existingFile->getFile()); + $existingFileTags = $getId3_existing->analyze($existingFile->getFile()); - $importHash = array_key_exists('md5_data_source', $allTags) ? $allTags['md5_data_source'] : $allTags['md5_data']; + $importHash = array_key_exists('md5_data_source', $sourceWithMd5) ? $sourceWithMd5['md5_data_source'] : $sourceWithMd5['md5_data']; $targetHash = array_key_exists('md5_data_source', $existingFileTags) ? $existingFileTags['md5_data_source'] : $existingFileTags['md5_data']; $this->info("Archive hash: " . $importHash); @@ -218,8 +246,12 @@ class ImportPonify extends Command $this->comment("Versions are the same. Skipping...\n"); continue; } else { - // Audio is different. Replace if it came from MLPMA - // TODO: Replace file + // Audio is different, let's replace it + $this->comment('Replacing (' . $existingTrack->id . ') ' . $existingTrack->title); + + $this->replaceTrack($file, $existingTrack, $artist, $allTags['mime_type']); + + continue; } } } else { @@ -253,9 +285,15 @@ class ImportPonify extends Command $this->comment('Extracting cover art!'); $coverId = null; + $image = null; + if (array_key_exists('comments', $allTags) && array_key_exists('picture', $allTags['comments'])) { $image = $allTags['comments']['picture'][0]; + } else if (array_key_exists('id3v2', $allTags) && array_key_exists('APIC', $allTags['id3v2'])) { + $image = $allTags['id3v2']['APIC'][0]; + } + if ($image !== null) { if ($image['image_mime'] === 'image/png') { $extension = 'png'; } else { @@ -300,6 +338,7 @@ class ImportPonify extends Command $this->error(json_encode($result->getValidator()->messages()->getMessages(), JSON_PRETTY_PRINT)); } else { $track = Track::find($result->getResponse()['id']); + $track->cover_id = $coverId; $track->license_id = 2; $track->save(); } @@ -324,17 +363,13 @@ class ImportPonify extends Command return null; } - public function parseTags($file) + public function parseTags($file, $allTags) { $audioCodec = $file->getExtension(); //========================================================================================================== // Extract the original tags. //========================================================================================================== - $getId3 = new getID3; - - // all tags read by getID3, including the cover art - $allTags = $getId3->analyze($file->getPathname()); // $rawTags => tags specific to a file format (ID3 or Atom), pre-normalization but with cover art removed // $parsedTags => normalized tags used by Pony.fm @@ -376,6 +411,8 @@ class ImportPonify extends Command { if (array_key_exists('tags', $rawTags) && array_key_exists('id3v2', $rawTags['tags'])) { $tags = $rawTags['tags']['id3v2']; + } elseif (array_key_exists('id3v2', $rawTags)) { + $tags = $rawTags['tags']['id3v2']; } elseif (array_key_exists('tags', $rawTags) && array_key_exists('id3v1', $rawTags['tags'])) { $tags = $rawTags['tags']['id3v1']; } else { @@ -555,4 +592,22 @@ class ImportPonify extends Command } } } + + protected function replaceTrack($toBeUploaded, $targetTrack, $artist, $mime) { + Auth::loginUsingId($artist->id); + + $trackFile = new UploadedFile($toBeUploaded->getPathname(), $toBeUploaded->getFilename(), $mime, null, null, true); + + $upload = new UploadTrackCommand(true, false, null, false, $targetTrack->getNextVersion(), $targetTrack); + $upload->_file = $trackFile; + $result = $upload->execute(); + + if ($result->didFail()) { + $this->error(json_encode($result->getValidator()->messages()->getMessages(), JSON_PRETTY_PRINT)); + } else { + $track = Track::find($result->getResponse()['id']); + $track->license_id = 2; + $track->save(); + } + } } diff --git a/database/migrations/2017_02_08_233324_create_ponify_tracks.php b/database/migrations/2017_02_08_233324_create_ponify_tracks.php new file mode 100644 index 00000000..30424b05 --- /dev/null +++ b/database/migrations/2017_02_08_233324_create_ponify_tracks.php @@ -0,0 +1,48 @@ +increments('id'); + $table->integer('track_id')->unsigned()->index(); + $table->string('path')->index(); + $table->string('filename')->index(); + $table->string('extension')->index(); + $table->dateTime('imported_at'); + $table->text('parsed_tags'); + $table->text('raw_tags'); + }); + + Schema::table('ponify_tracks', function(Blueprint $table) + { + $table->foreign('track_id')->references('id')->on('tracks')->onUpdate('RESTRICT')->onDelete('RESTRICT'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('ponify_tracks', function(Blueprint $table) + { + $table->dropForeign('ponify_tracks_track_id_foreign'); + }); + + Schema::drop('ponify_tracks'); + } +} From 1e153a614c7484f7f6c69ee3430c20f80fc18fee Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Tue, 28 Feb 2017 22:49:46 +0000 Subject: [PATCH 04/15] #100: Progress commit 2 --- app/Console/Commands/ImportPonify.php | 115 ++++++++++++++++++-------- 1 file changed, 80 insertions(+), 35 deletions(-) diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 6fb7799a..1f006e66 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -194,22 +194,16 @@ class ImportPonify extends Command if ($existingFile === null) { // Can't find a matching format - // Before we do anything, was this from MLPMA? - $mlpmaTrack = DB::table('mlpma_tracks')->where('track_id', '=', $existingTrack->id)->first(); + // See if we have a higher quality source file + if (Track::$Formats[$importFormat]['is_lossless']) { + // Source is lossless, is the existing track lossy? + if ($existingFile->isMasterLossy()) { + // Cool! Let's replace it + $this->comment('Replacing (' . $existingTrack->id . ') ' . $existingTrack->title); - if (!is_null($mlpmaTrack)) { - // This was from the archive - // See if we have a higher quality source file - if (Track::$Formats[$importFormat]['is_lossless']) { - // Source is lossless, is the existing track lossy? - if ($existingFile->isMasterLossy()) { - // Cool! Let's replace it - $this->comment('Replacing (' . $existingTrack->id . ') ' . $existingTrack->title); + $this->replaceTrack($file, $existingTrack, $artist, $allTags['mime_type']); - $this->replaceTrack($file, $existingTrack, $artist, $allTags['mime_type']); - - continue; - } + continue; } } @@ -221,36 +215,75 @@ class ImportPonify extends Command // Found a matching format, are they the same? // Before we check it, see if it came from MLPMA // We're only replacing tracks with the same format if they're archived - $getId3_source = new getID3; + $mlpmaTrack = DB::table('mlpma_tracks')->where('track_id', '=', $existingTrack->id)->first(); - $getId3_source->option_md5_data = true; - $getId3_source->option_md5_data_source = true; + if (!is_null($mlpmaTrack)) { + $getId3_source = new getID3; - $sourceWithMd5 = $getId3_source->analyze($file->getPathname()); + $getId3_source->option_md5_data = true; + $getId3_source->option_md5_data_source = true; - $getId3_existing = new getID3; - $getId3_existing->option_md5_data = true; - $getId3_existing->option_md5_data_source = true; - $existingFileTags = $getId3_existing->analyze($existingFile->getFile()); + $sourceWithMd5 = $getId3_source->analyze($file->getPathname()); - $importHash = array_key_exists('md5_data_source', $sourceWithMd5) ? $sourceWithMd5['md5_data_source'] : $sourceWithMd5['md5_data']; - $targetHash = array_key_exists('md5_data_source', $existingFileTags) ? $existingFileTags['md5_data_source'] : $existingFileTags['md5_data']; + $getId3_existing = new getID3; + $getId3_existing->option_md5_data = true; + $getId3_existing->option_md5_data_source = true; + $existingFileTags = $getId3_existing->analyze($existingFile->getFile()); - $this->info("Archive hash: " . $importHash); - $this->info("Pony.fm hash: " . $targetHash); + $importHash = array_key_exists('md5_data_source', $sourceWithMd5) ? $sourceWithMd5['md5_data_source'] : $sourceWithMd5['md5_data']; + $targetHash = array_key_exists('md5_data_source', $existingFileTags) ? $existingFileTags['md5_data_source'] : $existingFileTags['md5_data']; - if ($importHash == $targetHash) { - // Audio is identical, no need to reupload - // We can update the metadata though - // TODO: Update metadata - $this->comment("Versions are the same. Skipping...\n"); - continue; + $this->info("Archive hash: " . $importHash); + $this->info("Pony.fm hash: " . $targetHash); + + if ($importHash == $targetHash) { + // Audio is identical, no need to reupload + // We can update the metadata though + $this->comment("Versions are the same. Updating metadata...\n"); + $changedMetadata = false; + + if (strlen($existingTrack->description) < strlen($parsedTags['comments'])) { + $existingTrack->description = $parsedTags['comments']; + $changedMetadata = true; + $this->comment("Updated description"); + } + + if (strlen($existingTrack->lyrics) < strlen($parsedTags['lyrics'])) { + $existingTrack->lyrics = $parsedTags['lyrics']; + $changedMetadata = true; + $this->comment("Updated lyrics"); + } + + if ($changedMetadata) $existingTrack->save(); + + continue; + } else { + // Audio is different, let's replace it + $this->comment('Replacing (' . $existingTrack->id . ') ' . $existingTrack->title); + + $this->replaceTrack($file, $existingTrack, $artist, $allTags['mime_type']); + + continue; + } } else { - // Audio is different, let's replace it - $this->comment('Replacing (' . $existingTrack->id . ') ' . $existingTrack->title); + $this->comment("Not replacing, user uploaded"); - $this->replaceTrack($file, $existingTrack, $artist, $allTags['mime_type']); + // We can update the metadata though + $changedMetadata = false; + if (strlen($existingTrack->description) < strlen($parsedTags['comments'])) { + $existingTrack->description = $parsedTags['comments']; + $changedMetadata = true; + $this->comment("Updated description"); + } + + if (strlen($existingTrack->lyrics) < strlen($parsedTags['lyrics'])) { + $existingTrack->lyrics = $parsedTags['lyrics']; + $changedMetadata = true; + $this->comment("Updated lyrics"); + } + + if ($changedMetadata) $existingTrack->save(); continue; } } @@ -341,6 +374,18 @@ class ImportPonify extends Command $track->cover_id = $coverId; $track->license_id = 2; $track->save(); + + // If we made it to here, the track is intact! Log the import. + DB::table('ponify_tracks') + ->insert([ + 'track_id' => $result->getResponse()['id'], + 'path' => $file->getRelativePath(), + 'filename' => $file->getFilename(), + 'extension' => $file->getExtension(), + 'imported_at' => Carbon::now(), + 'parsed_tags' => json_encode($parsedTags), + 'raw_tags' => json_encode($rawTags), + ]); } echo PHP_EOL . PHP_EOL; From ede77808740854ddf4affa86687bd12ff3634797 Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Mon, 27 Mar 2017 19:44:20 +0100 Subject: [PATCH 05/15] #100: Don't know why this was missing --- app/Console/Commands/ImportPonify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 1f006e66..93e978ca 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -456,7 +456,7 @@ class ImportPonify extends Command { if (array_key_exists('tags', $rawTags) && array_key_exists('id3v2', $rawTags['tags'])) { $tags = $rawTags['tags']['id3v2']; - } elseif (array_key_exists('id3v2', $rawTags)) { + } elseif (array_key_exists('id3v2', $rawTags['tags'])) { $tags = $rawTags['tags']['id3v2']; } elseif (array_key_exists('tags', $rawTags) && array_key_exists('id3v1', $rawTags['tags'])) { $tags = $rawTags['tags']['id3v1']; From 104318e7893d901d90c937ea8aa1330e0f35c410 Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Thu, 27 Apr 2017 23:39:07 +0100 Subject: [PATCH 06/15] Changed name --- public/templates/pages/mlpforums-advertising-program.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/templates/pages/mlpforums-advertising-program.html b/public/templates/pages/mlpforums-advertising-program.html index 66ede1db..e821821a 100644 --- a/public/templates/pages/mlpforums-advertising-program.html +++ b/public/templates/pages/mlpforums-advertising-program.html @@ -180,10 +180,10 @@ contact for more information or answers to my questions? -

Just shoot a message to Poniverse's Head of Public Relations, Simon, +

Just shoot a message to Poniverse's Head of Public Relations, Mercury, at - simon@poniverse.net and he'll + mercury@poniverse.net and he'll be happy to answer any questions you have about Pony.fm and the advertising deal offered here!

From 373703990c26462ce2d259abda24ad13d5cc0422 Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Mon, 15 May 2017 12:18:04 +0100 Subject: [PATCH 07/15] Added ponify directory in config --- app/Console/Commands/ImportPonify.php | 2 +- config/ponyfm.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 93e978ca..855c4d99 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -82,7 +82,7 @@ class ImportPonify extends Command pcntl_signal(SIGINT, [$this, 'handleInterrupt']); - $ponifyPath = Config::get('ponyfm.files_directory').'/ponify'; + $ponifyPath = Config::get('ponyfm.ponify_directory'); $tmpPath = Config::get('ponyfm.files_directory').'/tmp'; if (!File::exists($tmpPath)) { diff --git a/config/ponyfm.php b/config/ponyfm.php index da95567f..b27cd037 100644 --- a/config/ponyfm.php +++ b/config/ponyfm.php @@ -13,6 +13,7 @@ return [ */ 'files_directory' => env('PONYFM_DATASTORE'), + 'ponify_directory' => env('PONIFY_DIRECTORY'), /* |-------------------------------------------------------------------------- From c510dd7dfc50ceb5a9ba0813e2eec17b17c91a07 Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Mon, 15 May 2017 17:59:51 +0100 Subject: [PATCH 08/15] Added ID3v2 support and some stuff from the MLPMA script --- app/Console/Commands/ImportPonify.php | 163 ++++++++++++++++++++++++-- 1 file changed, 151 insertions(+), 12 deletions(-) diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 855c4d99..47070e67 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -12,6 +12,8 @@ use getID3; use Poniverse\Ponyfm\Models\Image; use Poniverse\Ponyfm\Models\Track; use Poniverse\Ponyfm\Models\User; +use Poniverse\Ponyfm\Models\Genre; +use Poniverse\Ponyfm\Models\Album; use Poniverse\Ponyfm\Commands\UploadTrackCommand; use Illuminate\Console\Command; use Illuminate\Support\Str; @@ -89,6 +91,11 @@ class ImportPonify extends Command File::makeDirectory($tmpPath); } + $UNKNOWN_GENRE = Genre::firstOrCreate([ + 'name' => 'Unknown', + 'slug' => 'unknown' + ]); + //========================================================================================================== // Get the list of files and artists //========================================================================================================== @@ -151,9 +158,63 @@ class ImportPonify extends Command list($parsedTags, $rawTags) = $this->parseTags($file, $allTags); - $imageFilename = $file->getFilename() . ".tags.txt"; - $imageFilePath = "$tmpPath/" . $imageFilename; - File::put($imageFilePath, print_r($allTags, true)); + //$imageFilename = $file->getFilename() . ".tags.txt"; + //$imageFilePath = "$tmpPath/" . $imageFilename; + //File::put($imageFilePath, print_r($allTags, true)); + + //========================================================================================================== + // Determine the release date. + //========================================================================================================== + $modifiedDate = Carbon::createFromTimeStampUTC(File::lastModified($file->getPathname())); + $taggedYear = $parsedTags['year']; + + $this->info('Modification year: '.$modifiedDate->year); + $this->info('Tagged year: '.$taggedYear); + + if ($taggedYear !== null && $modifiedDate->year === $taggedYear) { + $releasedAt = $modifiedDate; + + } else if ($taggedYear !== null && $modifiedDate->year !== $taggedYear) { + $this->error('Release years don\'t match! Using the tagged year...'); + $releasedAt = Carbon::create($taggedYear); + + } else { + // $taggedYear is null + $this->error('This track isn\'t tagged with its release year! Using the track\'s last modified date...'); + $releasedAt = $modifiedDate; + } + + // This is later used by the classification/publishing script to determine the publication date. + $parsedTags['released_at'] = $releasedAt->toDateTimeString(); + + //========================================================================================================== + // Does this track have vocals? + //========================================================================================================== + $isVocal = $parsedTags['lyrics'] !== null; + + //========================================================================================================== + // Determine the genre + //========================================================================================================== + $genreName = $parsedTags['genre']; + $this->info('Genre: '.$genreName); + + if ($genreName) { + $genre = Genre::where('name', '=', $genreName)->first(); + if ($genre) { + $genreId = $genre->id; + + } else { + $genre = new Genre(); + $genre->name = $genreName; + $genre->slug = Str::slug($genreName); + $genre->save(); + $genreId = $genre->id; + $this->comment('Created a new genre!'); + } + + } else { + $genreId = $UNKNOWN_GENRE->id; // "Unknown" genre ID + } //========================================================================================================== // Check to see if we have this track already, if so, compare hashes of the two files @@ -352,6 +413,30 @@ class ImportPonify extends Command $this->comment('No cover art found!'); } + //========================================================================================================== + // Is this part of an album? + //========================================================================================================== + $albumId = null; + $albumName = $parsedTags['album']; + + if ($albumName !== null) { + $album = Album::where('user_id', '=', $artist->id) + ->where('title', '=', $albumName) + ->first(); + + if (!$album) { + $album = new Album; + + $album->title = $albumName; + $album->user_id = $artist->id; + $album->cover_id = $coverId; + + $album->save(); + } + + $albumId = $album->id; + } + //========================================================================================================== // Send the track into the upload system like a user just uploaded a track //========================================================================================================== @@ -361,7 +446,8 @@ class ImportPonify extends Command $mime = $allTags['mime_type']; - $trackFile = new UploadedFile($file->getPathname(), $file->getFilename(), $mime, null, null, true); + File::copy($file->getPathname(), "$tmpPath/" . $file->getFilename()); + $trackFile = new UploadedFile("$tmpPath/" . $file->getFilename(), $file->getFilename(), $mime, null, null, true); $upload = new UploadTrackCommand(true); $upload->_file = $trackFile; @@ -372,7 +458,15 @@ class ImportPonify extends Command } else { $track = Track::find($result->getResponse()['id']); $track->cover_id = $coverId; - $track->license_id = 2; + $track->album_id = $albumId; + $track->genre_id = $genreId; + $track->track_number = $parsedTags['track_number']; + $track->released_at = $releasedAt; + $track->description = $parsedTags['comments']; + $track->is_downloadable = true; + $track->lyrics = $parsedTags['lyrics']; + $track->is_vocal = $isVocal; + $track->license_id = 2; $track->save(); // If we made it to here, the track is intact! Log the import. @@ -448,23 +542,68 @@ class ImportPonify extends Command return [$parsedTags, $rawTags]; } + protected function parseId3v2Tags($tags) { + $parsedTags = []; + + if (array_key_exists('TIT2', $tags)) { + $parsedTags['title'] = $tags['TIT2'][0]['data']; + } + + if (array_key_exists('TPE1', $tags)) { + $parsedTags['artist'] = $tags['TPE1'][0]['data']; + } + + if (array_key_exists('TPE2', $tags)) { + $parsedTags['band'] = $tags['TPE2'][0]['data']; + } + + if (array_key_exists('TRCK', $tags)) { + $parsedTags['track_number'] = $tags['TRCK'][0]['data']; + } + + if (array_key_exists('TALB', $tags)) { + $parsedTags['album'] = $tags['TALB'][0]['data']; + } + + if (array_key_exists('TYER', $tags)) { + $parsedTags['year'] = $tags['TYER'][0]['data']; + } + + if (array_key_exists('COMM', $tags)) { + $parsedTags['comments'] = $tags['COMM'][0]['data']; + } + + if (array_key_exists('TDAT', $tags)) { + $parsedTags['release_date'] = $tags['TDAT'][0]['data']; + } + + if (array_key_exists('USLT', $tags)) { + $parsedTags['unsynchronised_lyric'] = $tags['USLT'][0]['data']; + } + } + /** * @param array $rawTags * @return array */ protected function getId3Tags($rawTags) { - if (array_key_exists('tags', $rawTags) && array_key_exists('id3v2', $rawTags['tags'])) { - $tags = $rawTags['tags']['id3v2']; - } elseif (array_key_exists('id3v2', $rawTags['tags'])) { - $tags = $rawTags['tags']['id3v2']; - } elseif (array_key_exists('tags', $rawTags) && array_key_exists('id3v1', $rawTags['tags'])) { - $tags = $rawTags['tags']['id3v1']; + $tags = []; + + if (array_key_exists('id3v2', $rawTags)) { + $tags = $this->parseId3v2Tags($rawTags['id3v2']); + } elseif (array_key_exists('tags', $rawTags)) { + if (array_key_exists('id3v2', $rawTags['tags'])) { + $tags = $rawTags['tags']['id3v2']; + } elseif (array_key_exists('id3v1', $rawTags['tags'])) { + $tags = $rawTags['tags']['id3v1']; + } else { + $tags = []; + } } else { $tags = []; } - $comment = null; if (isset($tags['comment'])) { From 9616538d9cbcd2a25177a1265b684228b95f91c3 Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Mon, 15 May 2017 18:17:09 +0100 Subject: [PATCH 09/15] Switched to a file whitelist --- app/Console/Commands/ImportPonify.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/ImportPonify.php b/app/Console/Commands/ImportPonify.php index 47070e67..87442104 100644 --- a/app/Console/Commands/ImportPonify.php +++ b/app/Console/Commands/ImportPonify.php @@ -41,7 +41,7 @@ class ImportPonify extends Command * * @var array */ - protected $ignoredExtensions = ['db', 'jpg', 'png']; + protected $allowedExtensions = ['mp3', 'aif', 'aiff', 'wav', 'flac', 'm4a', 'ogg']; /** * Used to stop the import process when a SIGINT is received. * @@ -128,7 +128,7 @@ class ImportPonify extends Command $this->comment('[' . $this->currentFile . '/' . $totalFiles . '] Importing track [' . $file->getFilename() . ']...'); - if (in_array($file->getExtension(), $this->ignoredExtensions)) { + if (!in_array($file->getExtension(), $this->allowedExtensions)) { $this->comment('This is not an audio file! Skipping...' . PHP_EOL); continue; } From d43dd9ba40401ad8f75f5d1f6d6d1cf71901aeca Mon Sep 17 00:00:00 2001 From: Josef Citrine Date: Mon, 15 May 2017 19:37:10 +0100 Subject: [PATCH 10/15] Updated getID3 --- app/Library/getid3/changelog.txt | 32 + app/Library/getid3/composer.json | 4 +- .../getid3/demos/demo.audioinfo.class.php | 369 +- app/Library/getid3/demos/demo.basic.php | 12 +- app/Library/getid3/demos/demo.browse.php | 964 ++- app/Library/getid3/demos/demo.joinmp3.php | 172 +- app/Library/getid3/demos/demo.mimeonly.php | 79 +- app/Library/getid3/demos/demo.mp3header.php | 4935 ++++++------ app/Library/getid3/demos/demo.mysql.php | 3672 +++++---- app/Library/getid3/demos/demo.simple.php | 30 +- .../getid3/demos/demo.simple.write.php | 37 +- app/Library/getid3/demos/demo.write.php | 406 +- app/Library/getid3/demos/demo.zip.php | 165 +- .../getid3/demos/getid3.demo.dirscan.php | 342 +- app/Library/getid3/demos/index.php | 10 +- .../getid3/getid3/extension.cache.dbm.php | 195 +- .../getid3/getid3/extension.cache.mysql.php | 181 +- .../getid3/getid3/extension.cache.mysqli.php | 183 + .../getid3/getid3/extension.cache.sqlite3.php | 337 +- app/Library/getid3/getid3/getid3.lib.php | 2858 ++++--- app/Library/getid3/getid3/getid3.php | 3418 ++++---- .../getid3/getid3/module.archive.gzip.php | 469 +- .../getid3/getid3/module.archive.rar.php | 53 +- .../getid3/getid3/module.archive.szip.php | 123 +- .../getid3/getid3/module.archive.tar.php | 297 +- .../getid3/getid3/module.archive.zip.php | 990 ++- .../getid3/getid3/module.audio-video.asf.php | 3862 ++++----- .../getid3/getid3/module.audio-video.bink.php | 79 +- .../getid3/getid3/module.audio-video.flv.php | 1203 ++- .../getid3/module.audio-video.matroska.php | 3438 ++++---- .../getid3/getid3/module.audio-video.mpeg.php | 841 +- .../getid3/getid3/module.audio-video.nsv.php | 345 +- .../getid3/module.audio-video.quicktime.php | 4736 ++++++----- .../getid3/getid3/module.audio-video.real.php | 870 +- .../getid3/getid3/module.audio-video.riff.php | 4962 ++++++------ .../getid3/getid3/module.audio-video.swf.php | 188 +- .../getid3/getid3/module.audio-video.ts.php | 107 +- app/Library/getid3/getid3/module.audio.aa.php | 60 +- .../getid3/getid3/module.audio.aac.php | 852 +- .../getid3/getid3/module.audio.ac3.php | 1047 ++- .../getid3/getid3/module.audio.amr.php | 132 +- app/Library/getid3/getid3/module.audio.au.php | 241 +- .../getid3/getid3/module.audio.avr.php | 184 +- .../getid3/getid3/module.audio.bonk.php | 361 +- .../getid3/getid3/module.audio.dsf.php | 133 + .../getid3/getid3/module.audio.dss.php | 132 +- .../getid3/getid3/module.audio.dts.php | 487 +- .../getid3/getid3/module.audio.flac.php | 735 +- app/Library/getid3/getid3/module.audio.la.php | 344 +- .../getid3/getid3/module.audio.lpac.php | 184 +- .../getid3/getid3/module.audio.midi.php | 901 ++- .../getid3/getid3/module.audio.mod.php | 134 +- .../getid3/getid3/module.audio.monkey.php | 334 +- .../getid3/getid3/module.audio.mp3.php | 3919 ++++----- .../getid3/getid3/module.audio.mpc.php | 979 ++- .../getid3/getid3/module.audio.ogg.php | 1445 ++-- .../getid3/getid3/module.audio.optimfrog.php | 806 +- .../getid3/getid3/module.audio.rkau.php | 116 +- .../getid3/getid3/module.audio.shorten.php | 279 +- .../getid3/getid3/module.audio.tta.php | 142 +- .../getid3/getid3/module.audio.voc.php | 311 +- .../getid3/getid3/module.audio.vqf.php | 243 +- .../getid3/getid3/module.audio.wavpack.php | 644 +- .../getid3/getid3/module.graphic.bmp.php | 1202 +-- .../getid3/getid3/module.graphic.efax.php | 48 +- .../getid3/getid3/module.graphic.gif.php | 133 +- .../getid3/getid3/module.graphic.jpg.php | 589 +- .../getid3/getid3/module.graphic.pcd.php | 190 +- .../getid3/getid3/module.graphic.png.php | 1022 ++- .../getid3/getid3/module.graphic.svg.php | 147 +- .../getid3/getid3/module.graphic.tiff.php | 355 +- app/Library/getid3/getid3/module.misc.cue.php | 484 +- app/Library/getid3/getid3/module.misc.exe.php | 63 +- app/Library/getid3/getid3/module.misc.iso.php | 631 +- .../getid3/getid3/module.misc.msoffice.php | 29 +- .../getid3/getid3/module.misc.par2.php | 15 +- app/Library/getid3/getid3/module.misc.pdf.php | 15 +- .../getid3/getid3/module.tag.apetag.php | 710 +- .../getid3/getid3/module.tag.id3v1.php | 657 +- .../getid3/getid3/module.tag.id3v2.php | 7130 +++++++++-------- .../getid3/getid3/module.tag.lyrics3.php | 475 +- app/Library/getid3/getid3/module.tag.xmp.php | 768 +- app/Library/getid3/getid3/write.apetag.php | 339 +- app/Library/getid3/getid3/write.id3v1.php | 220 +- app/Library/getid3/getid3/write.id3v2.php | 4124 +++++----- app/Library/getid3/getid3/write.lyrics3.php | 90 +- app/Library/getid3/getid3/write.metaflac.php | 229 +- app/Library/getid3/getid3/write.php | 1052 +-- app/Library/getid3/getid3/write.real.php | 448 +- .../getid3/getid3/write.vorbiscomment.php | 164 +- app/Library/getid3/readme.txt | 8 +- 91 files changed, 39356 insertions(+), 38090 deletions(-) create mode 100644 app/Library/getid3/getid3/extension.cache.mysqli.php create mode 100644 app/Library/getid3/getid3/module.audio.dsf.php diff --git a/app/Library/getid3/changelog.txt b/app/Library/getid3/changelog.txt index 11c1cf34..d8c50fcf 100644 --- a/app/Library/getid3/changelog.txt +++ b/app/Library/getid3/changelog.txt @@ -18,6 +18,38 @@ Version History =============== +1.9.14: [2017-03-27] James Heinrich + » Add experimental support for E-AC3 + * bugfix (G:105): RIFF.WAVE.iXML multiple TIMESTAMP_SAMPLE_RATE + * bugfix (G:95): improperly initialized error/warning keys + * bugfix (G:94): ID3v2 write support for TXXX + * bugfix (G:93): all errors or warnings should pass through class method + +1.9.13: [2016-12-14] James Heinrich + * bugfix (G:89): ID3v2.4 custom genres with slashes + * bugfix (G:88): large QuickTime files exceed PHP memory limit + * bugfix (G:87): ID3v2 write GRID data not working properly + * bugfix (G:86): Increase autoloading definitions + * bugfix (G:84): ID3v2 available writable frames list + * bugfix (G:82): ID3v2 datetime logic + * bugfix (G:80): attempt to autodetect ID3v1 encoding + * bugfix (G:77): add partial support of DSSv6 + * bugfix (G:76): add mysqli version of caching extension + * bugfix (G:75): mysql cache max key length + * bugfix (G:71): custom error handler to catch exif_read_data() errors + * bugfix (G:71): add support for mb_convert_encoding + * bugfix (G:70): ID3v2 POPM / UFID + * bugfix (G:68): workaround broken iTunes ID3v2 + * bugfix (G:48): Quicktime set MIME to video/mp4 where applicable + * bugfix (#1930) fread on pipes + * bugfix (#1926) relax ID3v2.IsValidURL check + +1.9.12: [2016-03-02] James Heinrich + » Add support for Direct Stream Digital (DSD) / + DSD Storage Facility (DSF) file format + » Add detection (not parsing) of WebP image format + * bugfix (#1910): Quicktime embedded images + 1.9.11: [2015-12-24] James Heinrich * bugfix (G:64): update constructor syntax for PHP 7 * bugfix (G:62): infinite loop in large PNG files diff --git a/app/Library/getid3/composer.json b/app/Library/getid3/composer.json index 233001fe..858b9051 100644 --- a/app/Library/getid3/composer.json +++ b/app/Library/getid3/composer.json @@ -10,6 +10,6 @@ "php": ">=5.3.0" }, "autoload": { - "classmap": ["getid3/getid3.php"] + "classmap": ["getid3/"] } -} \ No newline at end of file +} diff --git a/app/Library/getid3/demos/demo.audioinfo.class.php b/app/Library/getid3/demos/demo.audioinfo.class.php index 3409ba92..dc12a1ea 100644 --- a/app/Library/getid3/demos/demo.audioinfo.class.php +++ b/app/Library/getid3/demos/demo.audioinfo.class.php @@ -43,275 +43,274 @@ require_once('../getid3/getid3.php'); * Class for extracting information from audio files with getID3(). */ -class AudioInfo -{ +class AudioInfo { - /** - * Private variables - */ - var $result = null; - var $info = null; + /** + * Private variables + */ + var $result = NULL; + var $info = NULL; - /** - * Constructor - */ + /** + * Constructor + */ - function AudioInfo() - { + function AudioInfo() { - // Initialize getID3 engine - $this->getID3 = new getID3; - $this->getID3->option_md5_data = true; - $this->getID3->option_md5_data_source = true; - $this->getID3->encoding = 'UTF-8'; - } + // Initialize getID3 engine + $this->getID3 = new getID3; + $this->getID3->option_md5_data = true; + $this->getID3->option_md5_data_source = true; + $this->getID3->encoding = 'UTF-8'; + } - /** - * Extract information - only public function - * - * @access public - * @param string file Audio file to extract info from. - */ + /** + * Extract information - only public function + * + * @access public + * @param string file Audio file to extract info from. + */ - function Info($file) - { + function Info($file) { - // Analyze file - $this->info = $this->getID3->analyze($file); + // Analyze file + $this->info = $this->getID3->analyze($file); - // Exit here on error - if (isset($this->info['error'])) { - return ['error' => $this->info['error']]; - } + // Exit here on error + if (isset($this->info['error'])) { + return array ('error' => $this->info['error']); + } - // Init wrapper object - $this->result = []; - $this->result['format_name'] = (isset($this->info['fileformat']) ? $this->info['fileformat'] : '').'/'.(isset($this->info['audio']['dataformat']) ? $this->info['audio']['dataformat'] : '').(isset($this->info['video']['dataformat']) ? '/'.$this->info['video']['dataformat'] : ''); - $this->result['encoder_version'] = (isset($this->info['audio']['encoder']) ? $this->info['audio']['encoder'] : ''); - $this->result['encoder_options'] = (isset($this->info['audio']['encoder_options']) ? $this->info['audio']['encoder_options'] : ''); - $this->result['bitrate_mode'] = (isset($this->info['audio']['bitrate_mode']) ? $this->info['audio']['bitrate_mode'] : ''); - $this->result['channels'] = (isset($this->info['audio']['channels']) ? $this->info['audio']['channels'] : ''); - $this->result['sample_rate'] = (isset($this->info['audio']['sample_rate']) ? $this->info['audio']['sample_rate'] : ''); - $this->result['bits_per_sample'] = (isset($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : ''); - $this->result['playing_time'] = (isset($this->info['playtime_seconds']) ? $this->info['playtime_seconds'] : ''); - $this->result['avg_bit_rate'] = (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : ''); - $this->result['tags'] = (isset($this->info['tags']) ? $this->info['tags'] : ''); - $this->result['comments'] = (isset($this->info['comments']) ? $this->info['comments'] : ''); - $this->result['warning'] = (isset($this->info['warning']) ? $this->info['warning'] : ''); - $this->result['md5'] = (isset($this->info['md5_data']) ? $this->info['md5_data'] : ''); + // Init wrapper object + $this->result = array(); + $this->result['format_name'] = (isset($this->info['fileformat']) ? $this->info['fileformat'] : '').'/'.(isset($this->info['audio']['dataformat']) ? $this->info['audio']['dataformat'] : '').(isset($this->info['video']['dataformat']) ? '/'.$this->info['video']['dataformat'] : ''); + $this->result['encoder_version'] = (isset($this->info['audio']['encoder']) ? $this->info['audio']['encoder'] : ''); + $this->result['encoder_options'] = (isset($this->info['audio']['encoder_options']) ? $this->info['audio']['encoder_options'] : ''); + $this->result['bitrate_mode'] = (isset($this->info['audio']['bitrate_mode']) ? $this->info['audio']['bitrate_mode'] : ''); + $this->result['channels'] = (isset($this->info['audio']['channels']) ? $this->info['audio']['channels'] : ''); + $this->result['sample_rate'] = (isset($this->info['audio']['sample_rate']) ? $this->info['audio']['sample_rate'] : ''); + $this->result['bits_per_sample'] = (isset($this->info['audio']['bits_per_sample']) ? $this->info['audio']['bits_per_sample'] : ''); + $this->result['playing_time'] = (isset($this->info['playtime_seconds']) ? $this->info['playtime_seconds'] : ''); + $this->result['avg_bit_rate'] = (isset($this->info['audio']['bitrate']) ? $this->info['audio']['bitrate'] : ''); + $this->result['tags'] = (isset($this->info['tags']) ? $this->info['tags'] : ''); + $this->result['comments'] = (isset($this->info['comments']) ? $this->info['comments'] : ''); + $this->result['warning'] = (isset($this->info['warning']) ? $this->info['warning'] : ''); + $this->result['md5'] = (isset($this->info['md5_data']) ? $this->info['md5_data'] : ''); - // Post getID3() data handling based on file format - $method = (isset($this->info['fileformat']) ? $this->info['fileformat'] : '').'Info'; - if ($method && method_exists($this, $method)) { - $this->$method(); - } + // Post getID3() data handling based on file format + $method = (isset($this->info['fileformat']) ? $this->info['fileformat'] : '').'Info'; + if ($method && method_exists($this, $method)) { + $this->$method(); + } - return $this->result; - } + return $this->result; + } - /** - * post-getID3() data handling for AAC files. - * - * @access private - */ + /** + * post-getID3() data handling for AAC files. + * + * @access private + */ - function aacInfo() - { - $this->result['format_name'] = 'AAC'; - } + function aacInfo() { + $this->result['format_name'] = 'AAC'; + } - /** - * post-getID3() data handling for Wave files. - * - * @access private - */ + /** + * post-getID3() data handling for Wave files. + * + * @access private + */ - function riffInfo() - { - if ($this->info['audio']['dataformat'] == 'wav') { - $this->result['format_name'] = 'Wave'; - } elseif (preg_match('#^mp[1-3]$#', $this->info['audio']['dataformat'])) { - $this->result['format_name'] = strtoupper($this->info['audio']['dataformat']); - } else { - $this->result['format_name'] = 'riff/'.$this->info['audio']['dataformat']; - } - } + function riffInfo() { + if ($this->info['audio']['dataformat'] == 'wav') { + $this->result['format_name'] = 'Wave'; + } elseif (preg_match('#^mp[1-3]$#', $this->info['audio']['dataformat'])) { + $this->result['format_name'] = strtoupper($this->info['audio']['dataformat']); - /** - * * post-getID3() data handling for FLAC files. - * - * @access private - */ + } else { - function flacInfo() - { - $this->result['format_name'] = 'FLAC'; - } + $this->result['format_name'] = 'riff/'.$this->info['audio']['dataformat']; + } + } - /** - * post-getID3() data handling for Monkey's Audio files. - * - * @access private - */ + /** + * * post-getID3() data handling for FLAC files. + * + * @access private + */ - function macInfo() - { - $this->result['format_name'] = 'Monkey\'s Audio'; - } + function flacInfo() { + $this->result['format_name'] = 'FLAC'; + } - /** - * post-getID3() data handling for Lossless Audio files. - * - * @access private - */ + /** + * post-getID3() data handling for Monkey's Audio files. + * + * @access private + */ - function laInfo() - { - $this->result['format_name'] = 'La'; - } + function macInfo() { + $this->result['format_name'] = 'Monkey\'s Audio'; + } - /** - * post-getID3() data handling for Ogg Vorbis files. - * - * @access private - */ + /** + * post-getID3() data handling for Lossless Audio files. + * + * @access private + */ - function oggInfo() - { - if ($this->info['audio']['dataformat'] == 'vorbis') { - $this->result['format_name'] = 'Ogg Vorbis'; - } else if ($this->info['audio']['dataformat'] == 'flac') { - $this->result['format_name'] = 'Ogg FLAC'; - } else if ($this->info['audio']['dataformat'] == 'speex') { - $this->result['format_name'] = 'Ogg Speex'; - } else { - $this->result['format_name'] = 'Ogg '.$this->info['audio']['dataformat']; - } - } + function laInfo() { + $this->result['format_name'] = 'La'; + } - /** - * post-getID3() data handling for Musepack files. - * - * @access private - */ - function mpcInfo() - { - $this->result['format_name'] = 'Musepack'; - } + /** + * post-getID3() data handling for Ogg Vorbis files. + * + * @access private + */ + function oggInfo() { + if ($this->info['audio']['dataformat'] == 'vorbis') { + $this->result['format_name'] = 'Ogg Vorbis'; + } else if ($this->info['audio']['dataformat'] == 'flac') { - /** - * post-getID3() data handling for MPEG files. - * - * @access private - */ + $this->result['format_name'] = 'Ogg FLAC'; - function mp3Info() - { - $this->result['format_name'] = 'MP3'; - } + } else if ($this->info['audio']['dataformat'] == 'speex') { + $this->result['format_name'] = 'Ogg Speex'; + } else { + $this->result['format_name'] = 'Ogg '.$this->info['audio']['dataformat']; - /** - * post-getID3() data handling for MPEG files. - * - * @access private - */ + } + } - function mp2Info() - { - $this->result['format_name'] = 'MP2'; - } + /** + * post-getID3() data handling for Musepack files. + * + * @access private + */ + function mpcInfo() { + $this->result['format_name'] = 'Musepack'; + } - /** - * post-getID3() data handling for MPEG files. - * - * @access private - */ - function mp1Info() - { - $this->result['format_name'] = 'MP1'; - } + /** + * post-getID3() data handling for MPEG files. + * + * @access private + */ + function mp3Info() { + $this->result['format_name'] = 'MP3'; + } - /** - * post-getID3() data handling for WMA files. - * - * @access private - */ - function asfInfo() - { - $this->result['format_name'] = strtoupper($this->info['audio']['dataformat']); - } + /** + * post-getID3() data handling for MPEG files. + * + * @access private + */ - /** - * post-getID3() data handling for Real files. - * - * @access private - */ + function mp2Info() { + $this->result['format_name'] = 'MP2'; + } - function realInfo() - { - $this->result['format_name'] = 'Real'; - } + /** + * post-getID3() data handling for MPEG files. + * + * @access private + */ - /** - * post-getID3() data handling for VQF files. - * - * @access private - */ + function mp1Info() { + $this->result['format_name'] = 'MP1'; + } + + + + + /** + * post-getID3() data handling for WMA files. + * + * @access private + */ + + function asfInfo() { + $this->result['format_name'] = strtoupper($this->info['audio']['dataformat']); + } + + + + /** + * post-getID3() data handling for Real files. + * + * @access private + */ + + function realInfo() { + $this->result['format_name'] = 'Real'; + } + + + + + + /** + * post-getID3() data handling for VQF files. + * + * @access private + */ + + function vqfInfo() { + $this->result['format_name'] = 'VQF'; + } - function vqfInfo() - { - $this->result['format_name'] = 'VQF'; - } } diff --git a/app/Library/getid3/demos/demo.basic.php b/app/Library/getid3/demos/demo.basic.php index 3ba44ce5..73628ead 100644 --- a/app/Library/getid3/demos/demo.basic.php +++ b/app/Library/getid3/demos/demo.basic.php @@ -14,7 +14,6 @@ die('Due to a security issue, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in '.$_SERVER['PHP_SELF']); - // include getID3() library (can be in a different directory if full path is specified) require_once('../getid3/getid3.php'); @@ -46,7 +45,10 @@ getid3_lib::CopyTagsToComments($ThisFileInfo); //echo $ThisFileInfo['audio']['bitrate']; // audio bitrate //echo $ThisFileInfo['playtime_string']; // playtime in minutes:seconds, formatted string -/* - if you want to see ALL the output, uncomment this line: -*/ -//echo '
'.htmlentities(print_r($ThisFileInfo, true)).'
'; +/* if you want to see all the tag data (from all tag formats), uncomment this line: */ +//echo '
'.htmlentities(print_r($ThisFileInfo['comments'], true), ENT_SUBSTITUTE).'
'; + +/* if you want to see ALL the output, uncomment this line: */ +//echo '
'.htmlentities(print_r($ThisFileInfo, true), ENT_SUBSTITUTE).'
'; + + diff --git a/app/Library/getid3/demos/demo.browse.php b/app/Library/getid3/demos/demo.browse.php index 395e4fe0..a5034038 100644 --- a/app/Library/getid3/demos/demo.browse.php +++ b/app/Library/getid3/demos/demo.browse.php @@ -14,20 +14,17 @@ ///////////////////////////////////////////////////////////////// die('For security reasons, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in demos/'.basename(__FILE__)); -define('GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK', false); +define('GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK', false); define('GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK', false); -define('GETID3_DEMO_BROWSE_ALLOW_MD5_LINK', false); +define('GETID3_DEMO_BROWSE_ALLOW_MD5_LINK', false); ///////////////////////////////////////////////////////////////// // die if magic_quotes_runtime or magic_quotes_gpc are set if (function_exists('get_magic_quotes_runtime') && get_magic_quotes_runtime()) { - die('magic_quotes_runtime is enabled, getID3 will not run.'); + die('magic_quotes_runtime is enabled, getID3 will not run.'); } if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) { - die('magic_quotes_gpc is enabled, getID3 will not run.'); -} -if (!defined('ENT_SUBSTITUTE')) { // defined in PHP v5.4.0 - define('ENT_SUBSTITUTE', ENT_QUOTES); + die('magic_quotes_gpc is enabled, getID3 will not run.'); } ///////////////////////////////////////////////////////////////// @@ -42,7 +39,7 @@ require_once('../getid3/getid3.php'); // Initialize getID3 engine $getID3 = new getID3; -$getID3->setOption(['encoding' => $PageEncoding]); +$getID3->setOption(array('encoding' => $PageEncoding)); $getID3checkColor_Head = 'CCCCDD'; $getID3checkColor_DirectoryLight = 'FFCCCC'; @@ -65,331 +62,337 @@ echo ''.$deletefilemessage.'
'; - } else { - echo ''; - } + if (file_exists($_REQUEST['deletefile'])) { + if (unlink($_REQUEST['deletefile'])) { + $deletefilemessage = 'Successfully deleted '.addslashes($_REQUEST['deletefile']); + } else { + $deletefilemessage = 'FAILED to delete '.addslashes($_REQUEST['deletefile']).' - error deleting file'; + } + } else { + $deletefilemessage = 'FAILED to delete '.addslashes($_REQUEST['deletefile']).' - file does not exist'; + } + if (isset($_REQUEST['noalert'])) { + echo ''.$deletefilemessage.'
'; + } else { + echo ''; + } } if (isset($_REQUEST['filename'])) { - if (!file_exists($_REQUEST['filename']) || !is_file($_REQUEST['filename'])) { - die(getid3_lib::iconv_fallback('ISO-8859-1', $PageEncoding, $_REQUEST['filename'].' does not exist')); - } - $starttime = microtime(true); - //$getID3->setOption(array( - // 'option_md5_data' => $AutoGetHashes, - // 'option_sha1_data' => $AutoGetHashes, - //)); - $ThisFileInfo = $getID3->analyze($_REQUEST['filename']); - $AutoGetHashes = (bool) (isset($ThisFileInfo['filesize']) && ($ThisFileInfo['filesize'] > 0) && ($ThisFileInfo['filesize'] < (50 * 1048576))); // auto-get md5_data, md5_file, sha1_data, sha1_file if filesize < 50MB, and NOT zero (which may indicate a file>2GB) - $AutoGetHashes = ($AutoGetHashes && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK); - if ($AutoGetHashes) { - $ThisFileInfo['md5_file'] = md5_file($_REQUEST['filename']); - $ThisFileInfo['sha1_file'] = sha1_file($_REQUEST['filename']); - } + if (!file_exists($_REQUEST['filename']) || !is_file($_REQUEST['filename'])) { + die(getid3_lib::iconv_fallback('ISO-8859-1', $PageEncoding, $_REQUEST['filename'].' does not exist')); + } + $starttime = microtime(true); + + //$getID3->setOption(array( + // 'option_md5_data' => $AutoGetHashes, + // 'option_sha1_data' => $AutoGetHashes, + //)); + $ThisFileInfo = $getID3->analyze($_REQUEST['filename']); + $AutoGetHashes = (bool) (isset($ThisFileInfo['filesize']) && ($ThisFileInfo['filesize'] > 0) && ($ThisFileInfo['filesize'] < (50 * 1048576))); // auto-get md5_data, md5_file, sha1_data, sha1_file if filesize < 50MB, and NOT zero (which may indicate a file>2GB) + $AutoGetHashes = ($AutoGetHashes && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK); + if ($AutoGetHashes) { + $ThisFileInfo['md5_file'] = md5_file($_REQUEST['filename']); + $ThisFileInfo['sha1_file'] = sha1_file($_REQUEST['filename']); + } - getid3_lib::CopyTagsToComments($ThisFileInfo); + getid3_lib::CopyTagsToComments($ThisFileInfo); - $listdirectory = dirname($_REQUEST['filename']); - $listdirectory = realpath($listdirectory); // get rid of /../../ references + $listdirectory = dirname($_REQUEST['filename']); + $listdirectory = realpath($listdirectory); // get rid of /../../ references - if (GETID3_OS_ISWINDOWS) { - // this mostly just gives a consistant look to Windows and *nix filesystems - // (windows uses \ as directory seperator, *nix uses /) - $listdirectory = str_replace(DIRECTORY_SEPARATOR, '/', $listdirectory.'/'); - } + if (GETID3_OS_ISWINDOWS) { + // this mostly just gives a consistant look to Windows and *nix filesystems + // (windows uses \ as directory seperator, *nix uses /) + $listdirectory = str_replace(DIRECTORY_SEPARATOR, '/', $listdirectory.'/'); + } - if (strstr($_REQUEST['filename'], 'http://') || strstr($_REQUEST['filename'], 'ftp://')) { - echo 'Cannot browse remote filesystems
'; - } else { - echo 'Browse: '.getid3_lib::iconv_fallback('ISO-8859-1', $PageEncoding, $listdirectory).'
'; - } + if (strstr($_REQUEST['filename'], 'http://') || strstr($_REQUEST['filename'], 'ftp://')) { + echo 'Cannot browse remote filesystems
'; + } else { + echo 'Browse: '.getid3_lib::iconv_fallback('ISO-8859-1', $PageEncoding, $listdirectory).'
'; + } + + getid3_lib::ksort_recursive($ThisFileInfo); + echo table_var_dump($ThisFileInfo, false, $PageEncoding); + $endtime = microtime(true); + echo 'File parsed in '.number_format($endtime - $starttime, 3).' seconds.
'; - getid3_lib::ksort_recursive($ThisFileInfo); - echo table_var_dump($ThisFileInfo, false, $PageEncoding); - $endtime = microtime(true); - echo 'File parsed in '.number_format($endtime - $starttime, 3).' seconds.
'; } else { - $listdirectory = (isset($_REQUEST['listdirectory']) ? $_REQUEST['listdirectory'] : '.'); - $listdirectory = realpath($listdirectory); // get rid of /../../ references - $currentfulldir = $listdirectory.'/'; - if (GETID3_OS_ISWINDOWS) { - // this mostly just gives a consistant look to Windows and *nix filesystems - // (windows uses \ as directory seperator, *nix uses /) - $currentfulldir = str_replace(DIRECTORY_SEPARATOR, '/', $listdirectory.'/'); - } + $listdirectory = (isset($_REQUEST['listdirectory']) ? $_REQUEST['listdirectory'] : '.'); + $listdirectory = realpath($listdirectory); // get rid of /../../ references + $currentfulldir = $listdirectory.'/'; - ob_start(); - if ($handle = opendir($listdirectory)) { - ob_end_clean(); - echo str_repeat(' ', 300); // IE buffers the first 300 or so chars, making this progressive display useless - fill the buffer with spaces - echo 'Processing'; + if (GETID3_OS_ISWINDOWS) { + // this mostly just gives a consistant look to Windows and *nix filesystems + // (windows uses \ as directory seperator, *nix uses /) + $currentfulldir = str_replace(DIRECTORY_SEPARATOR, '/', $listdirectory.'/'); + } - $starttime = microtime(true); + ob_start(); + if ($handle = opendir($listdirectory)) { - $TotalScannedUnknownFiles = 0; - $TotalScannedKnownFiles = 0; - $TotalScannedPlaytimeFiles = 0; - $TotalScannedBitrateFiles = 0; - $TotalScannedFilesize = 0; - $TotalScannedPlaytime = 0; - $TotalScannedBitrate = 0; - $FilesWithWarnings = 0; - $FilesWithErrors = 0; + ob_end_clean(); + echo str_repeat(' ', 300); // IE buffers the first 300 or so chars, making this progressive display useless - fill the buffer with spaces + echo 'Processing'; - while ($file = readdir($handle)) { - $currentfilename = $listdirectory.'/'.$file; - set_time_limit(30); // allocate another 30 seconds to process this file - should go much quicker than this unless intense processing (like bitrate histogram analysis) is enabled - echo ' .'; // progress indicator dot - flush(); // make sure the dot is shown, otherwise it's useless + $starttime = microtime(true); - switch ($file) { - case '..': - $ParentDir = realpath($file.'/..').'/'; - if (GETID3_OS_ISWINDOWS) { - $ParentDir = str_replace(DIRECTORY_SEPARATOR, '/', $ParentDir); - } - $DirectoryContents[$currentfulldir]['dir'][$file]['filename'] = $ParentDir; - continue 2; - break; + $TotalScannedUnknownFiles = 0; + $TotalScannedKnownFiles = 0; + $TotalScannedPlaytimeFiles = 0; + $TotalScannedBitrateFiles = 0; + $TotalScannedFilesize = 0; + $TotalScannedPlaytime = 0; + $TotalScannedBitrate = 0; + $FilesWithWarnings = 0; + $FilesWithErrors = 0; - case '.': - // ignore - continue 2; - break; - } - // symbolic-link-resolution enhancements by davidbullock״ech-center*com - $TargetObject = realpath($currentfilename); // Find actual file path, resolve if it's a symbolic link - $TargetObjectType = filetype($TargetObject); // Check file type without examining extension + while ($file = readdir($handle)) { + $currentfilename = $listdirectory.'/'.$file; + set_time_limit(30); // allocate another 30 seconds to process this file - should go much quicker than this unless intense processing (like bitrate histogram analysis) is enabled + echo ' .'; // progress indicator dot + flush(); // make sure the dot is shown, otherwise it's useless + switch ($file) { + case '..': + $ParentDir = realpath($file.'/..').'/'; + if (GETID3_OS_ISWINDOWS) { + $ParentDir = str_replace(DIRECTORY_SEPARATOR, '/', $ParentDir); + } + $DirectoryContents[$currentfulldir]['dir'][$file]['filename'] = $ParentDir; + continue 2; + break; - if ($TargetObjectType == 'dir') { - $DirectoryContents[$currentfulldir]['dir'][$file]['filename'] = $file; - } elseif ($TargetObjectType == 'file') { - $getID3->setOption(['option_md5_data' => (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK)]); - $fileinformation = $getID3->analyze($currentfilename); + case '.': + // ignore + continue 2; + break; + } + // symbolic-link-resolution enhancements by davidbullock״ech-center*com + $TargetObject = realpath($currentfilename); // Find actual file path, resolve if it's a symbolic link + $TargetObjectType = filetype($TargetObject); // Check file type without examining extension - getid3_lib::CopyTagsToComments($fileinformation); + if ($TargetObjectType == 'dir') { - $TotalScannedFilesize += (isset($fileinformation['filesize']) ? $fileinformation['filesize'] : 0); + $DirectoryContents[$currentfulldir]['dir'][$file]['filename'] = $file; - if (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK) { - $fileinformation['md5_file'] = md5_file($currentfilename); - } + } elseif ($TargetObjectType == 'file') { - if (!empty($fileinformation['fileformat'])) { - $DirectoryContents[$currentfulldir]['known'][$file] = $fileinformation; - $TotalScannedPlaytime += (isset($fileinformation['playtime_seconds']) ? $fileinformation['playtime_seconds'] : 0); - $TotalScannedBitrate += (isset($fileinformation['bitrate']) ? $fileinformation['bitrate'] : 0); - $TotalScannedKnownFiles++; - } else { - $DirectoryContents[$currentfulldir]['other'][$file] = $fileinformation; - $DirectoryContents[$currentfulldir]['other'][$file]['playtime_string'] = '-'; - $TotalScannedUnknownFiles++; - } - if (isset($fileinformation['playtime_seconds']) && ($fileinformation['playtime_seconds'] > 0)) { - $TotalScannedPlaytimeFiles++; - } - if (isset($fileinformation['bitrate']) && ($fileinformation['bitrate'] > 0)) { - $TotalScannedBitrateFiles++; - } - } - } - $endtime = microtime(true); - closedir($handle); - echo 'done
'; - echo 'Directory scanned in '.number_format($endtime - $starttime, 2).' seconds.
'; - flush(); + $getID3->setOption(array('option_md5_data' => (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK))); + $fileinformation = $getID3->analyze($currentfilename); - $columnsintable = 14; - echo ''; + getid3_lib::CopyTagsToComments($fileinformation); - echo ''; - $rowcounter = 0; - foreach ($DirectoryContents as $dirname => $val) { - if (isset($DirectoryContents[$dirname]['dir']) && is_array($DirectoryContents[$dirname]['dir'])) { - uksort($DirectoryContents[$dirname]['dir'], 'MoreNaturalSort'); - foreach ($DirectoryContents[$dirname]['dir'] as $filename => $fileinfo) { - echo ''; - if ($filename == '..') { - echo ''; - } else { - $escaped_filename = htmlentities($filename, ENT_SUBSTITUTE, $PageEncoding); // do filesystems always return filenames in ISO-8859-1? - $escaped_filename = ($escaped_filename ? $escaped_filename : rawurlencode($filename)); - echo ''; - } - echo ''; - } - } + $TotalScannedFilesize += (isset($fileinformation['filesize']) ? $fileinformation['filesize'] : 0); - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - if (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK) { - echo ''; - echo ''; - echo ''; - } else { - echo ''; - } - echo ''; - echo ''; - echo (GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK ? '' : ''); - echo (GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK ? '' : ''); - echo ''; + if (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK) { + $fileinformation['md5_file'] = md5_file($currentfilename); + } - if (isset($DirectoryContents[$dirname]['known']) && is_array($DirectoryContents[$dirname]['known'])) { - uksort($DirectoryContents[$dirname]['known'], 'MoreNaturalSort'); - foreach ($DirectoryContents[$dirname]['known'] as $filename => $fileinfo) { - echo ''; - $escaped_filename = htmlentities($filename, ENT_SUBSTITUTE, $PageEncoding); - $escaped_filename = ($escaped_filename ? $escaped_filename : rawurlencode($filename)); - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - if (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK) { - echo ''; - echo ''; - echo ''; - } else { - echo ''; - } - echo ''; + if (!empty($fileinformation['fileformat'])) { + $DirectoryContents[$currentfulldir]['known'][$file] = $fileinformation; + $TotalScannedPlaytime += (isset($fileinformation['playtime_seconds']) ? $fileinformation['playtime_seconds'] : 0); + $TotalScannedBitrate += (isset($fileinformation['bitrate']) ? $fileinformation['bitrate'] : 0); + $TotalScannedKnownFiles++; + } else { + $DirectoryContents[$currentfulldir]['other'][$file] = $fileinformation; + $DirectoryContents[$currentfulldir]['other'][$file]['playtime_string'] = '-'; + $TotalScannedUnknownFiles++; + } + if (isset($fileinformation['playtime_seconds']) && ($fileinformation['playtime_seconds'] > 0)) { + $TotalScannedPlaytimeFiles++; + } + if (isset($fileinformation['bitrate']) && ($fileinformation['bitrate'] > 0)) { + $TotalScannedBitrateFiles++; + } + } + } + $endtime = microtime(true); + closedir($handle); + echo 'done
'; + echo 'Directory scanned in '.number_format($endtime - $starttime, 2).' seconds.
'; + flush(); - echo ''; + $columnsintable = 14; + echo '
Files in '.getid3_lib::iconv_fallback('ISO-8859-1', $PageEncoding, $currentfulldir).'
'; - echo '
'; - echo 'Parent directory: '; - echo ' '; - echo '
'.$escaped_filename.'
FilenameFile SizeFormatPlaytimeBitrateArtistTitleMD5 File (File) (disable)MD5 Data (File) (disable)MD5 Data (Source) (disable)MD5 Data'.(GETID3_DEMO_BROWSE_ALLOW_MD5_LINK ?' (enable)' : '').'TagsErrors & WarningsEditDelete
'.$escaped_filename.' '.number_format($fileinfo['filesize']).' '.NiceDisplayFiletypeFormat($fileinfo).' '.(isset($fileinfo['playtime_string']) ? $fileinfo['playtime_string'] : '-').' '.(isset($fileinfo['bitrate']) ? BitrateText($fileinfo['bitrate'] / 1000, 0, ((isset($fileinfo['audio']['bitrate_mode']) && ($fileinfo['audio']['bitrate_mode'] == 'vbr')) ? true : false)) : '-').' '.(isset($fileinfo['comments_html']['artist']) ? implode('
', $fileinfo['comments_html']['artist']) : ((isset($fileinfo['video']['resolution_x']) && isset($fileinfo['video']['resolution_y'])) ? $fileinfo['video']['resolution_x'].'x'.$fileinfo['video']['resolution_y'] : '')).'
 '.(isset($fileinfo['comments_html']['title']) ? implode('
', $fileinfo['comments_html']['title']) : (isset($fileinfo['video']['frame_rate']) ? number_format($fileinfo['video']['frame_rate'], 3).'fps' : '')).'
'.(isset($fileinfo['md5_file']) ? $fileinfo['md5_file'] : ' ').''.(isset($fileinfo['md5_data']) ? $fileinfo['md5_data'] : ' ').''.(isset($fileinfo['md5_data_source']) ? $fileinfo['md5_data_source'] : ' ').'- '.(!empty($fileinfo['tags']) ? implode(', ', array_keys($fileinfo['tags'])) : '').' '; - if (!empty($fileinfo['warning'])) { - $FilesWithWarnings++; - echo 'warning
'; - } - if (!empty($fileinfo['error'])) { - $FilesWithErrors++; - echo 'error
'; - } - echo '
'; - if (GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK) { - echo ''; - } - if (GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK) { - echo ''; - } - echo ''; - } - } + echo ''; + $rowcounter = 0; + foreach ($DirectoryContents as $dirname => $val) { + if (isset($DirectoryContents[$dirname]['dir']) && is_array($DirectoryContents[$dirname]['dir'])) { + uksort($DirectoryContents[$dirname]['dir'], 'MoreNaturalSort'); + foreach ($DirectoryContents[$dirname]['dir'] as $filename => $fileinfo) { + echo ''; + if ($filename == '..') { + echo ''; + } else { + $escaped_filename = htmlentities($filename, ENT_SUBSTITUTE, $PageEncoding); // do filesystems always return filenames in ISO-8859-1? + $escaped_filename = ($escaped_filename ? $escaped_filename : rawurlencode($filename)); + echo ''; + } + echo ''; + } + } - if (isset($DirectoryContents[$dirname]['other']) && is_array($DirectoryContents[$dirname]['other'])) { - uksort($DirectoryContents[$dirname]['other'], 'MoreNaturalSort'); - foreach ($DirectoryContents[$dirname]['other'] as $filename => $fileinfo) { - echo ''; - $escaped_filename = htmlentities($filename, ENT_SUBSTITUTE, $PageEncoding); - $escaped_filename = ($escaped_filename ? $escaped_filename : rawurlencode($filename)); - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; // Artist - echo ''; // Title - echo ''; // MD5_data - echo ''; // Tags + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + if (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK) { + echo ''; + echo ''; + echo ''; + } else { + echo ''; + } + echo ''; + echo ''; + echo (GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK ? '' : ''); + echo (GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK ? '' : ''); + echo ''; - //echo ''; // Warning/Error - echo ''; + if (isset($DirectoryContents[$dirname]['known']) && is_array($DirectoryContents[$dirname]['known'])) { + uksort($DirectoryContents[$dirname]['known'], 'MoreNaturalSort'); + foreach ($DirectoryContents[$dirname]['known'] as $filename => $fileinfo) { + echo ''; + $escaped_filename = htmlentities($filename, ENT_SUBSTITUTE, $PageEncoding); + $escaped_filename = ($escaped_filename ? $escaped_filename : rawurlencode($filename)); + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + if (isset($_REQUEST['ShowMD5']) && GETID3_DEMO_BROWSE_ALLOW_MD5_LINK) { + echo ''; + echo ''; + echo ''; + } else { + echo ''; + } + echo ''; - if (GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK) { - echo ''; // Edit - } - if (GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK) { - echo ''; - } - echo ''; - } - } + echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
 '; - $fileinfo['fileformat'] = (isset($fileinfo['fileformat']) ? $fileinfo['fileformat'] : ''); - switch ($fileinfo['fileformat']) { - case 'mp3': - case 'mp2': - case 'mp1': - case 'flac': - case 'mpc': - case 'real': - echo 'edit tags'; - break; - case 'ogg': - if (isset($fileinfo['audio']['dataformat']) && ($fileinfo['audio']['dataformat'] == 'vorbis')) { - echo 'edit tags'; - } - break; - default: - break; - } - echo ' delete
Files in '.getid3_lib::iconv_fallback('ISO-8859-1', $PageEncoding, $currentfulldir).'
'; + echo '
'; + echo 'Parent directory: '; + echo ' '; + echo '
'.$escaped_filename.'
'.$escaped_filename.' '.(isset($fileinfo['filesize']) ? number_format($fileinfo['filesize']) : '-').' '.NiceDisplayFiletypeFormat($fileinfo).' '.(isset($fileinfo['playtime_string']) ? $fileinfo['playtime_string'] : '-').' '.(isset($fileinfo['bitrate']) ? BitrateText($fileinfo['bitrate'] / 1000) : '-').'    
FilenameFile SizeFormatPlaytimeBitrateArtistTitleMD5 File (File) (disable)MD5 Data (File) (disable)MD5 Data (Source) (disable)MD5 Data'.(GETID3_DEMO_BROWSE_ALLOW_MD5_LINK ?' (enable)' : '').'TagsErrors & WarningsEditDelete
  '; - if (!empty($fileinfo['warning'])) { - $FilesWithWarnings++; - echo 'warning
'; - } - if (!empty($fileinfo['error'])) { - if ($fileinfo['error'][0] != 'unable to determine file format') { - $FilesWithErrors++; - echo 'error
'; - } - } - echo '
'.$escaped_filename.' '.number_format($fileinfo['filesize']).' '.NiceDisplayFiletypeFormat($fileinfo).' '.(isset($fileinfo['playtime_string']) ? $fileinfo['playtime_string'] : '-').' '.(isset($fileinfo['bitrate']) ? BitrateText($fileinfo['bitrate'] / 1000, 0, ((isset($fileinfo['audio']['bitrate_mode']) && ($fileinfo['audio']['bitrate_mode'] == 'vbr')) ? true : false)) : '-').' '.(isset($fileinfo['comments_html']['artist']) ? implode('
', $fileinfo['comments_html']['artist']) : ((isset($fileinfo['video']['resolution_x']) && isset($fileinfo['video']['resolution_y'])) ? $fileinfo['video']['resolution_x'].'x'.$fileinfo['video']['resolution_y'] : '')).'
 '.(isset($fileinfo['comments_html']['title']) ? implode('
', $fileinfo['comments_html']['title']) : (isset($fileinfo['video']['frame_rate']) ? number_format($fileinfo['video']['frame_rate'], 3).'fps' : '')).'
'.(isset($fileinfo['md5_file']) ? $fileinfo['md5_file'] : ' ').''.(isset($fileinfo['md5_data']) ? $fileinfo['md5_data'] : ' ').''.(isset($fileinfo['md5_data_source']) ? $fileinfo['md5_data_source'] : ' ').'- '.(!empty($fileinfo['tags']) ? implode(', ', array_keys($fileinfo['tags'])) : '').'  delete
 '; + if (!empty($fileinfo['warning'])) { + $FilesWithWarnings++; + echo 'warning
'; + } + if (!empty($fileinfo['error'])) { + $FilesWithErrors++; + echo 'error
'; + } + echo '
Average:'.number_format($TotalScannedFilesize / max($TotalScannedKnownFiles, 1)).' '.getid3_lib::PlaytimeString($TotalScannedPlaytime / max($TotalScannedPlaytimeFiles, 1)).''.BitrateText(round(($TotalScannedBitrate / 1000) / max($TotalScannedBitrateFiles, 1))).'
Identified Files:'.number_format($TotalScannedKnownFiles).'   Errors:'.number_format($FilesWithErrors).'
Unknown Files:'.number_format($TotalScannedUnknownFiles).'   Warnings:'.number_format($FilesWithWarnings).'
'; - echo '
Total:'.number_format($TotalScannedFilesize).' '.getid3_lib::PlaytimeString($TotalScannedPlaytime).' 
'; - } else { - $errormessage = ob_get_contents(); - ob_end_clean(); - echo 'ERROR: Could not open directory: '.$currentfulldir.'
'; - } + if (GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK) { + echo ' '; + $fileinfo['fileformat'] = (isset($fileinfo['fileformat']) ? $fileinfo['fileformat'] : ''); + switch ($fileinfo['fileformat']) { + case 'mp3': + case 'mp2': + case 'mp1': + case 'flac': + case 'mpc': + case 'real': + echo 'edit tags'; + break; + case 'ogg': + if (isset($fileinfo['audio']['dataformat']) && ($fileinfo['audio']['dataformat'] == 'vorbis')) { + echo 'edit tags'; + } + break; + default: + break; + } + echo ''; + } + if (GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK) { + echo ' delete'; + } + echo ''; + } + } + + if (isset($DirectoryContents[$dirname]['other']) && is_array($DirectoryContents[$dirname]['other'])) { + uksort($DirectoryContents[$dirname]['other'], 'MoreNaturalSort'); + foreach ($DirectoryContents[$dirname]['other'] as $filename => $fileinfo) { + echo ''; + $escaped_filename = htmlentities($filename, ENT_SUBSTITUTE, $PageEncoding); + $escaped_filename = ($escaped_filename ? $escaped_filename : rawurlencode($filename)); + echo ''.$escaped_filename.''; + echo ' '.(isset($fileinfo['filesize']) ? number_format($fileinfo['filesize']) : '-').''; + echo ' '.NiceDisplayFiletypeFormat($fileinfo).''; + echo ' '.(isset($fileinfo['playtime_string']) ? $fileinfo['playtime_string'] : '-').''; + echo ' '.(isset($fileinfo['bitrate']) ? BitrateText($fileinfo['bitrate'] / 1000) : '-').''; + echo ' '; // Artist + echo ' '; // Title + echo ' '; // MD5_data + echo ' '; // Tags + + //echo ' '; // Warning/Error + echo ' '; + if (!empty($fileinfo['warning'])) { + $FilesWithWarnings++; + echo 'warning
'; + } + if (!empty($fileinfo['error'])) { + if ($fileinfo['error'][0] != 'unable to determine file format') { + $FilesWithErrors++; + echo 'error
'; + } + } + echo ''; + + if (GETID3_DEMO_BROWSE_ALLOW_EDIT_LINK) { + echo ' '; // Edit + } + if (GETID3_DEMO_BROWSE_ALLOW_DELETE_LINK) { + echo ' delete'; + } + echo ''; + } + } + + echo ''; + echo 'Average:'; + echo ''.number_format($TotalScannedFilesize / max($TotalScannedKnownFiles, 1)).''; + echo ' '; + echo ''.getid3_lib::PlaytimeString($TotalScannedPlaytime / max($TotalScannedPlaytimeFiles, 1)).''; + echo ''.BitrateText(round(($TotalScannedBitrate / 1000) / max($TotalScannedBitrateFiles, 1))).''; + echo '
Identified Files:'.number_format($TotalScannedKnownFiles).'   Errors:'.number_format($FilesWithErrors).'
Unknown Files:'.number_format($TotalScannedUnknownFiles).'   Warnings:'.number_format($FilesWithWarnings).'
'; + echo ''; + echo ''; + echo 'Total:'; + echo ''.number_format($TotalScannedFilesize).''; + echo ' '; + echo ''.getid3_lib::PlaytimeString($TotalScannedPlaytime).''; + echo ' '; + echo ''; + } + echo ''; + } else { + $errormessage = ob_get_contents(); + ob_end_clean(); + echo 'ERROR: Could not open directory: '.$currentfulldir.'
'; + } } echo PoweredBygetID3().'
'; echo ''; @@ -398,216 +401,209 @@ echo ''; ///////////////////////////////////////////////////////////////// -function RemoveAccents($string) -{ - // Revised version by markstewardרotmail*com - // Again revised by James Heinrich (19-June-2006) - return strtr( - strtr( - $string, - "\x8A\x8E\x9A\x9E\x9F\xC0\xC1\xC2\xC3\xC4\xC5\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xE0\xE1\xE2\xE3\xE4\xE5\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFF", - 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy' - ), - [ - "\xDE" => 'TH', - "\xFE" => 'th', - "\xD0" => 'DH', - "\xF0" => 'dh', - "\xDF" => 'ss', - "\x8C" => 'OE', - "\x9C" => 'oe', - "\xC6" => 'AE', - "\xE6" => 'ae', - "\xB5" => 'u' - ] - ); +function RemoveAccents($string) { + // Revised version by markstewardרotmail*com + // Again revised by James Heinrich (19-June-2006) + return strtr( + strtr( + $string, + "\x8A\x8E\x9A\x9E\x9F\xC0\xC1\xC2\xC3\xC4\xC5\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xE0\xE1\xE2\xE3\xE4\xE5\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFF", + 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy' + ), + array( + "\xDE" => 'TH', + "\xFE" => 'th', + "\xD0" => 'DH', + "\xF0" => 'dh', + "\xDF" => 'ss', + "\x8C" => 'OE', + "\x9C" => 'oe', + "\xC6" => 'AE', + "\xE6" => 'ae', + "\xB5" => 'u' + ) + ); } -function BitrateColor($bitrate, $BitrateMaxScale = 768) -{ - // $BitrateMaxScale is bitrate of maximum-quality color (bright green) - // below this is gradient, above is solid green +function BitrateColor($bitrate, $BitrateMaxScale=768) { + // $BitrateMaxScale is bitrate of maximum-quality color (bright green) + // below this is gradient, above is solid green - $bitrate *= (256 / $BitrateMaxScale); // scale from 1-[768]kbps to 1-256 - $bitrate = round(min(max($bitrate, 1), 256)); - $bitrate--; // scale from 1-256kbps to 0-255kbps + $bitrate *= (256 / $BitrateMaxScale); // scale from 1-[768]kbps to 1-256 + $bitrate = round(min(max($bitrate, 1), 256)); + $bitrate--; // scale from 1-256kbps to 0-255kbps - $Rcomponent = max(255 - ($bitrate * 2), 0); - $Gcomponent = max(($bitrate * 2) - 255, 0); - if ($bitrate > 127) { - $Bcomponent = max((255 - $bitrate) * 2, 0); - } else { - $Bcomponent = max($bitrate * 2, 0); - } - return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT); + $Rcomponent = max(255 - ($bitrate * 2), 0); + $Gcomponent = max(($bitrate * 2) - 255, 0); + if ($bitrate > 127) { + $Bcomponent = max((255 - $bitrate) * 2, 0); + } else { + $Bcomponent = max($bitrate * 2, 0); + } + return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT); } -function BitrateText($bitrate, $decimals = 0, $vbr = false) -{ - return ''.number_format($bitrate, $decimals).' kbps'; +function BitrateText($bitrate, $decimals=0, $vbr=false) { + return ''.number_format($bitrate, $decimals).' kbps'; } -function string_var_dump($variable) -{ - if (version_compare(PHP_VERSION, '4.3.0', '>=')) { - return print_r($variable, true); - } - ob_start(); - var_dump($variable); - $dumpedvariable = ob_get_contents(); - ob_end_clean(); - return $dumpedvariable; +function string_var_dump($variable) { + if (version_compare(PHP_VERSION, '4.3.0', '>=')) { + return print_r($variable, true); + } + ob_start(); + var_dump($variable); + $dumpedvariable = ob_get_contents(); + ob_end_clean(); + return $dumpedvariable; } -function table_var_dump($variable, $wrap_in_td = false, $encoding = 'ISO-8859-1') -{ - $returnstring = ''; - switch (gettype($variable)) { - case 'array': - $returnstring .= ($wrap_in_td ? '' : ''); - $returnstring .= ''; - foreach ($variable as $key => $value) { - $returnstring .= ''."\n"; - $returnstring .= ''."\n".''."\n"; - } else { - $returnstring .= ''."\n".''."\n"; - } - } else { - $returnstring .= ''."\n".table_var_dump($value, true, $encoding).''."\n"; - } - } - $returnstring .= '
'.str_replace("\x00", ' ', $key).''.gettype($value); - if (is_array($value)) { - $returnstring .= ' ('.count($value).')'; - } elseif (is_string($value)) { - $returnstring .= ' ('.strlen($value).')'; - } - //if (($key == 'data') && isset($variable['image_mime']) && isset($variable['dataoffset'])) { - if (($key == 'data') && isset($variable['image_mime'])) { - $imageinfo = []; - if ($imagechunkcheck = getid3_lib::GetDataImageSize($value, $imageinfo)) { - $returnstring .= '
invalid image data
'."\n"; - $returnstring .= ($wrap_in_td ? ''."\n" : ''); - break; +function table_var_dump($variable, $wrap_in_td=false, $encoding='ISO-8859-1') { + $returnstring = ''; + switch (gettype($variable)) { + case 'array': + $returnstring .= ($wrap_in_td ? '' : ''); + $returnstring .= ''; + foreach ($variable as $key => $value) { + $returnstring .= ''."\n"; + $returnstring .= ''."\n".''."\n"; + } else { + $returnstring .= ''."\n".''."\n"; + } + } else { + $returnstring .= ''."\n".table_var_dump($value, true, $encoding).''."\n"; + } + } + $returnstring .= '
'.str_replace("\x00", ' ', $key).''.gettype($value); + if (is_array($value)) { + $returnstring .= ' ('.count($value).')'; + } elseif (is_string($value)) { + $returnstring .= ' ('.strlen($value).')'; + } + //if (($key == 'data') && isset($variable['image_mime']) && isset($variable['dataoffset'])) { + if (($key == 'data') && isset($variable['image_mime'])) { + $imageinfo = array(); + if ($imagechunkcheck = getid3_lib::GetDataImageSize($value, $imageinfo)) { + $returnstring .= '
invalid image data
'."\n"; + $returnstring .= ($wrap_in_td ? ''."\n" : ''); + break; - case 'boolean': - $returnstring .= ($wrap_in_td ? '' : '').($variable ? 'TRUE' : 'FALSE').($wrap_in_td ? ''."\n" : ''); - break; + case 'boolean': + $returnstring .= ($wrap_in_td ? '' : '').($variable ? 'TRUE' : 'FALSE').($wrap_in_td ? ''."\n" : ''); + break; - case 'integer': - $returnstring .= ($wrap_in_td ? '' : '').$variable.($wrap_in_td ? ''."\n" : ''); - break; + case 'integer': + $returnstring .= ($wrap_in_td ? '' : '').$variable.($wrap_in_td ? ''."\n" : ''); + break; - case 'double': - case 'float': - $returnstring .= ($wrap_in_td ? '' : '').$variable.($wrap_in_td ? ''."\n" : ''); - break; + case 'double': + case 'float': + $returnstring .= ($wrap_in_td ? '' : '').$variable.($wrap_in_td ? ''."\n" : ''); + break; - case 'object': - case 'null': - $returnstring .= ($wrap_in_td ? '' : '').string_var_dump($variable).($wrap_in_td ? ''."\n" : ''); - break; + case 'object': + case 'null': + $returnstring .= ($wrap_in_td ? '' : '').string_var_dump($variable).($wrap_in_td ? ''."\n" : ''); + break; - case 'string': - $returnstring = htmlentities($variable, ENT_QUOTES | ENT_SUBSTITUTE, $encoding); - $returnstring = ($wrap_in_td ? '' : '').nl2br($returnstring).($wrap_in_td ? ''."\n" : ''); - break; + case 'string': + $returnstring = htmlentities($variable, ENT_QUOTES | ENT_SUBSTITUTE, $encoding); + $returnstring = ($wrap_in_td ? '' : '').nl2br($returnstring).($wrap_in_td ? ''."\n" : ''); + break; - default: - $imageinfo = []; - if (($imagechunkcheck = getid3_lib::GetDataImageSize($variable, $imageinfo)) && ($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) { - $returnstring .= ($wrap_in_td ? '' : ''); - $returnstring .= ''; - $returnstring .= ''."\n"; - $returnstring .= ''."\n"; - $returnstring .= ''."\n"; - $returnstring .= '
type'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]).'
width'.number_format($imagechunkcheck[0]).' px
height'.number_format($imagechunkcheck[1]).' px
size'.number_format(strlen($variable)).' bytes
'."\n"; - $returnstring .= ($wrap_in_td ? ''."\n" : ''); - } else { - $returnstring .= ($wrap_in_td ? '' : '').nl2br(htmlspecialchars(str_replace("\x00", ' ', $variable))).($wrap_in_td ? ''."\n" : ''); - } - break; - } - return $returnstring; + default: + $imageinfo = array(); + if (($imagechunkcheck = getid3_lib::GetDataImageSize($variable, $imageinfo)) && ($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) { + $returnstring .= ($wrap_in_td ? '' : ''); + $returnstring .= ''; + $returnstring .= ''."\n"; + $returnstring .= ''."\n"; + $returnstring .= ''."\n"; + $returnstring .= '
type'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]).'
width'.number_format($imagechunkcheck[0]).' px
height'.number_format($imagechunkcheck[1]).' px
size'.number_format(strlen($variable)).' bytes
'."\n"; + $returnstring .= ($wrap_in_td ? ''."\n" : ''); + } else { + $returnstring .= ($wrap_in_td ? '' : '').nl2br(htmlspecialchars(str_replace("\x00", ' ', $variable))).($wrap_in_td ? ''."\n" : ''); + } + break; + } + return $returnstring; } -function NiceDisplayFiletypeFormat(&$fileinfo) -{ +function NiceDisplayFiletypeFormat(&$fileinfo) { - if (empty($fileinfo['fileformat'])) { - return '-'; - } + if (empty($fileinfo['fileformat'])) { + return '-'; + } + + $output = $fileinfo['fileformat']; + if (empty($fileinfo['video']['dataformat']) && empty($fileinfo['audio']['dataformat'])) { + return $output; // 'gif' + } + if (empty($fileinfo['video']['dataformat']) && !empty($fileinfo['audio']['dataformat'])) { + if ($fileinfo['fileformat'] == $fileinfo['audio']['dataformat']) { + return $output; // 'mp3' + } + $output .= '.'.$fileinfo['audio']['dataformat']; // 'ogg.flac' + return $output; + } + if (!empty($fileinfo['video']['dataformat']) && empty($fileinfo['audio']['dataformat'])) { + if ($fileinfo['fileformat'] == $fileinfo['video']['dataformat']) { + return $output; // 'mpeg' + } + $output .= '.'.$fileinfo['video']['dataformat']; // 'riff.avi' + return $output; + } + if ($fileinfo['video']['dataformat'] == $fileinfo['audio']['dataformat']) { + if ($fileinfo['fileformat'] == $fileinfo['video']['dataformat']) { + return $output; // 'real' + } + $output .= '.'.$fileinfo['video']['dataformat']; // any examples? + return $output; + } + $output .= '.'.$fileinfo['video']['dataformat']; + $output .= '.'.$fileinfo['audio']['dataformat']; // asf.wmv.wma + return $output; - $output = $fileinfo['fileformat']; - if (empty($fileinfo['video']['dataformat']) && empty($fileinfo['audio']['dataformat'])) { - return $output; // 'gif' - } - if (empty($fileinfo['video']['dataformat']) && !empty($fileinfo['audio']['dataformat'])) { - if ($fileinfo['fileformat'] == $fileinfo['audio']['dataformat']) { - return $output; // 'mp3' - } - $output .= '.'.$fileinfo['audio']['dataformat']; // 'ogg.flac' - return $output; - } - if (!empty($fileinfo['video']['dataformat']) && empty($fileinfo['audio']['dataformat'])) { - if ($fileinfo['fileformat'] == $fileinfo['video']['dataformat']) { - return $output; // 'mpeg' - } - $output .= '.'.$fileinfo['video']['dataformat']; // 'riff.avi' - return $output; - } - if ($fileinfo['video']['dataformat'] == $fileinfo['audio']['dataformat']) { - if ($fileinfo['fileformat'] == $fileinfo['video']['dataformat']) { - return $output; // 'real' - } - $output .= '.'.$fileinfo['video']['dataformat']; // any examples? - return $output; - } - $output .= '.'.$fileinfo['video']['dataformat']; - $output .= '.'.$fileinfo['audio']['dataformat']; // asf.wmv.wma - return $output; } -function MoreNaturalSort($ar1, $ar2) -{ - if ($ar1 === $ar2) { - return 0; - } - $len1 = strlen($ar1); - $len2 = strlen($ar2); - $shortest = min($len1, $len2); - if (substr($ar1, 0, $shortest) === substr($ar2, 0, $shortest)) { - // the shorter argument is the beginning of the longer one, like "str" and "string" - if ($len1 < $len2) { - return -1; - } elseif ($len1 > $len2) { - return 1; - } - return 0; - } - $ar1 = RemoveAccents(strtolower(trim($ar1))); - $ar2 = RemoveAccents(strtolower(trim($ar2))); - $translatearray = ['\''=>'', '"'=>'', '_'=>' ', '('=>'', ')'=>'', '-'=>' ', ' '=>' ', '.'=>'', ','=>'']; - foreach ($translatearray as $key => $val) { - $ar1 = str_replace($key, $val, $ar1); - $ar2 = str_replace($key, $val, $ar2); - } +function MoreNaturalSort($ar1, $ar2) { + if ($ar1 === $ar2) { + return 0; + } + $len1 = strlen($ar1); + $len2 = strlen($ar2); + $shortest = min($len1, $len2); + if (substr($ar1, 0, $shortest) === substr($ar2, 0, $shortest)) { + // the shorter argument is the beginning of the longer one, like "str" and "string" + if ($len1 < $len2) { + return -1; + } elseif ($len1 > $len2) { + return 1; + } + return 0; + } + $ar1 = RemoveAccents(strtolower(trim($ar1))); + $ar2 = RemoveAccents(strtolower(trim($ar2))); + $translatearray = array('\''=>'', '"'=>'', '_'=>' ', '('=>'', ')'=>'', '-'=>' ', ' '=>' ', '.'=>'', ','=>''); + foreach ($translatearray as $key => $val) { + $ar1 = str_replace($key, $val, $ar1); + $ar2 = str_replace($key, $val, $ar2); + } - if ($ar1 < $ar2) { - return -1; - } elseif ($ar1 > $ar2) { - return 1; - } - return 0; + if ($ar1 < $ar2) { + return -1; + } elseif ($ar1 > $ar2) { + return 1; + } + return 0; } -function PoweredBygetID3($string = '') -{ - global $getID3; - if (!$string) { - $string = '
Powered by getID3() v
http://getid3.sourceforge.net

Running on PHP v'.phpversion().' ('.(ceil(log(PHP_INT_MAX, 2)) + 1).'-bit)
'; - } - return str_replace('', $getID3->version(), $string); +function PoweredBygetID3($string='') { + global $getID3; + if (!$string) { + $string = '
Powered by getID3() v
http://www.getid3.org/

Running on PHP v'.phpversion().' ('.(ceil(log(PHP_INT_MAX, 2)) + 1).'-bit)
'; + } + return str_replace('', $getID3->version(), $string); } diff --git a/app/Library/getid3/demos/demo.joinmp3.php b/app/Library/getid3/demos/demo.joinmp3.php index 117e856e..b819e930 100644 --- a/app/Library/getid3/demos/demo.joinmp3.php +++ b/app/Library/getid3/demos/demo.joinmp3.php @@ -33,91 +33,103 @@ // CombineMultipleMP3sTo('sample.mp3', array(array('input.mp3', 0, 30))); // extract first 30 seconds of audio -function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) -{ +function CombineMultipleMP3sTo($FilenameOut, $FilenamesIn) { - foreach ($FilenamesIn as $nextinputfilename) { - if (is_array($nextinputfilename)) { - $nextinputfilename = $nextinputfilename[0]; - } - if (!is_readable($nextinputfilename)) { - echo 'Cannot read "'.$nextinputfilename.'"
'; - return false; - } - } - if ((file_exists($FilenameOut) && !is_writeable($FilenameOut)) || (!file_exists($FilenameOut) && !is_writeable(dirname($FilenameOut)))) { - echo 'Cannot write "'.$FilenameOut.'"
'; - return false; - } + foreach ($FilenamesIn as $nextinputfilename) { + if (is_array($nextinputfilename)) { + $nextinputfilename = $nextinputfilename[0]; + } + if (!is_readable($nextinputfilename)) { + echo 'Cannot read "'.$nextinputfilename.'"
'; + return false; + } + } + if ((file_exists($FilenameOut) && !is_writeable($FilenameOut)) || (!file_exists($FilenameOut) && !is_writeable(dirname($FilenameOut)))) { + echo 'Cannot write "'.$FilenameOut.'"
'; + return false; + } - require_once(dirname(__FILE__).'/../getid3/getid3.php'); - ob_start(); - if ($fp_output = fopen($FilenameOut, 'wb')) { - ob_end_clean(); - // Initialize getID3 engine - $getID3 = new getID3; - foreach ($FilenamesIn as $nextinputfilename) { - $startoffset = 0; - $length_seconds = 0; - if (is_array($nextinputfilename)) { - @list($nextinputfilename, $startoffset, $length_seconds) = $nextinputfilename; - } - $CurrentFileInfo = $getID3->analyze($nextinputfilename); - if ($CurrentFileInfo['fileformat'] == 'mp3') { - ob_start(); - if ($fp_source = fopen($nextinputfilename, 'rb')) { - ob_end_clean(); - $CurrentOutputPosition = ftell($fp_output); + require_once(dirname(__FILE__).'/../getid3/getid3.php'); + ob_start(); + if ($fp_output = fopen($FilenameOut, 'wb')) { - // copy audio data from first file - $start_offset_bytes = $CurrentFileInfo['avdataoffset']; - if ($startoffset > 0) { // start X seconds from start of audio - $start_offset_bytes = $CurrentFileInfo['avdataoffset'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset); - } elseif ($startoffset < 0) { // start X seconds from end of audio - $start_offset_bytes = $CurrentFileInfo['avdataend'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset); - } - $start_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $start_offset_bytes)); + ob_end_clean(); + // Initialize getID3 engine + $getID3 = new getID3; + foreach ($FilenamesIn as $nextinputfilename) { + $startoffset = 0; + $length_seconds = 0; + if (is_array($nextinputfilename)) { + @list($nextinputfilename, $startoffset, $length_seconds) = $nextinputfilename; + } + $CurrentFileInfo = $getID3->analyze($nextinputfilename); + if ($CurrentFileInfo['fileformat'] == 'mp3') { - $end_offset_bytes = $CurrentFileInfo['avdataend']; - if ($length_seconds > 0) { // seconds from start of audio - $end_offset_bytes = $start_offset_bytes + round($CurrentFileInfo['bitrate'] / 8 * $length_seconds); - } elseif ($length_seconds < 0) { // seconds from start of audio - $end_offset_bytes = $CurrentFileInfo['avdataend'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset); - } - $end_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $end_offset_bytes)); + ob_start(); + if ($fp_source = fopen($nextinputfilename, 'rb')) { - if ($end_offset_bytes <= $start_offset_bytes) { - echo 'failed to copy '.$nextinputfilename.' from '.$startoffset.'-seconds start for '.$length_seconds.'-seconds length (not enough data)'; - fclose($fp_source); - fclose($fp_output); - return false; - } + ob_end_clean(); + $CurrentOutputPosition = ftell($fp_output); - fseek($fp_source, $start_offset_bytes, SEEK_SET); - while (!feof($fp_source) && (ftell($fp_source) < $end_offset_bytes)) { - fwrite($fp_output, fread($fp_source, min(32768, $end_offset_bytes - ftell($fp_source)))); - } - fclose($fp_source); - } else { - $errormessage = ob_get_contents(); - ob_end_clean(); - echo 'failed to open '.$nextinputfilename.' for reading'; - fclose($fp_output); - return false; - } - } else { - echo $nextinputfilename.' is not MP3 format'; - fclose($fp_output); - return false; - } - } - } else { - $errormessage = ob_get_contents(); - ob_end_clean(); - echo 'failed to open '.$FilenameOut.' for writing'; - return false; - } + // copy audio data from first file + $start_offset_bytes = $CurrentFileInfo['avdataoffset']; + if ($startoffset > 0) { // start X seconds from start of audio + $start_offset_bytes = $CurrentFileInfo['avdataoffset'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset); + } elseif ($startoffset < 0) { // start X seconds from end of audio + $start_offset_bytes = $CurrentFileInfo['avdataend'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset); + } + $start_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $start_offset_bytes)); - fclose($fp_output); - return true; + $end_offset_bytes = $CurrentFileInfo['avdataend']; + if ($length_seconds > 0) { // seconds from start of audio + $end_offset_bytes = $start_offset_bytes + round($CurrentFileInfo['bitrate'] / 8 * $length_seconds); + } elseif ($length_seconds < 0) { // seconds from start of audio + $end_offset_bytes = $CurrentFileInfo['avdataend'] + round($CurrentFileInfo['bitrate'] / 8 * $startoffset); + } + $end_offset_bytes = max($CurrentFileInfo['avdataoffset'], min($CurrentFileInfo['avdataend'], $end_offset_bytes)); + + if ($end_offset_bytes <= $start_offset_bytes) { + echo 'failed to copy '.$nextinputfilename.' from '.$startoffset.'-seconds start for '.$length_seconds.'-seconds length (not enough data)'; + fclose($fp_source); + fclose($fp_output); + return false; + } + + fseek($fp_source, $start_offset_bytes, SEEK_SET); + while (!feof($fp_source) && (ftell($fp_source) < $end_offset_bytes)) { + fwrite($fp_output, fread($fp_source, min(32768, $end_offset_bytes - ftell($fp_source)))); + } + fclose($fp_source); + + } else { + + $errormessage = ob_get_contents(); + ob_end_clean(); + echo 'failed to open '.$nextinputfilename.' for reading'; + fclose($fp_output); + return false; + + } + + } else { + + echo $nextinputfilename.' is not MP3 format'; + fclose($fp_output); + return false; + + } + + } + + } else { + + $errormessage = ob_get_contents(); + ob_end_clean(); + echo 'failed to open '.$FilenameOut.' for writing'; + return false; + + } + + fclose($fp_output); + return true; } diff --git a/app/Library/getid3/demos/demo.mimeonly.php b/app/Library/getid3/demos/demo.mimeonly.php index 57da51e9..9a381780 100644 --- a/app/Library/getid3/demos/demo.mimeonly.php +++ b/app/Library/getid3/demos/demo.mimeonly.php @@ -20,50 +20,55 @@ echo 'getID3 demos - MIME type only'; if (!empty($_REQUEST['filename'])) { - echo 'The file "'.htmlentities($_REQUEST['filename']).'" has a MIME type of "'.htmlentities(GetMIMEtype($_REQUEST['filename'])).'"'; + + echo 'The file "'.htmlentities($_REQUEST['filename']).'" has a MIME type of "'.htmlentities(GetMIMEtype($_REQUEST['filename'])).'"'; + } else { - echo 'Usage: '.htmlentities($_SERVER['PHP_SELF']).'?filename=filename.ext'; + + echo 'Usage: '.htmlentities($_SERVER['PHP_SELF']).'?filename=filename.ext'; + } -function GetMIMEtype($filename) -{ - $filename = realpath($filename); - if (!file_exists($filename)) { - echo 'File does not exist: "'.htmlentities($filename).'"
'; - return ''; - } elseif (!is_readable($filename)) { - echo 'File is not readable: "'.htmlentities($filename).'"
'; - return ''; - } +function GetMIMEtype($filename) { + $filename = realpath($filename); + if (!file_exists($filename)) { + echo 'File does not exist: "'.htmlentities($filename).'"
'; + return ''; + } elseif (!is_readable($filename)) { + echo 'File is not readable: "'.htmlentities($filename).'"
'; + return ''; + } - // include getID3() library (can be in a different directory if full path is specified) - require_once('../getid3/getid3.php'); - // Initialize getID3 engine - $getID3 = new getID3; + // include getID3() library (can be in a different directory if full path is specified) + require_once('../getid3/getid3.php'); + // Initialize getID3 engine + $getID3 = new getID3; - $DeterminedMIMEtype = ''; - if ($fp = fopen($filename, 'rb')) { - $getID3->openfile($filename); - if (empty($getID3->info['error'])) { - // ID3v2 is the only tag format that might be prepended in front of files, and it's non-trivial to skip, easier just to parse it and know where to skip to - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); - $getid3_id3v2 = new getid3_id3v2($getID3); - $getid3_id3v2->Analyze(); + $DeterminedMIMEtype = ''; + if ($fp = fopen($filename, 'rb')) { + $getID3->openfile($filename); + if (empty($getID3->info['error'])) { - fseek($fp, $getID3->info['avdataoffset'], SEEK_SET); - $formattest = fread($fp, 16); // 16 bytes is sufficient for any format except ISO CD-image - fclose($fp); + // ID3v2 is the only tag format that might be prepended in front of files, and it's non-trivial to skip, easier just to parse it and know where to skip to + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); + $getid3_id3v2 = new getid3_id3v2($getID3); + $getid3_id3v2->Analyze(); - $DeterminedFormatInfo = $getID3->GetFileFormat($formattest); - $DeterminedMIMEtype = $DeterminedFormatInfo['mime_type']; - } else { - echo 'Failed to getID3->openfile "'.htmlentities($filename).'"
'; - } - } else { - echo 'Failed to fopen "'.htmlentities($filename).'"
'; - } - return $DeterminedMIMEtype; + fseek($fp, $getID3->info['avdataoffset'], SEEK_SET); + $formattest = fread($fp, 16); // 16 bytes is sufficient for any format except ISO CD-image + fclose($fp); + + $DeterminedFormatInfo = $getID3->GetFileFormat($formattest); + $DeterminedMIMEtype = $DeterminedFormatInfo['mime_type']; + + } else { + echo 'Failed to getID3->openfile "'.htmlentities($filename).'"
'; + } + } else { + echo 'Failed to fopen "'.htmlentities($filename).'"
'; + } + return $DeterminedMIMEtype; } -echo ''; +echo ''; \ No newline at end of file diff --git a/app/Library/getid3/demos/demo.mp3header.php b/app/Library/getid3/demos/demo.mp3header.php index 24207154..ad5a3d8a 100644 --- a/app/Library/getid3/demos/demo.mp3header.php +++ b/app/Library/getid3/demos/demo.mp3header.php @@ -1,1405 +1,1349 @@ '; - foreach ($variable as $key => $value) { - $returnstring .= ''.str_replace(chr(0), ' ', $key).''; - $returnstring .= ''.gettype($value); - if (is_array($value)) { - $returnstring .= ' ('.count($value).')'; - } elseif (is_string($value)) { - $returnstring .= ' ('.strlen($value).')'; - } - if (($key == 'data') && isset($variable['image_mime']) && isset($variable['dataoffset'])) { - require_once(GETID3_INCLUDEPATH.'getid3.getimagesize.php'); - $imageinfo = []; - if ($imagechunkcheck = GetDataImageSize($value, $imageinfo)) { - $DumpedImageSRC = (!empty($_REQUEST['filename']) ? $_REQUEST['filename'] : '.getid3').'.'.$variable['dataoffset'].'.'.ImageTypesLookup($imagechunkcheck[2]); - if ($tempimagefile = fopen($DumpedImageSRC, 'wb')) { - fwrite($tempimagefile, $value); - fclose($tempimagefile); - } - $returnstring .= ''; - } else { - $returnstring .= 'invalid image data'; - } - } else { - $returnstring .= ''.table_var_dump($value).''; - } - } - $returnstring .= ''; - break; + function table_var_dump($variable) { + $returnstring = ''; + switch (gettype($variable)) { + case 'array': + $returnstring .= ''; + foreach ($variable as $key => $value) { + $returnstring .= ''; + $returnstring .= ''; + } else { + $returnstring .= ''; + } + } else { + $returnstring .= ''; + } + } + $returnstring .= '
'.str_replace(chr(0), ' ', $key).''.gettype($value); + if (is_array($value)) { + $returnstring .= ' ('.count($value).')'; + } elseif (is_string($value)) { + $returnstring .= ' ('.strlen($value).')'; + } + if (($key == 'data') && isset($variable['image_mime']) && isset($variable['dataoffset'])) { + require_once(GETID3_INCLUDEPATH.'getid3.getimagesize.php'); + $imageinfo = array(); + if ($imagechunkcheck = GetDataImageSize($value, $imageinfo)) { + $DumpedImageSRC = (!empty($_REQUEST['filename']) ? $_REQUEST['filename'] : '.getid3').'.'.$variable['dataoffset'].'.'.ImageTypesLookup($imagechunkcheck[2]); + if ($tempimagefile = fopen($DumpedImageSRC, 'wb')) { + fwrite($tempimagefile, $value); + fclose($tempimagefile); + } + $returnstring .= '
invalid image data
'.table_var_dump($value).'
'; + break; - case 'boolean': - $returnstring .= ($variable ? 'TRUE' : 'FALSE'); - break; + case 'boolean': + $returnstring .= ($variable ? 'TRUE' : 'FALSE'); + break; - case 'integer': - case 'double': - case 'float': - $returnstring .= $variable; - break; + case 'integer': + case 'double': + case 'float': + $returnstring .= $variable; + break; - case 'object': - case 'null': - $returnstring .= string_var_dump($variable); - break; + case 'object': + case 'null': + $returnstring .= string_var_dump($variable); + break; - case 'string': - $variable = str_replace(chr(0), ' ', $variable); - $varlen = strlen($variable); - for ($i = 0; $i < $varlen; $i++) { - if (preg_match('#['.chr(0x0A).chr(0x0D).' -;0-9A-Za-z]#', $variable{$i})) { - $returnstring .= $variable{$i}; - } else { - $returnstring .= '&#'.str_pad(ord($variable{$i}), 3, '0', STR_PAD_LEFT).';'; - } - } - $returnstring = nl2br($returnstring); - break; + case 'string': + $variable = str_replace(chr(0), ' ', $variable); + $varlen = strlen($variable); + for ($i = 0; $i < $varlen; $i++) { + if (preg_match('#['.chr(0x0A).chr(0x0D).' -;0-9A-Za-z]#', $variable{$i})) { + $returnstring .= $variable{$i}; + } else { + $returnstring .= '&#'.str_pad(ord($variable{$i}), 3, '0', STR_PAD_LEFT).';'; + } + } + $returnstring = nl2br($returnstring); + break; - default: - require_once(GETID3_INCLUDEPATH.'getid3.getimagesize.php'); - $imageinfo = []; - if (($imagechunkcheck = GetDataImageSize(substr($variable, 0, 32768), $imageinfo)) && ($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) { - $returnstring .= ''; - $returnstring .= ''; - $returnstring .= ''; - $returnstring .= ''; - $returnstring .= '
type'.ImageTypesLookup($imagechunkcheck[2]).'
width'.number_format($imagechunkcheck[0]).' px
height'.number_format($imagechunkcheck[1]).' px
size'.number_format(strlen($variable)).' bytes
'; - } else { - $returnstring .= nl2br(htmlspecialchars(str_replace(chr(0), ' ', $variable))); - } - break; - } - return $returnstring; - } + default: + require_once(GETID3_INCLUDEPATH.'getid3.getimagesize.php'); + $imageinfo = array(); + if (($imagechunkcheck = GetDataImageSize(substr($variable, 0, 32768), $imageinfo)) && ($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) { + $returnstring .= ''; + $returnstring .= ''; + $returnstring .= ''; + $returnstring .= ''; + $returnstring .= '
type'.ImageTypesLookup($imagechunkcheck[2]).'
width'.number_format($imagechunkcheck[0]).' px
height'.number_format($imagechunkcheck[1]).' px
size'.number_format(strlen($variable)).' bytes
'; + } else { + $returnstring .= nl2br(htmlspecialchars(str_replace(chr(0), ' ', $variable))); + } + break; + } + return $returnstring; + } } if (!function_exists('string_var_dump')) { - function string_var_dump($variable) - { - if (version_compare(PHP_VERSION, '4.3.0', '>=')) { - return print_r($variable, true); - } - ob_start(); - var_dump($variable); - $dumpedvariable = ob_get_contents(); - ob_end_clean(); - return $dumpedvariable; - } + function string_var_dump($variable) { + if (version_compare(PHP_VERSION, '4.3.0', '>=')) { + return print_r($variable, true); + } + ob_start(); + var_dump($variable); + $dumpedvariable = ob_get_contents(); + ob_end_clean(); + return $dumpedvariable; + } } if (!function_exists('fileextension')) { - function fileextension($filename, $numextensions = 1) - { - if (strstr($filename, '.')) { - $reversedfilename = strrev($filename); - $offset = 0; - for ($i = 0; $i < $numextensions; $i++) { - $offset = strpos($reversedfilename, '.', $offset + 1); - if ($offset === false) { - return ''; - } - } - return strrev(substr($reversedfilename, 0, $offset)); - } - return ''; - } + function fileextension($filename, $numextensions=1) { + if (strstr($filename, '.')) { + $reversedfilename = strrev($filename); + $offset = 0; + for ($i = 0; $i < $numextensions; $i++) { + $offset = strpos($reversedfilename, '.', $offset + 1); + if ($offset === false) { + return ''; + } + } + return strrev(substr($reversedfilename, 0, $offset)); + } + return ''; + } } if (!function_exists('RemoveAccents')) { - function RemoveAccents($string) - { - // return strtr($string, 'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ', 'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy'); - // Revised version by marksteward@hotmail.com - return strtr(strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'), ['Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u']); - } + function RemoveAccents($string) { + // return strtr($string, 'ŠŒŽšœžŸ¥µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ', 'SOZsozYYuAAAAAAACEEEEIIIIDNOOOOOOUUUUYsaaaaaaaceeeeiiiionoooooouuuuyy'); + // Revised version by marksteward@hotmail.com + return strtr(strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'), array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u')); + } } if (!function_exists('MoreNaturalSort')) { - function MoreNaturalSort($ar1, $ar2) - { - if ($ar1 === $ar2) { - return 0; - } - $len1 = strlen($ar1); - $len2 = strlen($ar2); - $shortest = min($len1, $len2); - if (substr($ar1, 0, $shortest) === substr($ar2, 0, $shortest)) { - // the shorter argument is the beginning of the longer one, like "str" and "string" - if ($len1 < $len2) { - return -1; - } elseif ($len1 > $len2) { - return 1; - } - return 0; - } - $ar1 = RemoveAccents(strtolower(trim($ar1))); - $ar2 = RemoveAccents(strtolower(trim($ar2))); - $translatearray = ['\''=>'', '"'=>'', '_'=>' ', '('=>'', ')'=>'', '-'=>' ', ' '=>' ', '.'=>'', ','=>'']; - foreach ($translatearray as $key => $val) { - $ar1 = str_replace($key, $val, $ar1); - $ar2 = str_replace($key, $val, $ar2); - } + function MoreNaturalSort($ar1, $ar2) { + if ($ar1 === $ar2) { + return 0; + } + $len1 = strlen($ar1); + $len2 = strlen($ar2); + $shortest = min($len1, $len2); + if (substr($ar1, 0, $shortest) === substr($ar2, 0, $shortest)) { + // the shorter argument is the beginning of the longer one, like "str" and "string" + if ($len1 < $len2) { + return -1; + } elseif ($len1 > $len2) { + return 1; + } + return 0; + } + $ar1 = RemoveAccents(strtolower(trim($ar1))); + $ar2 = RemoveAccents(strtolower(trim($ar2))); + $translatearray = array('\''=>'', '"'=>'', '_'=>' ', '('=>'', ')'=>'', '-'=>' ', ' '=>' ', '.'=>'', ','=>''); + foreach ($translatearray as $key => $val) { + $ar1 = str_replace($key, $val, $ar1); + $ar2 = str_replace($key, $val, $ar2); + } - if ($ar1 < $ar2) { - return -1; - } elseif ($ar1 > $ar2) { - return 1; - } - return 0; - } + if ($ar1 < $ar2) { + return -1; + } elseif ($ar1 > $ar2) { + return 1; + } + return 0; + } } if (!function_exists('trunc')) { - function trunc($floatnumber) - { - // truncates a floating-point number at the decimal point - // returns int (if possible, otherwise float) - if ($floatnumber >= 1) { - $truncatednumber = floor($floatnumber); - } elseif ($floatnumber <= -1) { - $truncatednumber = ceil($floatnumber); - } else { - $truncatednumber = 0; - } - if ($truncatednumber <= pow(2, 30)) { - $truncatednumber = (int) $truncatednumber; - } - return $truncatednumber; - } + function trunc($floatnumber) { + // truncates a floating-point number at the decimal point + // returns int (if possible, otherwise float) + if ($floatnumber >= 1) { + $truncatednumber = floor($floatnumber); + } elseif ($floatnumber <= -1) { + $truncatednumber = ceil($floatnumber); + } else { + $truncatednumber = 0; + } + if ($truncatednumber <= pow(2, 30)) { + $truncatednumber = (int) $truncatednumber; + } + return $truncatednumber; + } } if (!function_exists('CastAsInt')) { - function CastAsInt($floatnum) - { - // convert to float if not already - $floatnum = (float) $floatnum; + function CastAsInt($floatnum) { + // convert to float if not already + $floatnum = (float) $floatnum; - // convert a float to type int, only if possible - if (trunc($floatnum) == $floatnum) { - // it's not floating point - if ($floatnum <= pow(2, 30)) { - // it's within int range - $floatnum = (int) $floatnum; - } - } - return $floatnum; - } + // convert a float to type int, only if possible + if (trunc($floatnum) == $floatnum) { + // it's not floating point + if ($floatnum <= pow(2, 30)) { + // it's within int range + $floatnum = (int) $floatnum; + } + } + return $floatnum; + } } if (!function_exists('getmicrotime')) { - function getmicrotime() - { - list($usec, $sec) = explode(' ', microtime()); - return ((float) $usec + (float) $sec); - } + function getmicrotime() { + list($usec, $sec) = explode(' ', microtime()); + return ((float) $usec + (float) $sec); + } } if (!function_exists('DecimalBinary2Float')) { - function DecimalBinary2Float($binarynumerator) - { - $numerator = Bin2Dec($binarynumerator); - $denominator = Bin2Dec(str_repeat('1', strlen($binarynumerator))); - return ($numerator / $denominator); - } + function DecimalBinary2Float($binarynumerator) { + $numerator = Bin2Dec($binarynumerator); + $denominator = Bin2Dec(str_repeat('1', strlen($binarynumerator))); + return ($numerator / $denominator); + } } if (!function_exists('NormalizeBinaryPoint')) { - function NormalizeBinaryPoint($binarypointnumber, $maxbits = 52) - { - // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html - if (strpos($binarypointnumber, '.') === false) { - $binarypointnumber = '0.'.$binarypointnumber; - } elseif ($binarypointnumber{0} == '.') { - $binarypointnumber = '0'.$binarypointnumber; - } - $exponent = 0; - while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) { - if (substr($binarypointnumber, 1, 1) == '.') { - $exponent--; - $binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3); - } else { - $pointpos = strpos($binarypointnumber, '.'); - $exponent += ($pointpos - 1); - $binarypointnumber = str_replace('.', '', $binarypointnumber); - $binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1); - } - } - $binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT); - return ['normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent]; - } + function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) { + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html + if (strpos($binarypointnumber, '.') === false) { + $binarypointnumber = '0.'.$binarypointnumber; + } elseif ($binarypointnumber{0} == '.') { + $binarypointnumber = '0'.$binarypointnumber; + } + $exponent = 0; + while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) { + if (substr($binarypointnumber, 1, 1) == '.') { + $exponent--; + $binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3); + } else { + $pointpos = strpos($binarypointnumber, '.'); + $exponent += ($pointpos - 1); + $binarypointnumber = str_replace('.', '', $binarypointnumber); + $binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1); + } + } + $binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT); + return array('normalized'=>$binarypointnumber, 'exponent'=>(int) $exponent); + } } if (!function_exists('Float2BinaryDecimal')) { - function Float2BinaryDecimal($floatvalue) - { - // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html - $maxbits = 128; // to how many bits of precision should the calculations be taken? - $intpart = trunc($floatvalue); - $floatpart = abs($floatvalue - $intpart); - $pointbitstring = ''; - while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) { - $floatpart *= 2; - $pointbitstring .= (string) trunc($floatpart); - $floatpart -= trunc($floatpart); - } - $binarypointnumber = decbin($intpart).'.'.$pointbitstring; - return $binarypointnumber; - } + function Float2BinaryDecimal($floatvalue) { + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/binary.html + $maxbits = 128; // to how many bits of precision should the calculations be taken? + $intpart = trunc($floatvalue); + $floatpart = abs($floatvalue - $intpart); + $pointbitstring = ''; + while (($floatpart != 0) && (strlen($pointbitstring) < $maxbits)) { + $floatpart *= 2; + $pointbitstring .= (string) trunc($floatpart); + $floatpart -= trunc($floatpart); + } + $binarypointnumber = decbin($intpart).'.'.$pointbitstring; + return $binarypointnumber; + } } if (!function_exists('Float2String')) { - function Float2String($floatvalue, $bits) - { - // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html - switch ($bits) { - case 32: - $exponentbits = 8; - $fractionbits = 23; - break; + function Float2String($floatvalue, $bits) { + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee-expl.html + switch ($bits) { + case 32: + $exponentbits = 8; + $fractionbits = 23; + break; - case 64: - $exponentbits = 11; - $fractionbits = 52; - break; + case 64: + $exponentbits = 11; + $fractionbits = 52; + break; - default: - return false; - break; - } - if ($floatvalue >= 0) { - $signbit = '0'; - } else { - $signbit = '1'; - } - $normalizedbinary = NormalizeBinaryPoint(Float2BinaryDecimal($floatvalue), $fractionbits); - $biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent - $exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT); - $fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT); + default: + return false; + break; + } + if ($floatvalue >= 0) { + $signbit = '0'; + } else { + $signbit = '1'; + } + $normalizedbinary = NormalizeBinaryPoint(Float2BinaryDecimal($floatvalue), $fractionbits); + $biasedexponent = pow(2, $exponentbits - 1) - 1 + $normalizedbinary['exponent']; // (127 or 1023) +/- exponent + $exponentbitstring = str_pad(decbin($biasedexponent), $exponentbits, '0', STR_PAD_LEFT); + $fractionbitstring = str_pad(substr($normalizedbinary['normalized'], 2), $fractionbits, '0', STR_PAD_RIGHT); - return BigEndian2String(Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false); - } + return BigEndian2String(Bin2Dec($signbit.$exponentbitstring.$fractionbitstring), $bits % 8, false); + } } if (!function_exists('LittleEndian2Float')) { - function LittleEndian2Float($byteword) - { - return BigEndian2Float(strrev($byteword)); - } + function LittleEndian2Float($byteword) { + return BigEndian2Float(strrev($byteword)); + } } if (!function_exists('BigEndian2Float')) { - function BigEndian2Float($byteword) - { - // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic - // http://www.psc.edu/general/software/packages/ieee/ieee.html - // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html + function BigEndian2Float($byteword) { + // ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic + // http://www.psc.edu/general/software/packages/ieee/ieee.html + // http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html - $bitword = BigEndian2Bin($byteword); - $signbit = $bitword{0}; + $bitword = BigEndian2Bin($byteword); + $signbit = $bitword{0}; - switch (strlen($byteword) * 8) { - case 32: - $exponentbits = 8; - $fractionbits = 23; - break; + switch (strlen($byteword) * 8) { + case 32: + $exponentbits = 8; + $fractionbits = 23; + break; - case 64: - $exponentbits = 11; - $fractionbits = 52; - break; + case 64: + $exponentbits = 11; + $fractionbits = 52; + break; - case 80: - $exponentbits = 16; - $fractionbits = 64; - break; + case 80: + $exponentbits = 16; + $fractionbits = 64; + break; - default: - return false; - break; - } - $exponentstring = substr($bitword, 1, $exponentbits - 1); - $fractionstring = substr($bitword, $exponentbits, $fractionbits); - $exponent = Bin2Dec($exponentstring); - $fraction = Bin2Dec($fractionstring); + default: + return false; + break; + } + $exponentstring = substr($bitword, 1, $exponentbits - 1); + $fractionstring = substr($bitword, $exponentbits, $fractionbits); + $exponent = Bin2Dec($exponentstring); + $fraction = Bin2Dec($fractionstring); - if (($exponentbits == 16) && ($fractionbits == 64)) { - // 80-bit - // As used in Apple AIFF for sample_rate - // A bit of a hack, but it works ;) - return pow(2, ($exponent - 16382)) * DecimalBinary2Float($fractionstring); - } + if (($exponentbits == 16) && ($fractionbits == 64)) { + // 80-bit + // As used in Apple AIFF for sample_rate + // A bit of a hack, but it works ;) + return pow(2, ($exponent - 16382)) * DecimalBinary2Float($fractionstring); + } - if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) { - // Not a Number - $floatvalue = false; - } elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) { - if ($signbit == '1') { - $floatvalue = '-infinity'; - } else { - $floatvalue = '+infinity'; - } - } elseif (($exponent == 0) && ($fraction == 0)) { - if ($signbit == '1') { - $floatvalue = -0; - } else { - $floatvalue = 0; - } - $floatvalue = ($signbit ? 0 : -0); - } elseif (($exponent == 0) && ($fraction != 0)) { - // These are 'unnormalized' values - $floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * DecimalBinary2Float($fractionstring); - if ($signbit == '1') { - $floatvalue *= -1; - } - } elseif ($exponent != 0) { - $floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + DecimalBinary2Float($fractionstring)); - if ($signbit == '1') { - $floatvalue *= -1; - } - } - return (float) $floatvalue; - } + if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) { + // Not a Number + $floatvalue = false; + } elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) { + if ($signbit == '1') { + $floatvalue = '-infinity'; + } else { + $floatvalue = '+infinity'; + } + } elseif (($exponent == 0) && ($fraction == 0)) { + if ($signbit == '1') { + $floatvalue = -0; + } else { + $floatvalue = 0; + } + $floatvalue = ($signbit ? 0 : -0); + } elseif (($exponent == 0) && ($fraction != 0)) { + // These are 'unnormalized' values + $floatvalue = pow(2, (-1 * (pow(2, $exponentbits - 1) - 2))) * DecimalBinary2Float($fractionstring); + if ($signbit == '1') { + $floatvalue *= -1; + } + } elseif ($exponent != 0) { + $floatvalue = pow(2, ($exponent - (pow(2, $exponentbits - 1) - 1))) * (1 + DecimalBinary2Float($fractionstring)); + if ($signbit == '1') { + $floatvalue *= -1; + } + } + return (float) $floatvalue; + } } if (!function_exists('BigEndian2Int')) { - function BigEndian2Int($byteword, $synchsafe = false, $signed = false) - { - $intvalue = 0; - $bytewordlen = strlen($byteword); - for ($i = 0; $i < $bytewordlen; $i++) { - if ($synchsafe) { // disregard MSB, effectively 7-bit bytes - $intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7); - } else { - $intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i)); - } - } - if ($signed && !$synchsafe) { - // synchsafe ints are not allowed to be signed - switch ($bytewordlen) { - case 1: - case 2: - case 3: - case 4: - $signmaskbit = 0x80 << (8 * ($bytewordlen - 1)); - if ($intvalue & $signmaskbit) { - $intvalue = 0 - ($intvalue & ($signmaskbit - 1)); - } - break; + function BigEndian2Int($byteword, $synchsafe=false, $signed=false) { + $intvalue = 0; + $bytewordlen = strlen($byteword); + for ($i = 0; $i < $bytewordlen; $i++) { + if ($synchsafe) { // disregard MSB, effectively 7-bit bytes + $intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7); + } else { + $intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i)); + } + } + if ($signed && !$synchsafe) { + // synchsafe ints are not allowed to be signed + switch ($bytewordlen) { + case 1: + case 2: + case 3: + case 4: + $signmaskbit = 0x80 << (8 * ($bytewordlen - 1)); + if ($intvalue & $signmaskbit) { + $intvalue = 0 - ($intvalue & ($signmaskbit - 1)); + } + break; - default: - die('ERROR: Cannot have signed integers larger than 32-bits in BigEndian2Int()'); - break; - } - } - return CastAsInt($intvalue); - } + default: + die('ERROR: Cannot have signed integers larger than 32-bits in BigEndian2Int()'); + break; + } + } + return CastAsInt($intvalue); + } } if (!function_exists('LittleEndian2Int')) { - function LittleEndian2Int($byteword, $signed = false) - { - return BigEndian2Int(strrev($byteword), false, $signed); - } + function LittleEndian2Int($byteword, $signed=false) { + return BigEndian2Int(strrev($byteword), false, $signed); + } } if (!function_exists('BigEndian2Bin')) { - function BigEndian2Bin($byteword) - { - $binvalue = ''; - $bytewordlen = strlen($byteword); - for ($i = 0; $i < $bytewordlen; $i++) { - $binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT); - } - return $binvalue; - } + function BigEndian2Bin($byteword) { + $binvalue = ''; + $bytewordlen = strlen($byteword); + for ($i = 0; $i < $bytewordlen; $i++) { + $binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT); + } + return $binvalue; + } } if (!function_exists('BigEndian2String')) { - function BigEndian2String($number, $minbytes = 1, $synchsafe = false, $signed = false) - { - if ($number < 0) { - return false; - } - $maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF); - $intstring = ''; - if ($signed) { - if ($minbytes > 4) { - die('ERROR: Cannot have signed integers larger than 32-bits in BigEndian2String()'); - } - $number = $number & (0x80 << (8 * ($minbytes - 1))); - } - while ($number != 0) { - $quotient = ($number / ($maskbyte + 1)); - $intstring = chr(ceil(($quotient - floor($quotient)) * $maskbyte)).$intstring; - $number = floor($quotient); - } - return str_pad($intstring, $minbytes, chr(0), STR_PAD_LEFT); - } + function BigEndian2String($number, $minbytes=1, $synchsafe=false, $signed=false) { + if ($number < 0) { + return false; + } + $maskbyte = (($synchsafe || $signed) ? 0x7F : 0xFF); + $intstring = ''; + if ($signed) { + if ($minbytes > 4) { + die('ERROR: Cannot have signed integers larger than 32-bits in BigEndian2String()'); + } + $number = $number & (0x80 << (8 * ($minbytes - 1))); + } + while ($number != 0) { + $quotient = ($number / ($maskbyte + 1)); + $intstring = chr(ceil(($quotient - floor($quotient)) * $maskbyte)).$intstring; + $number = floor($quotient); + } + return str_pad($intstring, $minbytes, chr(0), STR_PAD_LEFT); + } } if (!function_exists('Dec2Bin')) { - function Dec2Bin($number) - { - while ($number >= 256) { - $bytes[] = (($number / 256) - (floor($number / 256))) * 256; - $number = floor($number / 256); - } - $bytes[] = $number; - $binstring = ''; - for ($i = 0; $i < count($bytes); $i++) { - $binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring; - } - return $binstring; - } + function Dec2Bin($number) { + while ($number >= 256) { + $bytes[] = (($number / 256) - (floor($number / 256))) * 256; + $number = floor($number / 256); + } + $bytes[] = $number; + $binstring = ''; + for ($i = 0; $i < count($bytes); $i++) { + $binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring; + } + return $binstring; + } } if (!function_exists('Bin2Dec')) { - function Bin2Dec($binstring) - { - $decvalue = 0; - for ($i = 0; $i < strlen($binstring); $i++) { - $decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i); - } - return CastAsInt($decvalue); - } + function Bin2Dec($binstring) { + $decvalue = 0; + for ($i = 0; $i < strlen($binstring); $i++) { + $decvalue += ((int) substr($binstring, strlen($binstring) - $i - 1, 1)) * pow(2, $i); + } + return CastAsInt($decvalue); + } } if (!function_exists('Bin2String')) { - function Bin2String($binstring) - { - // return 'hi' for input of '0110100001101001' - $string = ''; - $binstringreversed = strrev($binstring); - for ($i = 0; $i < strlen($binstringreversed); $i += 8) { - $string = chr(Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string; - } - return $string; - } + function Bin2String($binstring) { + // return 'hi' for input of '0110100001101001' + $string = ''; + $binstringreversed = strrev($binstring); + for ($i = 0; $i < strlen($binstringreversed); $i += 8) { + $string = chr(Bin2Dec(strrev(substr($binstringreversed, $i, 8)))).$string; + } + return $string; + } } if (!function_exists('LittleEndian2String')) { - function LittleEndian2String($number, $minbytes = 1, $synchsafe = false) - { - $intstring = ''; - while ($number > 0) { - if ($synchsafe) { - $intstring = $intstring.chr($number & 127); - $number >>= 7; - } else { - $intstring = $intstring.chr($number & 255); - $number >>= 8; - } - } - return str_pad($intstring, $minbytes, chr(0), STR_PAD_RIGHT); - } + function LittleEndian2String($number, $minbytes=1, $synchsafe=false) { + $intstring = ''; + while ($number > 0) { + if ($synchsafe) { + $intstring = $intstring.chr($number & 127); + $number >>= 7; + } else { + $intstring = $intstring.chr($number & 255); + $number >>= 8; + } + } + return str_pad($intstring, $minbytes, chr(0), STR_PAD_RIGHT); + } } if (!function_exists('Bool2IntString')) { - function Bool2IntString($intvalue) - { - return ($intvalue ? '1' : '0'); - } + function Bool2IntString($intvalue) { + return ($intvalue ? '1' : '0'); + } } if (!function_exists('IntString2Bool')) { - function IntString2Bool($char) - { - if ($char == '1') { - return true; - } elseif ($char == '0') { - return false; - } - return null; - } + function IntString2Bool($char) { + if ($char == '1') { + return true; + } elseif ($char == '0') { + return false; + } + return null; + } } if (!function_exists('InverseBoolean')) { - function InverseBoolean($value) - { - return ($value ? false : true); - } + function InverseBoolean($value) { + return ($value ? false : true); + } } if (!function_exists('DeUnSynchronise')) { - function DeUnSynchronise($data) - { - return str_replace(chr(0xFF).chr(0x00), chr(0xFF), $data); - } + function DeUnSynchronise($data) { + return str_replace(chr(0xFF).chr(0x00), chr(0xFF), $data); + } } if (!function_exists('Unsynchronise')) { - function Unsynchronise($data) - { - // Whenever a false synchronisation is found within the tag, one zeroed - // byte is inserted after the first false synchronisation byte. The - // format of a correct sync that should be altered by ID3 encoders is as - // follows: - // %11111111 111xxxxx - // And should be replaced with: - // %11111111 00000000 111xxxxx - // This has the side effect that all $FF 00 combinations have to be - // altered, so they won't be affected by the decoding process. Therefore - // all the $FF 00 combinations have to be replaced with the $FF 00 00 - // combination during the unsynchronisation. + function Unsynchronise($data) { + // Whenever a false synchronisation is found within the tag, one zeroed + // byte is inserted after the first false synchronisation byte. The + // format of a correct sync that should be altered by ID3 encoders is as + // follows: + // %11111111 111xxxxx + // And should be replaced with: + // %11111111 00000000 111xxxxx + // This has the side effect that all $FF 00 combinations have to be + // altered, so they won't be affected by the decoding process. Therefore + // all the $FF 00 combinations have to be replaced with the $FF 00 00 + // combination during the unsynchronisation. - $data = str_replace(chr(0xFF).chr(0x00), chr(0xFF).chr(0x00).chr(0x00), $data); - $unsyncheddata = ''; - for ($i = 0; $i < strlen($data); $i++) { - $thischar = $data{$i}; - $unsyncheddata .= $thischar; - if ($thischar == chr(255)) { - $nextchar = ord(substr($data, $i + 1, 1)); - if (($nextchar | 0xE0) == 0xE0) { - // previous byte = 11111111, this byte = 111????? - $unsyncheddata .= chr(0); - } - } - } - return $unsyncheddata; - } + $data = str_replace(chr(0xFF).chr(0x00), chr(0xFF).chr(0x00).chr(0x00), $data); + $unsyncheddata = ''; + for ($i = 0; $i < strlen($data); $i++) { + $thischar = $data{$i}; + $unsyncheddata .= $thischar; + if ($thischar == chr(255)) { + $nextchar = ord(substr($data, $i + 1, 1)); + if (($nextchar | 0xE0) == 0xE0) { + // previous byte = 11111111, this byte = 111????? + $unsyncheddata .= chr(0); + } + } + } + return $unsyncheddata; + } } if (!function_exists('is_hash')) { - function is_hash($var) - { - // written by dev-null@christophe.vg - // taken from http://www.php.net/manual/en/function.array-merge-recursive.php - if (is_array($var)) { - $keys = array_keys($var); - $all_num = true; - for ($i = 0; $i < count($keys); $i++) { - if (is_string($keys[$i])) { - return true; - } - } - } - return false; - } + function is_hash($var) { + // written by dev-null@christophe.vg + // taken from http://www.php.net/manual/en/function.array-merge-recursive.php + if (is_array($var)) { + $keys = array_keys($var); + $all_num = true; + for ($i = 0; $i < count($keys); $i++) { + if (is_string($keys[$i])) { + return true; + } + } + } + return false; + } } if (!function_exists('array_join_merge')) { - function array_join_merge($arr1, $arr2) - { - // written by dev-null@christophe.vg - // taken from http://www.php.net/manual/en/function.array-merge-recursive.php - if (is_array($arr1) && is_array($arr2)) { - // the same -> merge - $new_array = []; + function array_join_merge($arr1, $arr2) { + // written by dev-null@christophe.vg + // taken from http://www.php.net/manual/en/function.array-merge-recursive.php + if (is_array($arr1) && is_array($arr2)) { + // the same -> merge + $new_array = array(); - if (is_hash($arr1) && is_hash($arr2)) { - // hashes -> merge based on keys - $keys = array_merge(array_keys($arr1), array_keys($arr2)); - foreach ($keys as $key) { - $arr1[$key] = (isset($arr1[$key]) ? $arr1[$key] : ''); - $arr2[$key] = (isset($arr2[$key]) ? $arr2[$key] : ''); - $new_array[$key] = array_join_merge($arr1[$key], $arr2[$key]); - } - } else { - // two real arrays -> merge - $new_array = array_reverse(array_unique(array_reverse(array_merge($arr1, $arr2)))); - } - return $new_array; - } else { - // not the same ... take new one if defined, else the old one stays - return $arr2 ? $arr2 : $arr1; - } - } + if (is_hash($arr1) && is_hash($arr2)) { + // hashes -> merge based on keys + $keys = array_merge(array_keys($arr1), array_keys($arr2)); + foreach ($keys as $key) { + $arr1[$key] = (isset($arr1[$key]) ? $arr1[$key] : ''); + $arr2[$key] = (isset($arr2[$key]) ? $arr2[$key] : ''); + $new_array[$key] = array_join_merge($arr1[$key], $arr2[$key]); + } + } else { + // two real arrays -> merge + $new_array = array_reverse(array_unique(array_reverse(array_merge($arr1,$arr2)))); + } + return $new_array; + } else { + // not the same ... take new one if defined, else the old one stays + return $arr2 ? $arr2 : $arr1; + } + } } if (!function_exists('array_merge_clobber')) { - function array_merge_clobber($array1, $array2) - { - // written by kc@hireability.com - // taken from http://www.php.net/manual/en/function.array-merge-recursive.php - if (!is_array($array1) || !is_array($array2)) { - return false; - } - $newarray = $array1; - foreach ($array2 as $key => $val) { - if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) { - $newarray[$key] = array_merge_clobber($newarray[$key], $val); - } else { - $newarray[$key] = $val; - } - } - return $newarray; - } + function array_merge_clobber($array1, $array2) { + // written by kc@hireability.com + // taken from http://www.php.net/manual/en/function.array-merge-recursive.php + if (!is_array($array1) || !is_array($array2)) { + return false; + } + $newarray = $array1; + foreach ($array2 as $key => $val) { + if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) { + $newarray[$key] = array_merge_clobber($newarray[$key], $val); + } else { + $newarray[$key] = $val; + } + } + return $newarray; + } } if (!function_exists('array_merge_noclobber')) { - function array_merge_noclobber($array1, $array2) - { - if (!is_array($array1) || !is_array($array2)) { - return false; - } - $newarray = $array1; - foreach ($array2 as $key => $val) { - if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) { - $newarray[$key] = array_merge_noclobber($newarray[$key], $val); - } elseif (!isset($newarray[$key])) { - $newarray[$key] = $val; - } - } - return $newarray; - } + function array_merge_noclobber($array1, $array2) { + if (!is_array($array1) || !is_array($array2)) { + return false; + } + $newarray = $array1; + foreach ($array2 as $key => $val) { + if (is_array($val) && isset($newarray[$key]) && is_array($newarray[$key])) { + $newarray[$key] = array_merge_noclobber($newarray[$key], $val); + } elseif (!isset($newarray[$key])) { + $newarray[$key] = $val; + } + } + return $newarray; + } } if (!function_exists('RoughTranslateUnicodeToASCII')) { - function RoughTranslateUnicodeToASCII($rawdata, $frame_textencoding) - { - // rough translation of data for application that can't handle Unicode data + function RoughTranslateUnicodeToASCII($rawdata, $frame_textencoding) { + // rough translation of data for application that can't handle Unicode data - $tempstring = ''; - switch ($frame_textencoding) { - case 0: // ISO-8859-1. Terminated with $00. - $asciidata = $rawdata; - break; + $tempstring = ''; + switch ($frame_textencoding) { + case 0: // ISO-8859-1. Terminated with $00. + $asciidata = $rawdata; + break; - case 1: // UTF-16 encoded Unicode with BOM. Terminated with $00 00. - $asciidata = $rawdata; - if (substr($asciidata, 0, 2) == chr(0xFF).chr(0xFE)) { - // remove BOM, only if present (it should be, but...) - $asciidata = substr($asciidata, 2); - } - if (substr($asciidata, strlen($asciidata) - 2, 2) == chr(0).chr(0)) { - $asciidata = substr($asciidata, 0, strlen($asciidata) - 2); // remove terminator, only if present (it should be, but...) - } - for ($i = 0; $i < strlen($asciidata); $i += 2) { - if ((ord($asciidata{$i}) <= 0x7F) || (ord($asciidata{$i}) >= 0xA0)) { - $tempstring .= $asciidata{$i}; - } else { - $tempstring .= '?'; - } - } - $asciidata = $tempstring; - break; + case 1: // UTF-16 encoded Unicode with BOM. Terminated with $00 00. + $asciidata = $rawdata; + if (substr($asciidata, 0, 2) == chr(0xFF).chr(0xFE)) { + // remove BOM, only if present (it should be, but...) + $asciidata = substr($asciidata, 2); + } + if (substr($asciidata, strlen($asciidata) - 2, 2) == chr(0).chr(0)) { + $asciidata = substr($asciidata, 0, strlen($asciidata) - 2); // remove terminator, only if present (it should be, but...) + } + for ($i = 0; $i < strlen($asciidata); $i += 2) { + if ((ord($asciidata{$i}) <= 0x7F) || (ord($asciidata{$i}) >= 0xA0)) { + $tempstring .= $asciidata{$i}; + } else { + $tempstring .= '?'; + } + } + $asciidata = $tempstring; + break; - case 2: // UTF-16BE encoded Unicode without BOM. Terminated with $00 00. - $asciidata = $rawdata; - if (substr($asciidata, strlen($asciidata) - 2, 2) == chr(0).chr(0)) { - $asciidata = substr($asciidata, 0, strlen($asciidata) - 2); // remove terminator, only if present (it should be, but...) - } - for ($i = 0; $i < strlen($asciidata); $i += 2) { - if ((ord($asciidata{$i}) <= 0x7F) || (ord($asciidata{$i}) >= 0xA0)) { - $tempstring .= $asciidata{$i}; - } else { - $tempstring .= '?'; - } - } - $asciidata = $tempstring; - break; + case 2: // UTF-16BE encoded Unicode without BOM. Terminated with $00 00. + $asciidata = $rawdata; + if (substr($asciidata, strlen($asciidata) - 2, 2) == chr(0).chr(0)) { + $asciidata = substr($asciidata, 0, strlen($asciidata) - 2); // remove terminator, only if present (it should be, but...) + } + for ($i = 0; $i < strlen($asciidata); $i += 2) { + if ((ord($asciidata{$i}) <= 0x7F) || (ord($asciidata{$i}) >= 0xA0)) { + $tempstring .= $asciidata{$i}; + } else { + $tempstring .= '?'; + } + } + $asciidata = $tempstring; + break; - case 3: // UTF-8 encoded Unicode. Terminated with $00. - $asciidata = utf8_decode($rawdata); - break; + case 3: // UTF-8 encoded Unicode. Terminated with $00. + $asciidata = utf8_decode($rawdata); + break; - case 255: // Unicode, Big-Endian. Terminated with $00 00. - $asciidata = $rawdata; - if (substr($asciidata, strlen($asciidata) - 2, 2) == chr(0).chr(0)) { - $asciidata = substr($asciidata, 0, strlen($asciidata) - 2); // remove terminator, only if present (it should be, but...) - } - for ($i = 0; ($i + 1) < strlen($asciidata); $i += 2) { - if ((ord($asciidata{($i + 1)}) <= 0x7F) || (ord($asciidata{($i + 1)}) >= 0xA0)) { - $tempstring .= $asciidata{($i + 1)}; - } else { - $tempstring .= '?'; - } - } - $asciidata = $tempstring; - break; + case 255: // Unicode, Big-Endian. Terminated with $00 00. + $asciidata = $rawdata; + if (substr($asciidata, strlen($asciidata) - 2, 2) == chr(0).chr(0)) { + $asciidata = substr($asciidata, 0, strlen($asciidata) - 2); // remove terminator, only if present (it should be, but...) + } + for ($i = 0; ($i + 1) < strlen($asciidata); $i += 2) { + if ((ord($asciidata{($i + 1)}) <= 0x7F) || (ord($asciidata{($i + 1)}) >= 0xA0)) { + $tempstring .= $asciidata{($i + 1)}; + } else { + $tempstring .= '?'; + } + } + $asciidata = $tempstring; + break; - default: - // shouldn't happen, but in case $frame_textencoding is not 1 <= $frame_textencoding <= 4 - // just pass the data through unchanged. - $asciidata = $rawdata; - break; - } - if (substr($asciidata, strlen($asciidata) - 1, 1) == chr(0)) { - // remove null terminator, if present - $asciidata = NoNullString($asciidata); - } - return $asciidata; - // return str_replace(chr(0), '', $asciidata); // just in case any nulls slipped through - } + default: + // shouldn't happen, but in case $frame_textencoding is not 1 <= $frame_textencoding <= 4 + // just pass the data through unchanged. + $asciidata = $rawdata; + break; + } + if (substr($asciidata, strlen($asciidata) - 1, 1) == chr(0)) { + // remove null terminator, if present + $asciidata = NoNullString($asciidata); + } + return $asciidata; + // return str_replace(chr(0), '', $asciidata); // just in case any nulls slipped through + } } if (!function_exists('PlaytimeString')) { - function PlaytimeString($playtimeseconds) - { - $contentseconds = round((($playtimeseconds / 60) - floor($playtimeseconds / 60)) * 60); - $contentminutes = floor($playtimeseconds / 60); - if ($contentseconds >= 60) { - $contentseconds -= 60; - $contentminutes++; - } - return number_format($contentminutes).':'.str_pad($contentseconds, 2, 0, STR_PAD_LEFT); - } + function PlaytimeString($playtimeseconds) { + $contentseconds = round((($playtimeseconds / 60) - floor($playtimeseconds / 60)) * 60); + $contentminutes = floor($playtimeseconds / 60); + if ($contentseconds >= 60) { + $contentseconds -= 60; + $contentminutes++; + } + return number_format($contentminutes).':'.str_pad($contentseconds, 2, 0, STR_PAD_LEFT); + } } if (!function_exists('CloseMatch')) { - function CloseMatch($value1, $value2, $tolerance) - { - return (abs($value1 - $value2) <= $tolerance); - } + function CloseMatch($value1, $value2, $tolerance) { + return (abs($value1 - $value2) <= $tolerance); + } } if (!function_exists('ID3v1matchesID3v2')) { - function ID3v1matchesID3v2($id3v1, $id3v2) - { + function ID3v1matchesID3v2($id3v1, $id3v2) { - $requiredindices = ['title', 'artist', 'album', 'year', 'genre', 'comment']; - foreach ($requiredindices as $requiredindex) { - if (!isset($id3v1["$requiredindex"])) { - $id3v1["$requiredindex"] = ''; - } - if (!isset($id3v2["$requiredindex"])) { - $id3v2["$requiredindex"] = ''; - } - } + $requiredindices = array('title', 'artist', 'album', 'year', 'genre', 'comment'); + foreach ($requiredindices as $requiredindex) { + if (!isset($id3v1["$requiredindex"])) { + $id3v1["$requiredindex"] = ''; + } + if (!isset($id3v2["$requiredindex"])) { + $id3v2["$requiredindex"] = ''; + } + } - if (trim($id3v1['title']) != trim(substr($id3v2['title'], 0, 30))) { - return false; - } - if (trim($id3v1['artist']) != trim(substr($id3v2['artist'], 0, 30))) { - return false; - } - if (trim($id3v1['album']) != trim(substr($id3v2['album'], 0, 30))) { - return false; - } - if (trim($id3v1['year']) != trim(substr($id3v2['year'], 0, 4))) { - return false; - } - if (trim($id3v1['genre']) != trim($id3v2['genre'])) { - return false; - } - if (isset($id3v1['track'])) { - if (!isset($id3v1['track']) || (trim($id3v1['track']) != trim($id3v2['track']))) { - return false; - } - if (trim($id3v1['comment']) != trim(substr($id3v2['comment'], 0, 28))) { - return false; - } - } else { - if (trim($id3v1['comment']) != trim(substr($id3v2['comment'], 0, 30))) { - return false; - } - } - return true; - } + if (trim($id3v1['title']) != trim(substr($id3v2['title'], 0, 30))) { + return false; + } + if (trim($id3v1['artist']) != trim(substr($id3v2['artist'], 0, 30))) { + return false; + } + if (trim($id3v1['album']) != trim(substr($id3v2['album'], 0, 30))) { + return false; + } + if (trim($id3v1['year']) != trim(substr($id3v2['year'], 0, 4))) { + return false; + } + if (trim($id3v1['genre']) != trim($id3v2['genre'])) { + return false; + } + if (isset($id3v1['track'])) { + if (!isset($id3v1['track']) || (trim($id3v1['track']) != trim($id3v2['track']))) { + return false; + } + if (trim($id3v1['comment']) != trim(substr($id3v2['comment'], 0, 28))) { + return false; + } + } else { + if (trim($id3v1['comment']) != trim(substr($id3v2['comment'], 0, 30))) { + return false; + } + } + return true; + } } if (!function_exists('FILETIMEtoUNIXtime')) { - function FILETIMEtoUNIXtime($FILETIME, $round = true) - { - // FILETIME is a 64-bit unsigned integer representing - // the number of 100-nanosecond intervals since January 1, 1601 - // UNIX timestamp is number of seconds since January 1, 1970 - // 116444736000000000 = 10000000 * 60 * 60 * 24 * 365 * 369 + 89 leap days - if ($round) { - return round(($FILETIME - 116444736000000000) / 10000000); - } - return ($FILETIME - 116444736000000000) / 10000000; - } + function FILETIMEtoUNIXtime($FILETIME, $round=true) { + // FILETIME is a 64-bit unsigned integer representing + // the number of 100-nanosecond intervals since January 1, 1601 + // UNIX timestamp is number of seconds since January 1, 1970 + // 116444736000000000 = 10000000 * 60 * 60 * 24 * 365 * 369 + 89 leap days + if ($round) { + return round(($FILETIME - 116444736000000000) / 10000000); + } + return ($FILETIME - 116444736000000000) / 10000000; + } } if (!function_exists('GUIDtoBytestring')) { - function GUIDtoBytestring($GUIDstring) - { - // Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way: - // first 4 bytes are in little-endian order - // next 2 bytes are appended in little-endian order - // next 2 bytes are appended in little-endian order - // next 2 bytes are appended in big-endian order - // next 6 bytes are appended in big-endian order + function GUIDtoBytestring($GUIDstring) { + // Microsoft defines these 16-byte (128-bit) GUIDs in the strangest way: + // first 4 bytes are in little-endian order + // next 2 bytes are appended in little-endian order + // next 2 bytes are appended in little-endian order + // next 2 bytes are appended in big-endian order + // next 6 bytes are appended in big-endian order - // AaBbCcDd-EeFf-GgHh-IiJj-KkLlMmNnOoPp is stored as this 16-byte string: - // $Dd $Cc $Bb $Aa $Ff $Ee $Hh $Gg $Ii $Jj $Kk $Ll $Mm $Nn $Oo $Pp + // AaBbCcDd-EeFf-GgHh-IiJj-KkLlMmNnOoPp is stored as this 16-byte string: + // $Dd $Cc $Bb $Aa $Ff $Ee $Hh $Gg $Ii $Jj $Kk $Ll $Mm $Nn $Oo $Pp - $hexbytecharstring = chr(hexdec(substr($GUIDstring, 6, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 4, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 2, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 0, 2))); + $hexbytecharstring = chr(hexdec(substr($GUIDstring, 6, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 4, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 2, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 0, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 11, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 9, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 11, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 9, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 16, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 14, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 16, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 14, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 19, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 21, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 19, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 21, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 24, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 26, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 28, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 30, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 32, 2))); - $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 34, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 24, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 26, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 28, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 30, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 32, 2))); + $hexbytecharstring .= chr(hexdec(substr($GUIDstring, 34, 2))); - return $hexbytecharstring; - } + return $hexbytecharstring; + } } if (!function_exists('BytestringToGUID')) { - function BytestringToGUID($Bytestring) - { - $GUIDstring = str_pad(dechex(ord($Bytestring{3})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{2})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{1})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{0})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= '-'; - $GUIDstring .= str_pad(dechex(ord($Bytestring{5})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{4})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= '-'; - $GUIDstring .= str_pad(dechex(ord($Bytestring{7})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{6})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= '-'; - $GUIDstring .= str_pad(dechex(ord($Bytestring{8})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{9})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= '-'; - $GUIDstring .= str_pad(dechex(ord($Bytestring{10})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{11})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{12})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{13})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{14})), 2, '0', STR_PAD_LEFT); - $GUIDstring .= str_pad(dechex(ord($Bytestring{15})), 2, '0', STR_PAD_LEFT); + function BytestringToGUID($Bytestring) { + $GUIDstring = str_pad(dechex(ord($Bytestring{3})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{2})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{1})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{0})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= '-'; + $GUIDstring .= str_pad(dechex(ord($Bytestring{5})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{4})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= '-'; + $GUIDstring .= str_pad(dechex(ord($Bytestring{7})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{6})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= '-'; + $GUIDstring .= str_pad(dechex(ord($Bytestring{8})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{9})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= '-'; + $GUIDstring .= str_pad(dechex(ord($Bytestring{10})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{11})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{12})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{13})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{14})), 2, '0', STR_PAD_LEFT); + $GUIDstring .= str_pad(dechex(ord($Bytestring{15})), 2, '0', STR_PAD_LEFT); - return strtoupper($GUIDstring); - } + return strtoupper($GUIDstring); + } } if (!function_exists('BitrateColor')) { - function BitrateColor($bitrate) - { - $bitrate /= 3; // scale from 1-768kbps to 1-256kbps - $bitrate--; // scale from 1-256kbps to 0-255kbps - $bitrate = max($bitrate, 0); - $bitrate = min($bitrate, 255); - //$bitrate = max($bitrate, 32); - //$bitrate = min($bitrate, 143); - //$bitrate = ($bitrate * 2) - 32; + function BitrateColor($bitrate) { + $bitrate /= 3; // scale from 1-768kbps to 1-256kbps + $bitrate--; // scale from 1-256kbps to 0-255kbps + $bitrate = max($bitrate, 0); + $bitrate = min($bitrate, 255); + //$bitrate = max($bitrate, 32); + //$bitrate = min($bitrate, 143); + //$bitrate = ($bitrate * 2) - 32; - $Rcomponent = max(255 - ($bitrate * 2), 0); - $Gcomponent = max(($bitrate * 2) - 255, 0); - if ($bitrate > 127) { - $Bcomponent = max((255 - $bitrate) * 2, 0); - } else { - $Bcomponent = max($bitrate * 2, 0); - } - return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT); - } + $Rcomponent = max(255 - ($bitrate * 2), 0); + $Gcomponent = max(($bitrate * 2) - 255, 0); + if ($bitrate > 127) { + $Bcomponent = max((255 - $bitrate) * 2, 0); + } else { + $Bcomponent = max($bitrate * 2, 0); + } + return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT); + } } if (!function_exists('BitrateText')) { - function BitrateText($bitrate) - { - return ''.round($bitrate).' kbps'; - } + function BitrateText($bitrate) { + return ''.round($bitrate).' kbps'; + } } if (!function_exists('image_type_to_mime_type')) { - function image_type_to_mime_type($imagetypeid) - { - // only available in PHP v4.3.0+ - static $image_type_to_mime_type = []; - if (empty($image_type_to_mime_type)) { - $image_type_to_mime_type[1] = 'image/gif'; // GIF - $image_type_to_mime_type[2] = 'image/jpeg'; // JPEG - $image_type_to_mime_type[3] = 'image/png'; // PNG - $image_type_to_mime_type[4] = 'application/x-shockwave-flash'; // Flash - $image_type_to_mime_type[5] = 'image/psd'; // PSD - $image_type_to_mime_type[6] = 'image/bmp'; // BMP - $image_type_to_mime_type[7] = 'image/tiff'; // TIFF: little-endian (Intel) - $image_type_to_mime_type[8] = 'image/tiff'; // TIFF: big-endian (Motorola) - //$image_type_to_mime_type[9] = 'image/jpc'; // JPC - //$image_type_to_mime_type[10] = 'image/jp2'; // JPC - //$image_type_to_mime_type[11] = 'image/jpx'; // JPC - //$image_type_to_mime_type[12] = 'image/jb2'; // JPC - $image_type_to_mime_type[13] = 'application/x-shockwave-flash'; // Shockwave - $image_type_to_mime_type[14] = 'image/iff'; // IFF - } - return (isset($image_type_to_mime_type[$imagetypeid]) ? $image_type_to_mime_type[$imagetypeid] : 'application/octet-stream'); - } + function image_type_to_mime_type($imagetypeid) { + // only available in PHP v4.3.0+ + static $image_type_to_mime_type = array(); + if (empty($image_type_to_mime_type)) { + $image_type_to_mime_type[1] = 'image/gif'; // GIF + $image_type_to_mime_type[2] = 'image/jpeg'; // JPEG + $image_type_to_mime_type[3] = 'image/png'; // PNG + $image_type_to_mime_type[4] = 'application/x-shockwave-flash'; // Flash + $image_type_to_mime_type[5] = 'image/psd'; // PSD + $image_type_to_mime_type[6] = 'image/bmp'; // BMP + $image_type_to_mime_type[7] = 'image/tiff'; // TIFF: little-endian (Intel) + $image_type_to_mime_type[8] = 'image/tiff'; // TIFF: big-endian (Motorola) + //$image_type_to_mime_type[9] = 'image/jpc'; // JPC + //$image_type_to_mime_type[10] = 'image/jp2'; // JPC + //$image_type_to_mime_type[11] = 'image/jpx'; // JPC + //$image_type_to_mime_type[12] = 'image/jb2'; // JPC + $image_type_to_mime_type[13] = 'application/x-shockwave-flash'; // Shockwave + $image_type_to_mime_type[14] = 'image/iff'; // IFF + } + return (isset($image_type_to_mime_type[$imagetypeid]) ? $image_type_to_mime_type[$imagetypeid] : 'application/octet-stream'); + } } if (!function_exists('utf8_decode')) { - // PHP has this function built-in if it's configured with the --with-xml option - // This version of the function is only provided in case XML isn't installed - function utf8_decode($utf8text) - { - // http://www.php.net/manual/en/function.utf8-encode.php - // bytes bits representation - // 1 7 0bbbbbbb - // 2 11 110bbbbb 10bbbbbb - // 3 16 1110bbbb 10bbbbbb 10bbbbbb - // 4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb + // PHP has this function built-in if it's configured with the --with-xml option + // This version of the function is only provided in case XML isn't installed + function utf8_decode($utf8text) { + // http://www.php.net/manual/en/function.utf8-encode.php + // bytes bits representation + // 1 7 0bbbbbbb + // 2 11 110bbbbb 10bbbbbb + // 3 16 1110bbbb 10bbbbbb 10bbbbbb + // 4 21 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb - $utf8length = strlen($utf8text); - $decodedtext = ''; - for ($i = 0; $i < $utf8length; $i++) { - if ((ord($utf8text{$i}) & 0x80) == 0) { - $decodedtext .= $utf8text{$i}; - } elseif ((ord($utf8text{$i}) & 0xF0) == 0xF0) { - $decodedtext .= '?'; - $i += 3; - } elseif ((ord($utf8text{$i}) & 0xE0) == 0xE0) { - $decodedtext .= '?'; - $i += 2; - } elseif ((ord($utf8text{$i}) & 0xC0) == 0xC0) { - // 2 11 110bbbbb 10bbbbbb - $decodedchar = Bin2Dec(substr(Dec2Bin(ord($utf8text{$i})), 3, 5).substr(Dec2Bin(ord($utf8text{($i + 1)})), 2, 6)); - if ($decodedchar <= 255) { - $decodedtext .= chr($decodedchar); - } else { - $decodedtext .= '?'; - } - $i += 1; - } - } - return $decodedtext; - } + $utf8length = strlen($utf8text); + $decodedtext = ''; + for ($i = 0; $i < $utf8length; $i++) { + if ((ord($utf8text{$i}) & 0x80) == 0) { + $decodedtext .= $utf8text{$i}; + } elseif ((ord($utf8text{$i}) & 0xF0) == 0xF0) { + $decodedtext .= '?'; + $i += 3; + } elseif ((ord($utf8text{$i}) & 0xE0) == 0xE0) { + $decodedtext .= '?'; + $i += 2; + } elseif ((ord($utf8text{$i}) & 0xC0) == 0xC0) { + // 2 11 110bbbbb 10bbbbbb + $decodedchar = Bin2Dec(substr(Dec2Bin(ord($utf8text{$i})), 3, 5).substr(Dec2Bin(ord($utf8text{($i + 1)})), 2, 6)); + if ($decodedchar <= 255) { + $decodedtext .= chr($decodedchar); + } else { + $decodedtext .= '?'; + } + $i += 1; + } + } + return $decodedtext; + } } if (!function_exists('DateMac2Unix')) { - function DateMac2Unix($macdate) - { - // Macintosh timestamp: seconds since 00:00h January 1, 1904 - // UNIX timestamp: seconds since 00:00h January 1, 1970 - return CastAsInt($macdate - 2082844800); - } + function DateMac2Unix($macdate) { + // Macintosh timestamp: seconds since 00:00h January 1, 1904 + // UNIX timestamp: seconds since 00:00h January 1, 1970 + return CastAsInt($macdate - 2082844800); + } } if (!function_exists('FixedPoint8_8')) { - function FixedPoint8_8($rawdata) - { - return BigEndian2Int(substr($rawdata, 0, 1)) + (float) (BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8)); - } + function FixedPoint8_8($rawdata) { + return BigEndian2Int(substr($rawdata, 0, 1)) + (float) (BigEndian2Int(substr($rawdata, 1, 1)) / pow(2, 8)); + } } if (!function_exists('FixedPoint16_16')) { - function FixedPoint16_16($rawdata) - { - return BigEndian2Int(substr($rawdata, 0, 2)) + (float) (BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16)); - } + function FixedPoint16_16($rawdata) { + return BigEndian2Int(substr($rawdata, 0, 2)) + (float) (BigEndian2Int(substr($rawdata, 2, 2)) / pow(2, 16)); + } } if (!function_exists('FixedPoint2_30')) { - function FixedPoint2_30($rawdata) - { - $binarystring = BigEndian2Bin($rawdata); - return Bin2Dec(substr($binarystring, 0, 2)) + (float) (Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30)); - } + function FixedPoint2_30($rawdata) { + $binarystring = BigEndian2Bin($rawdata); + return Bin2Dec(substr($binarystring, 0, 2)) + (float) (Bin2Dec(substr($binarystring, 2, 30)) / pow(2, 30)); + } } if (!function_exists('Pascal2String')) { - function Pascal2String($pascalstring) - { - // Pascal strings have 1 byte at the beginning saying how many chars are in the string - return substr($pascalstring, 1); - } + function Pascal2String($pascalstring) { + // Pascal strings have 1 byte at the beginning saying how many chars are in the string + return substr($pascalstring, 1); + } } if (!function_exists('NoNullString')) { - function NoNullString($nullterminatedstring) - { - // remove the single null terminator on null terminated strings - if (substr($nullterminatedstring, strlen($nullterminatedstring) - 1, 1) === chr(0)) { - return substr($nullterminatedstring, 0, strlen($nullterminatedstring) - 1); - } - return $nullterminatedstring; - } + function NoNullString($nullterminatedstring) { + // remove the single null terminator on null terminated strings + if (substr($nullterminatedstring, strlen($nullterminatedstring) - 1, 1) === chr(0)) { + return substr($nullterminatedstring, 0, strlen($nullterminatedstring) - 1); + } + return $nullterminatedstring; + } } if (!function_exists('FileSizeNiceDisplay')) { - function FileSizeNiceDisplay($filesize, $precision = 2) - { - if ($filesize < 1000) { - $sizeunit = 'bytes'; - $precision = 0; - } else { - $filesize /= 1024; - $sizeunit = 'kB'; - } - if ($filesize >= 1000) { - $filesize /= 1024; - $sizeunit = 'MB'; - } - if ($filesize >= 1000) { - $filesize /= 1024; - $sizeunit = 'GB'; - } - return number_format($filesize, $precision).' '.$sizeunit; - } + function FileSizeNiceDisplay($filesize, $precision=2) { + if ($filesize < 1000) { + $sizeunit = 'bytes'; + $precision = 0; + } else { + $filesize /= 1024; + $sizeunit = 'kB'; + } + if ($filesize >= 1000) { + $filesize /= 1024; + $sizeunit = 'MB'; + } + if ($filesize >= 1000) { + $filesize /= 1024; + $sizeunit = 'GB'; + } + return number_format($filesize, $precision).' '.$sizeunit; + } } if (!function_exists('DOStime2UNIXtime')) { - function DOStime2UNIXtime($DOSdate, $DOStime) - { - // wFatDate - // Specifies the MS-DOS date. The date is a packed 16-bit value with the following format: - // Bits Contents - // 0-4 Day of the month (1-31) - // 5-8 Month (1 = January, 2 = February, and so on) - // 9-15 Year offset from 1980 (add 1980 to get actual year) + function DOStime2UNIXtime($DOSdate, $DOStime) { + // wFatDate + // Specifies the MS-DOS date. The date is a packed 16-bit value with the following format: + // Bits Contents + // 0-4 Day of the month (1-31) + // 5-8 Month (1 = January, 2 = February, and so on) + // 9-15 Year offset from 1980 (add 1980 to get actual year) - $UNIXday = ($DOSdate & 0x001F); - $UNIXmonth = (($DOSdate & 0x01E0) >> 5); - $UNIXyear = (($DOSdate & 0xFE00) >> 9) + 1980; + $UNIXday = ($DOSdate & 0x001F); + $UNIXmonth = (($DOSdate & 0x01E0) >> 5); + $UNIXyear = (($DOSdate & 0xFE00) >> 9) + 1980; - // wFatTime - // Specifies the MS-DOS time. The time is a packed 16-bit value with the following format: - // Bits Contents - // 0-4 Second divided by 2 - // 5-10 Minute (0-59) - // 11-15 Hour (0-23 on a 24-hour clock) + // wFatTime + // Specifies the MS-DOS time. The time is a packed 16-bit value with the following format: + // Bits Contents + // 0-4 Second divided by 2 + // 5-10 Minute (0-59) + // 11-15 Hour (0-23 on a 24-hour clock) - $UNIXsecond = ($DOStime & 0x001F) * 2; - $UNIXminute = (($DOStime & 0x07E0) >> 5); - $UNIXhour = (($DOStime & 0xF800) >> 11); + $UNIXsecond = ($DOStime & 0x001F) * 2; + $UNIXminute = (($DOStime & 0x07E0) >> 5); + $UNIXhour = (($DOStime & 0xF800) >> 11); - return mktime($UNIXhour, $UNIXminute, $UNIXsecond, $UNIXmonth, $UNIXday, $UNIXyear); - } + return mktime($UNIXhour, $UNIXminute, $UNIXsecond, $UNIXmonth, $UNIXday, $UNIXyear); + } } if (!function_exists('CreateDeepArray')) { - function CreateDeepArray($ArrayPath, $Separator, $Value) - { - // assigns $Value to a nested array path: - // $foo = CreateDeepArray('/path/to/my', '/', 'file.txt') - // is the same as: - // $foo = array('path'=>array('to'=>'array('my'=>array('file.txt')))); - // or - // $foo['path']['to']['my'] = 'file.txt'; - while ($ArrayPath{0} == $Separator) { - $ArrayPath = substr($ArrayPath, 1); - } - if (($pos = strpos($ArrayPath, $Separator)) !== false) { - $ReturnedArray[substr($ArrayPath, 0, $pos)] = CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value); - } else { - $ReturnedArray["$ArrayPath"] = $Value; - } - return $ReturnedArray; - } + function CreateDeepArray($ArrayPath, $Separator, $Value) { + // assigns $Value to a nested array path: + // $foo = CreateDeepArray('/path/to/my', '/', 'file.txt') + // is the same as: + // $foo = array('path'=>array('to'=>'array('my'=>array('file.txt')))); + // or + // $foo['path']['to']['my'] = 'file.txt'; + while ($ArrayPath{0} == $Separator) { + $ArrayPath = substr($ArrayPath, 1); + } + if (($pos = strpos($ArrayPath, $Separator)) !== false) { + $ReturnedArray[substr($ArrayPath, 0, $pos)] = CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value); + } else { + $ReturnedArray["$ArrayPath"] = $Value; + } + return $ReturnedArray; + } } if (!function_exists('md5_file')) { - // Allan Hansen - // md5_file() exists in PHP 4.2.0. - // The following works under UNIX only, but dies on windows - function md5_file($file) - { - if (substr(php_uname(), 0, 7) == 'Windows') { - die('PHP 4.2.0 or newer required for md5_file()'); - } + // Allan Hansen + // md5_file() exists in PHP 4.2.0. + // The following works under UNIX only, but dies on windows + function md5_file($file) { + if (substr(php_uname(), 0, 7) == 'Windows') { + die('PHP 4.2.0 or newer required for md5_file()'); + } - $file = str_replace('`', '\\`', $file); - if (preg_match("#^([0-9a-f]{32})[ \t\n\r]#i", `md5sum "$file"`, $r)) { - return $r[1]; - } - return false; - } + $file = str_replace('`', '\\`', $file); + if (preg_match("#^([0-9a-f]{32})[ \t\n\r]#i", `md5sum "$file"`, $r)) { + return $r[1]; + } + return false; + } } if (!function_exists('md5_data')) { - // Allan Hansen - // md5_data() - returns md5sum for a file from startuing position to absolute end position + // Allan Hansen + // md5_data() - returns md5sum for a file from startuing position to absolute end position - function md5_data($file, $offset, $end, $invertsign = false) - { - // first try and create a temporary file in the same directory as the file being scanned - if (($dataMD5filename = tempnam(dirname($file), preg_replace('#[^[:alnum:]]#i', '', basename($file)))) === false) { - // if that fails, create a temporary file in the system temp directory - if (($dataMD5filename = tempnam('/tmp', 'getID3')) === false) { - // if that fails, create a temporary file in the current directory - if (($dataMD5filename = tempnam('.', preg_replace('#[^[:alnum:]]#i', '', basename($file)))) === false) { - // can't find anywhere to create a temp file, just die - return false; - } - } - } - $md5 = false; - set_time_limit(max(filesize($file) / 1000000, 30)); + function md5_data($file, $offset, $end, $invertsign=false) { + // first try and create a temporary file in the same directory as the file being scanned + if (($dataMD5filename = tempnam(dirname($file), preg_replace('#[^[:alnum:]]#i', '', basename($file)))) === false) { + // if that fails, create a temporary file in the system temp directory + if (($dataMD5filename = tempnam('/tmp', 'getID3')) === false) { + // if that fails, create a temporary file in the current directory + if (($dataMD5filename = tempnam('.', preg_replace('#[^[:alnum:]]#i', '', basename($file)))) === false) { + // can't find anywhere to create a temp file, just die + return false; + } + } + } + $md5 = false; + set_time_limit(max(filesize($file) / 1000000, 30)); - // copy parts of file - ob_start(); - if ($fp = fopen($file, 'rb')) { - ob_end_clean(); + // copy parts of file + ob_start(); + if ($fp = fopen($file, 'rb')) { + ob_end_clean(); - ob_start(); - if ($MD5fp = fopen($dataMD5filename, 'wb')) { - ob_end_clean(); - if ($invertsign) { - // Load conversion lookup strings for 8-bit unsigned->signed conversion below - $from = ''; - $to = ''; - for ($i = 0; $i < 128; $i++) { - $from .= chr($i); - $to .= chr($i + 128); - } - for ($i = 128; $i < 256; $i++) { - $from .= chr($i); - $to .= chr($i - 128); - } - } + ob_start(); + if ($MD5fp = fopen($dataMD5filename, 'wb')) { - fseek($fp, $offset, SEEK_SET); - $byteslefttowrite = $end - $offset; - while (($byteslefttowrite > 0) && ($buffer = fread($fp, 32768))) { - if ($invertsign) { - // Possibly FLAC-specific (?) - // FLAC calculates the MD5sum of the source data of 8-bit files - // not on the actual byte values in the source file, but of those - // values converted from unsigned to signed, or more specifcally, - // with the MSB inverted. ex: 01 -> 81; F5 -> 75; etc + ob_end_clean(); + if ($invertsign) { + // Load conversion lookup strings for 8-bit unsigned->signed conversion below + $from = ''; + $to = ''; + for ($i = 0; $i < 128; $i++) { + $from .= chr($i); + $to .= chr($i + 128); + } + for ($i = 128; $i < 256; $i++) { + $from .= chr($i); + $to .= chr($i - 128); + } + } - // Therefore, 8-bit WAV data has to be converted before getting the - // md5_data value so as to match the FLAC value + fseek($fp, $offset, SEEK_SET); + $byteslefttowrite = $end - $offset; + while (($byteslefttowrite > 0) && ($buffer = fread($fp, 32768))) { + if ($invertsign) { + // Possibly FLAC-specific (?) + // FLAC calculates the MD5sum of the source data of 8-bit files + // not on the actual byte values in the source file, but of those + // values converted from unsigned to signed, or more specifcally, + // with the MSB inverted. ex: 01 -> 81; F5 -> 75; etc - // Flip the MSB for each byte in the buffer before copying - $buffer = strtr($buffer, $from, $to); - } - $byteswritten = fwrite($MD5fp, $buffer, $byteslefttowrite); - $byteslefttowrite -= $byteswritten; - } - fclose($MD5fp); - $md5 = md5_file($dataMD5filename); - } else { - $errormessage = ob_get_contents(); - ob_end_clean(); - } - fclose($fp); - } else { - $errormessage = ob_get_contents(); - ob_end_clean(); - } - unlink($dataMD5filename); - return $md5; - } + // Therefore, 8-bit WAV data has to be converted before getting the + // md5_data value so as to match the FLAC value + + // Flip the MSB for each byte in the buffer before copying + $buffer = strtr($buffer, $from, $to); + } + $byteswritten = fwrite($MD5fp, $buffer, $byteslefttowrite); + $byteslefttowrite -= $byteswritten; + } + fclose($MD5fp); + $md5 = md5_file($dataMD5filename); + + } else { + $errormessage = ob_get_contents(); + ob_end_clean(); + } + fclose($fp); + + } else { + $errormessage = ob_get_contents(); + ob_end_clean(); + } + unlink($dataMD5filename); + return $md5; + } } if (!function_exists('TwosCompliment2Decimal')) { - function TwosCompliment2Decimal($BinaryValue) - { - // http://sandbox.mc.edu/~bennet/cs110/tc/tctod.html - // First check if the number is negative or positive by looking at the sign bit. - // If it is positive, simply convert it to decimal. - // If it is negative, make it positive by inverting the bits and adding one. - // Then, convert the result to decimal. - // The negative of this number is the value of the original binary. + function TwosCompliment2Decimal($BinaryValue) { + // http://sandbox.mc.edu/~bennet/cs110/tc/tctod.html + // First check if the number is negative or positive by looking at the sign bit. + // If it is positive, simply convert it to decimal. + // If it is negative, make it positive by inverting the bits and adding one. + // Then, convert the result to decimal. + // The negative of this number is the value of the original binary. - if ($BinaryValue & 0x80) { - // negative number - return (0 - ((~$BinaryValue & 0xFF) + 1)); - } else { - // positive number - return $BinaryValue; - } - } + if ($BinaryValue & 0x80) { + + // negative number + return (0 - ((~$BinaryValue & 0xFF) + 1)); + + } else { + + // positive number + return $BinaryValue; + + } + + } } if (!function_exists('LastArrayElement')) { - function LastArrayElement($MyArray) - { - if (!is_array($MyArray)) { - return false; - } - if (empty($MyArray)) { - return null; - } - foreach ($MyArray as $key => $value) { - } - return $value; - } + function LastArrayElement($MyArray) { + if (!is_array($MyArray)) { + return false; + } + if (empty($MyArray)) { + return null; + } + foreach ($MyArray as $key => $value) { + } + return $value; + } } if (!function_exists('safe_inc')) { - function safe_inc(&$variable, $increment = 1) - { - if (isset($variable)) { - $variable += $increment; - } else { - $variable = $increment; - } - return true; - } + function safe_inc(&$variable, $increment=1) { + if (isset($variable)) { + $variable += $increment; + } else { + $variable = $increment; + } + return true; + } } if (!function_exists('CalculateCompressionRatioVideo')) { - function CalculateCompressionRatioVideo(&$ThisFileInfo) - { - if (empty($ThisFileInfo['video'])) { - return false; - } - if (empty($ThisFileInfo['video']['resolution_x']) || empty($ThisFileInfo['video']['resolution_y'])) { - return false; - } - if (empty($ThisFileInfo['video']['bits_per_sample'])) { - return false; - } + function CalculateCompressionRatioVideo(&$ThisFileInfo) { + if (empty($ThisFileInfo['video'])) { + return false; + } + if (empty($ThisFileInfo['video']['resolution_x']) || empty($ThisFileInfo['video']['resolution_y'])) { + return false; + } + if (empty($ThisFileInfo['video']['bits_per_sample'])) { + return false; + } - switch ($ThisFileInfo['video']['dataformat']) { - case 'bmp': - case 'gif': - case 'jpeg': - case 'jpg': - case 'png': - case 'tiff': - $FrameRate = 1; - $PlaytimeSeconds = 1; - $BitrateCompressed = $ThisFileInfo['filesize'] * 8; - break; + switch ($ThisFileInfo['video']['dataformat']) { + case 'bmp': + case 'gif': + case 'jpeg': + case 'jpg': + case 'png': + case 'tiff': + $FrameRate = 1; + $PlaytimeSeconds = 1; + $BitrateCompressed = $ThisFileInfo['filesize'] * 8; + break; - default: - if (!empty($ThisFileInfo['video']['frame_rate'])) { - $FrameRate = $ThisFileInfo['video']['frame_rate']; - } else { - return false; - } - if (!empty($ThisFileInfo['playtime_seconds'])) { - $PlaytimeSeconds = $ThisFileInfo['playtime_seconds']; - } else { - return false; - } - if (!empty($ThisFileInfo['video']['bitrate'])) { - $BitrateCompressed = $ThisFileInfo['video']['bitrate']; - } else { - return false; - } - break; - } - $BitrateUncompressed = $ThisFileInfo['video']['resolution_x'] * $ThisFileInfo['video']['resolution_y'] * $ThisFileInfo['video']['bits_per_sample'] * $FrameRate; + default: + if (!empty($ThisFileInfo['video']['frame_rate'])) { + $FrameRate = $ThisFileInfo['video']['frame_rate']; + } else { + return false; + } + if (!empty($ThisFileInfo['playtime_seconds'])) { + $PlaytimeSeconds = $ThisFileInfo['playtime_seconds']; + } else { + return false; + } + if (!empty($ThisFileInfo['video']['bitrate'])) { + $BitrateCompressed = $ThisFileInfo['video']['bitrate']; + } else { + return false; + } + break; + } + $BitrateUncompressed = $ThisFileInfo['video']['resolution_x'] * $ThisFileInfo['video']['resolution_y'] * $ThisFileInfo['video']['bits_per_sample'] * $FrameRate; - $ThisFileInfo['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed; - return true; - } + $ThisFileInfo['video']['compression_ratio'] = $BitrateCompressed / $BitrateUncompressed; + return true; + } } if (!function_exists('CalculateCompressionRatioAudio')) { - function CalculateCompressionRatioAudio(&$ThisFileInfo) - { - if (empty($ThisFileInfo['audio']['bitrate']) || empty($ThisFileInfo['audio']['channels']) || empty($ThisFileInfo['audio']['sample_rate']) || empty($ThisFileInfo['audio']['bits_per_sample'])) { - return false; - } - $ThisFileInfo['audio']['compression_ratio'] = $ThisFileInfo['audio']['bitrate'] / ($ThisFileInfo['audio']['channels'] * $ThisFileInfo['audio']['sample_rate'] * $ThisFileInfo['audio']['bits_per_sample']); - return true; - } + function CalculateCompressionRatioAudio(&$ThisFileInfo) { + if (empty($ThisFileInfo['audio']['bitrate']) || empty($ThisFileInfo['audio']['channels']) || empty($ThisFileInfo['audio']['sample_rate']) || empty($ThisFileInfo['audio']['bits_per_sample'])) { + return false; + } + $ThisFileInfo['audio']['compression_ratio'] = $ThisFileInfo['audio']['bitrate'] / ($ThisFileInfo['audio']['channels'] * $ThisFileInfo['audio']['sample_rate'] * $ThisFileInfo['audio']['bits_per_sample']); + return true; + } } if (!function_exists('IsValidMIMEstring')) { - function IsValidMIMEstring($mimestring) - { - if ((strlen($mimestring) >= 3) && (strpos($mimestring, '/') > 0) && (strpos($mimestring, '/') < (strlen($mimestring) - 1))) { - return true; - } - return false; - } + function IsValidMIMEstring($mimestring) { + if ((strlen($mimestring) >= 3) && (strpos($mimestring, '/') > 0) && (strpos($mimestring, '/') < (strlen($mimestring) - 1))) { + return true; + } + return false; + } } if (!function_exists('IsWithinBitRange')) { - function IsWithinBitRange($number, $maxbits, $signed = false) - { - if ($signed) { - if (($number > (0 - pow(2, $maxbits - 1))) && ($number <= pow(2, $maxbits - 1))) { - return true; - } - } else { - if (($number >= 0) && ($number <= pow(2, $maxbits))) { - return true; - } - } - return false; - } + function IsWithinBitRange($number, $maxbits, $signed=false) { + if ($signed) { + if (($number > (0 - pow(2, $maxbits - 1))) && ($number <= pow(2, $maxbits - 1))) { + return true; + } + } else { + if (($number >= 0) && ($number <= pow(2, $maxbits))) { + return true; + } + } + return false; + } } if (!function_exists('safe_parse_url')) { - function safe_parse_url($url) - { - ob_start(); - $parts = parse_url($url); - $errormessage = ob_get_contents(); - ob_end_clean(); - $parts['scheme'] = (isset($parts['scheme']) ? $parts['scheme'] : ''); - $parts['host'] = (isset($parts['host']) ? $parts['host'] : ''); - $parts['user'] = (isset($parts['user']) ? $parts['user'] : ''); - $parts['pass'] = (isset($parts['pass']) ? $parts['pass'] : ''); - $parts['path'] = (isset($parts['path']) ? $parts['path'] : ''); - $parts['query'] = (isset($parts['query']) ? $parts['query'] : ''); - return $parts; - } + function safe_parse_url($url) { + ob_start(); + $parts = parse_url($url); + $errormessage = ob_get_contents(); + ob_end_clean(); + $parts['scheme'] = (isset($parts['scheme']) ? $parts['scheme'] : ''); + $parts['host'] = (isset($parts['host']) ? $parts['host'] : ''); + $parts['user'] = (isset($parts['user']) ? $parts['user'] : ''); + $parts['pass'] = (isset($parts['pass']) ? $parts['pass'] : ''); + $parts['path'] = (isset($parts['path']) ? $parts['path'] : ''); + $parts['query'] = (isset($parts['query']) ? $parts['query'] : ''); + return $parts; + } } if (!function_exists('IsValidURL')) { - function IsValidURL($url, $allowUserPass = false) - { - if ($url == '') { - return false; - } - if ($allowUserPass !== true) { - if (strstr($url, '@')) { - // in the format http://user:pass@example.com or http://user@example.com - // but could easily be somebody incorrectly entering an email address in place of a URL - return false; - } - } - if ($parts = safe_parse_url($url)) { - if (($parts['scheme'] != 'http') && ($parts['scheme'] != 'https') && ($parts['scheme'] != 'ftp') && ($parts['scheme'] != 'gopher')) { - return false; - } elseif (!preg_match("#^[[:alnum:]]([-.]?[0-9a-z])*\.[a-z]{2,3}#i$", $parts['host'], $regs) && !preg_match('#^[0-9]{1,3}(\.[0-9]{1,3}){3}$#', $parts['host'])) { - return false; - } elseif (!preg_match("#^([[:alnum:]-]|[\_])*$#i", $parts['user'], $regs)) { - return false; - } elseif (!preg_match("#^([[:alnum:]-]|[\_])*$#i", $parts['pass'], $regs)) { - return false; - } elseif (!preg_match("#^[[:alnum:]/_\.@~-]*$#i", $parts['path'], $regs)) { - return false; - } elseif (!preg_match("#^[[:alnum:]?&=+:;_()%#/,\.-]*$#i", $parts['query'], $regs)) { - return false; - } else { - return true; - } - } - return false; - } + function IsValidURL($url, $allowUserPass=false) { + if ($url == '') { + return false; + } + if ($allowUserPass !== true) { + if (strstr($url, '@')) { + // in the format http://user:pass@example.com or http://user@example.com + // but could easily be somebody incorrectly entering an email address in place of a URL + return false; + } + } + if ($parts = safe_parse_url($url)) { + if (($parts['scheme'] != 'http') && ($parts['scheme'] != 'https') && ($parts['scheme'] != 'ftp') && ($parts['scheme'] != 'gopher')) { + return false; + } elseif (!preg_match("#^[[:alnum:]]([-.]?[0-9a-z])*\.[a-z]{2,3}#i$", $parts['host'], $regs) && !preg_match('#^[0-9]{1,3}(\.[0-9]{1,3}){3}$#', $parts['host'])) { + return false; + } elseif (!preg_match("#^([[:alnum:]-]|[\_])*$#i", $parts['user'], $regs)) { + return false; + } elseif (!preg_match("#^([[:alnum:]-]|[\_])*$#i", $parts['pass'], $regs)) { + return false; + } elseif (!preg_match("#^[[:alnum:]/_\.@~-]*$#i", $parts['path'], $regs)) { + return false; + } elseif (!preg_match("#^[[:alnum:]?&=+:;_()%#/,\.-]*$#i", $parts['query'], $regs)) { + return false; + } else { + return true; + } + } + return false; + } } echo '
'; @@ -1412,31 +1356,31 @@ echo ''; -$MPEGgenerateValues = [ - 'version'=>['1', '2', '2.5'], - 'layer'=>['I', 'II', 'III'], - 'protection'=>['Y', 'N'], - 'bitrate'=>['free', '8', '16', '24', '32', '40', '48', '56', '64', '80', '96', '112', '128', '144', '160', '176', '192', '224', '256', '288', '320', '352', '384', '416', '448'], - 'frequency'=>['8000', '11025', '12000', '16000', '22050', '24000', '32000', '44100', '48000'], - 'padding'=>['Y', 'N'], - 'private'=>['Y', 'N'], - 'channelmode'=>['stereo', 'joint stereo', 'dual channel', 'mono'], - 'modeextension'=>['none', 'IS', 'MS', 'IS+MS', '4-31', '8-31', '12-31', '16-31'], - 'copyright'=>['Y', 'N'], - 'original'=>['Y', 'N'], - 'emphasis'=>['none', '50/15ms', 'CCIT J.17'] - ]; +$MPEGgenerateValues = array( + 'version'=>array('1', '2', '2.5'), + 'layer'=>array('I', 'II', 'III'), + 'protection'=>array('Y', 'N'), + 'bitrate'=>array('free', '8', '16', '24', '32', '40', '48', '56', '64', '80', '96', '112', '128', '144', '160', '176', '192', '224', '256', '288', '320', '352', '384', '416', '448'), + 'frequency'=>array('8000', '11025', '12000', '16000', '22050', '24000', '32000', '44100', '48000'), + 'padding'=>array('Y', 'N'), + 'private'=>array('Y', 'N'), + 'channelmode'=>array('stereo', 'joint stereo', 'dual channel', 'mono'), + 'modeextension'=>array('none', 'IS', 'MS', 'IS+MS', '4-31', '8-31', '12-31', '16-31'), + 'copyright'=>array('Y', 'N'), + 'original'=>array('Y', 'N'), + 'emphasis'=>array('none', '50/15ms', 'CCIT J.17') + ); foreach ($MPEGgenerateValues as $name => $dataarray) { - echo ''.$name.':'; + echo ''.$name.':'; } if (isset($_POST['bitrate'])) { - echo 'Frame Length:'.(int) MPEGaudioFrameLength($_POST['bitrate'], $_POST['version'], $_POST['layer'], (($_POST['padding'] == 'Y') ? '1' : '0'), $_POST['frequency']).''; + echo 'Frame Length:'.(int) MPEGaudioFrameLength($_POST['bitrate'], $_POST['version'], $_POST['layer'], (($_POST['padding'] == 'Y') ? '1' : '0'), $_POST['frequency']).''; } echo ''; echo '
'; @@ -1444,185 +1388,185 @@ echo '
'; if (isset($_POST['Analyze']) && $_POST['HeaderHexBytes']) { - $headerbytearray = explode(' ', $_POST['HeaderHexBytes']); - if (count($headerbytearray) != 4) { - die('Invalid byte pattern'); - } - $headerstring = ''; - foreach ($headerbytearray as $textbyte) { - $headerstring .= chr(hexdec($textbyte)); - } - $MP3fileInfo['error'] = ''; + $headerbytearray = explode(' ', $_POST['HeaderHexBytes']); + if (count($headerbytearray) != 4) { + die('Invalid byte pattern'); + } + $headerstring = ''; + foreach ($headerbytearray as $textbyte) { + $headerstring .= chr(hexdec($textbyte)); + } - $MPEGheaderRawArray = MPEGaudioHeaderDecode(substr($headerstring, 0, 4)); + $MP3fileInfo['error'] = ''; - if (MPEGaudioHeaderValid($MPEGheaderRawArray, true)) { - $MP3fileInfo['raw'] = $MPEGheaderRawArray; + $MPEGheaderRawArray = MPEGaudioHeaderDecode(substr($headerstring, 0, 4)); - $MP3fileInfo['version'] = MPEGaudioVersionLookup($MP3fileInfo['raw']['version']); - $MP3fileInfo['layer'] = MPEGaudioLayerLookup($MP3fileInfo['raw']['layer']); - $MP3fileInfo['protection'] = MPEGaudioCRCLookup($MP3fileInfo['raw']['protection']); - $MP3fileInfo['bitrate'] = MPEGaudioBitrateLookup($MP3fileInfo['version'], $MP3fileInfo['layer'], $MP3fileInfo['raw']['bitrate']); - $MP3fileInfo['frequency'] = MPEGaudioFrequencyLookup($MP3fileInfo['version'], $MP3fileInfo['raw']['sample_rate']); - $MP3fileInfo['padding'] = (bool) $MP3fileInfo['raw']['padding']; - $MP3fileInfo['private'] = (bool) $MP3fileInfo['raw']['private']; - $MP3fileInfo['channelmode'] = MPEGaudioChannelModeLookup($MP3fileInfo['raw']['channelmode']); - $MP3fileInfo['channels'] = (($MP3fileInfo['channelmode'] == 'mono') ? 1 : 2); - $MP3fileInfo['modeextension'] = MPEGaudioModeExtensionLookup($MP3fileInfo['layer'], $MP3fileInfo['raw']['modeextension']); - $MP3fileInfo['copyright'] = (bool) $MP3fileInfo['raw']['copyright']; - $MP3fileInfo['original'] = (bool) $MP3fileInfo['raw']['original']; - $MP3fileInfo['emphasis'] = MPEGaudioEmphasisLookup($MP3fileInfo['raw']['emphasis']); + if (MPEGaudioHeaderValid($MPEGheaderRawArray, true)) { - if ($MP3fileInfo['protection']) { - $MP3fileInfo['crc'] = BigEndian2Int(substr($headerstring, 4, 2)); - } + $MP3fileInfo['raw'] = $MPEGheaderRawArray; - if ($MP3fileInfo['frequency'] > 0) { - $MP3fileInfo['framelength'] = MPEGaudioFrameLength($MP3fileInfo['bitrate'], $MP3fileInfo['version'], $MP3fileInfo['layer'], (int) $MP3fileInfo['padding'], $MP3fileInfo['frequency']); - } - if ($MP3fileInfo['bitrate'] != 'free') { - $MP3fileInfo['bitrate'] *= 1000; - } - } else { - $MP3fileInfo['error'] .= "\n".'Invalid MPEG audio header'; - } + $MP3fileInfo['version'] = MPEGaudioVersionLookup($MP3fileInfo['raw']['version']); + $MP3fileInfo['layer'] = MPEGaudioLayerLookup($MP3fileInfo['raw']['layer']); + $MP3fileInfo['protection'] = MPEGaudioCRCLookup($MP3fileInfo['raw']['protection']); + $MP3fileInfo['bitrate'] = MPEGaudioBitrateLookup($MP3fileInfo['version'], $MP3fileInfo['layer'], $MP3fileInfo['raw']['bitrate']); + $MP3fileInfo['frequency'] = MPEGaudioFrequencyLookup($MP3fileInfo['version'], $MP3fileInfo['raw']['sample_rate']); + $MP3fileInfo['padding'] = (bool) $MP3fileInfo['raw']['padding']; + $MP3fileInfo['private'] = (bool) $MP3fileInfo['raw']['private']; + $MP3fileInfo['channelmode'] = MPEGaudioChannelModeLookup($MP3fileInfo['raw']['channelmode']); + $MP3fileInfo['channels'] = (($MP3fileInfo['channelmode'] == 'mono') ? 1 : 2); + $MP3fileInfo['modeextension'] = MPEGaudioModeExtensionLookup($MP3fileInfo['layer'], $MP3fileInfo['raw']['modeextension']); + $MP3fileInfo['copyright'] = (bool) $MP3fileInfo['raw']['copyright']; + $MP3fileInfo['original'] = (bool) $MP3fileInfo['raw']['original']; + $MP3fileInfo['emphasis'] = MPEGaudioEmphasisLookup($MP3fileInfo['raw']['emphasis']); - if (!$MP3fileInfo['error']) { - unset($MP3fileInfo['error']); - } + if ($MP3fileInfo['protection']) { + $MP3fileInfo['crc'] = BigEndian2Int(substr($headerstring, 4, 2)); + } + + if ($MP3fileInfo['frequency'] > 0) { + $MP3fileInfo['framelength'] = MPEGaudioFrameLength($MP3fileInfo['bitrate'], $MP3fileInfo['version'], $MP3fileInfo['layer'], (int) $MP3fileInfo['padding'], $MP3fileInfo['frequency']); + } + if ($MP3fileInfo['bitrate'] != 'free') { + $MP3fileInfo['bitrate'] *= 1000; + } + + } else { + + $MP3fileInfo['error'] .= "\n".'Invalid MPEG audio header'; + + } + + if (!$MP3fileInfo['error']) { + unset($MP3fileInfo['error']); + } + + echo table_var_dump($MP3fileInfo); - echo table_var_dump($MP3fileInfo); } elseif (isset($_POST['Generate'])) { - // AAAA AAAA AAAB BCCD EEEE FFGH IIJJ KLMM - $headerbitstream = '11111111111'; // A - Frame sync (all bits set) + // AAAA AAAA AAAB BCCD EEEE FFGH IIJJ KLMM - $MPEGversionLookup = ['2.5'=>'00', '2'=>'10', '1'=>'11']; - $headerbitstream .= $MPEGversionLookup[$_POST['version']]; // B - MPEG Audio version ID + $headerbitstream = '11111111111'; // A - Frame sync (all bits set) - $MPEGlayerLookup = ['III'=>'01', 'II'=>'10', 'I'=>'11']; - $headerbitstream .= $MPEGlayerLookup[$_POST['layer']]; // C - Layer description + $MPEGversionLookup = array('2.5'=>'00', '2'=>'10', '1'=>'11'); + $headerbitstream .= $MPEGversionLookup[$_POST['version']]; // B - MPEG Audio version ID - $headerbitstream .= (($_POST['protection'] == 'Y') ? '0' : '1'); // D - Protection bit + $MPEGlayerLookup = array('III'=>'01', 'II'=>'10', 'I'=>'11'); + $headerbitstream .= $MPEGlayerLookup[$_POST['layer']]; // C - Layer description - $MPEGaudioBitrateLookup['1']['I'] = ['free'=>'0000', '32'=>'0001', '64'=>'0010', '96'=>'0011', '128'=>'0100', '160'=>'0101', '192'=>'0110', '224'=>'0111', '256'=>'1000', '288'=>'1001', '320'=>'1010', '352'=>'1011', '384'=>'1100', '416'=>'1101', '448'=>'1110']; - $MPEGaudioBitrateLookup['1']['II'] = ['free'=>'0000', '32'=>'0001', '48'=>'0010', '56'=>'0011', '64'=>'0100', '80'=>'0101', '96'=>'0110', '112'=>'0111', '128'=>'1000', '160'=>'1001', '192'=>'1010', '224'=>'1011', '256'=>'1100', '320'=>'1101', '384'=>'1110']; - $MPEGaudioBitrateLookup['1']['III'] = ['free'=>'0000', '32'=>'0001', '40'=>'0010', '48'=>'0011', '56'=>'0100', '64'=>'0101', '80'=>'0110', '96'=>'0111', '112'=>'1000', '128'=>'1001', '160'=>'1010', '192'=>'1011', '224'=>'1100', '256'=>'1101', '320'=>'1110']; - $MPEGaudioBitrateLookup['2']['I'] = ['free'=>'0000', '32'=>'0001', '48'=>'0010', '56'=>'0011', '64'=>'0100', '80'=>'0101', '96'=>'0110', '112'=>'0111', '128'=>'1000', '144'=>'1001', '160'=>'1010', '176'=>'1011', '192'=>'1100', '224'=>'1101', '256'=>'1110']; - $MPEGaudioBitrateLookup['2']['II'] = ['free'=>'0000', '8'=>'0001', '16'=>'0010', '24'=>'0011', '32'=>'0100', '40'=>'0101', '48'=>'0110', '56'=>'0111', '64'=>'1000', '80'=>'1001', '96'=>'1010', '112'=>'1011', '128'=>'1100', '144'=>'1101', '160'=>'1110']; - $MPEGaudioBitrateLookup['2']['III'] = $MPEGaudioBitrateLookup['2']['II']; - $MPEGaudioBitrateLookup['2.5']['I'] = $MPEGaudioBitrateLookup['2']['I']; - $MPEGaudioBitrateLookup['2.5']['II'] = $MPEGaudioBitrateLookup['2']['II']; - $MPEGaudioBitrateLookup['2.5']['III'] = $MPEGaudioBitrateLookup['2']['II']; - if (isset($MPEGaudioBitrateLookup[$_POST['version']][$_POST['layer']][$_POST['bitrate']])) { - $headerbitstream .= $MPEGaudioBitrateLookup[$_POST['version']][$_POST['layer']][$_POST['bitrate']]; // E - Bitrate index - } else { - die('Invalid Bitrate'); - } + $headerbitstream .= (($_POST['protection'] == 'Y') ? '0' : '1'); // D - Protection bit - $MPEGaudioFrequencyLookup['1'] = ['44100'=>'00', '48000'=>'01', '32000'=>'10']; - $MPEGaudioFrequencyLookup['2'] = ['22050'=>'00', '24000'=>'01', '16000'=>'10']; - $MPEGaudioFrequencyLookup['2.5'] = ['11025'=>'00', '12000'=>'01', '8000'=>'10']; - if (isset($MPEGaudioFrequencyLookup[$_POST['version']][$_POST['frequency']])) { - $headerbitstream .= $MPEGaudioFrequencyLookup[$_POST['version']][$_POST['frequency']]; // F - Sampling rate frequency index - } else { - die('Invalid Frequency'); - } + $MPEGaudioBitrateLookup['1']['I'] = array('free'=>'0000', '32'=>'0001', '64'=>'0010', '96'=>'0011', '128'=>'0100', '160'=>'0101', '192'=>'0110', '224'=>'0111', '256'=>'1000', '288'=>'1001', '320'=>'1010', '352'=>'1011', '384'=>'1100', '416'=>'1101', '448'=>'1110'); + $MPEGaudioBitrateLookup['1']['II'] = array('free'=>'0000', '32'=>'0001', '48'=>'0010', '56'=>'0011', '64'=>'0100', '80'=>'0101', '96'=>'0110', '112'=>'0111', '128'=>'1000', '160'=>'1001', '192'=>'1010', '224'=>'1011', '256'=>'1100', '320'=>'1101', '384'=>'1110'); + $MPEGaudioBitrateLookup['1']['III'] = array('free'=>'0000', '32'=>'0001', '40'=>'0010', '48'=>'0011', '56'=>'0100', '64'=>'0101', '80'=>'0110', '96'=>'0111', '112'=>'1000', '128'=>'1001', '160'=>'1010', '192'=>'1011', '224'=>'1100', '256'=>'1101', '320'=>'1110'); + $MPEGaudioBitrateLookup['2']['I'] = array('free'=>'0000', '32'=>'0001', '48'=>'0010', '56'=>'0011', '64'=>'0100', '80'=>'0101', '96'=>'0110', '112'=>'0111', '128'=>'1000', '144'=>'1001', '160'=>'1010', '176'=>'1011', '192'=>'1100', '224'=>'1101', '256'=>'1110'); + $MPEGaudioBitrateLookup['2']['II'] = array('free'=>'0000', '8'=>'0001', '16'=>'0010', '24'=>'0011', '32'=>'0100', '40'=>'0101', '48'=>'0110', '56'=>'0111', '64'=>'1000', '80'=>'1001', '96'=>'1010', '112'=>'1011', '128'=>'1100', '144'=>'1101', '160'=>'1110'); + $MPEGaudioBitrateLookup['2']['III'] = $MPEGaudioBitrateLookup['2']['II']; + $MPEGaudioBitrateLookup['2.5']['I'] = $MPEGaudioBitrateLookup['2']['I']; + $MPEGaudioBitrateLookup['2.5']['II'] = $MPEGaudioBitrateLookup['2']['II']; + $MPEGaudioBitrateLookup['2.5']['III'] = $MPEGaudioBitrateLookup['2']['II']; + if (isset($MPEGaudioBitrateLookup[$_POST['version']][$_POST['layer']][$_POST['bitrate']])) { + $headerbitstream .= $MPEGaudioBitrateLookup[$_POST['version']][$_POST['layer']][$_POST['bitrate']]; // E - Bitrate index + } else { + die('Invalid Bitrate'); + } - $headerbitstream .= (($_POST['padding'] == 'Y') ? '1' : '0'); // G - Padding bit + $MPEGaudioFrequencyLookup['1'] = array('44100'=>'00', '48000'=>'01', '32000'=>'10'); + $MPEGaudioFrequencyLookup['2'] = array('22050'=>'00', '24000'=>'01', '16000'=>'10'); + $MPEGaudioFrequencyLookup['2.5'] = array('11025'=>'00', '12000'=>'01', '8000'=>'10'); + if (isset($MPEGaudioFrequencyLookup[$_POST['version']][$_POST['frequency']])) { + $headerbitstream .= $MPEGaudioFrequencyLookup[$_POST['version']][$_POST['frequency']]; // F - Sampling rate frequency index + } else { + die('Invalid Frequency'); + } - $headerbitstream .= (($_POST['private'] == 'Y') ? '1' : '0'); // H - Private bit + $headerbitstream .= (($_POST['padding'] == 'Y') ? '1' : '0'); // G - Padding bit - $MPEGaudioChannelModeLookup = ['stereo'=>'00', 'joint stereo'=>'01', 'dual channel'=>'10', 'mono'=>'11']; - $headerbitstream .= $MPEGaudioChannelModeLookup[$_POST['channelmode']]; // I - Channel Mode + $headerbitstream .= (($_POST['private'] == 'Y') ? '1' : '0'); // H - Private bit - $MPEGaudioModeExtensionLookup['I'] = ['4-31'=>'00', '8-31'=>'01', '12-31'=>'10', '16-31'=>'11']; - $MPEGaudioModeExtensionLookup['II'] = $MPEGaudioModeExtensionLookup['I']; - $MPEGaudioModeExtensionLookup['III'] = ['none'=>'00', 'IS'=>'01', 'MS'=>'10', 'IS+MS'=>'11']; - if ($_POST['channelmode'] != 'joint stereo') { - $headerbitstream .= '00'; - } elseif (isset($MPEGaudioModeExtensionLookup[$_POST['layer']][$_POST['modeextension']])) { - $headerbitstream .= $MPEGaudioModeExtensionLookup[$_POST['layer']][$_POST['modeextension']]; // J - Mode extension (Only if Joint stereo) - } else { - die('Invalid Mode Extension'); - } + $MPEGaudioChannelModeLookup = array('stereo'=>'00', 'joint stereo'=>'01', 'dual channel'=>'10', 'mono'=>'11'); + $headerbitstream .= $MPEGaudioChannelModeLookup[$_POST['channelmode']]; // I - Channel Mode - $headerbitstream .= (($_POST['copyright'] == 'Y') ? '1' : '0'); // K - Copyright + $MPEGaudioModeExtensionLookup['I'] = array('4-31'=>'00', '8-31'=>'01', '12-31'=>'10', '16-31'=>'11'); + $MPEGaudioModeExtensionLookup['II'] = $MPEGaudioModeExtensionLookup['I']; + $MPEGaudioModeExtensionLookup['III'] = array('none'=>'00', 'IS'=>'01', 'MS'=>'10', 'IS+MS'=>'11'); + if ($_POST['channelmode'] != 'joint stereo') { + $headerbitstream .= '00'; + } elseif (isset($MPEGaudioModeExtensionLookup[$_POST['layer']][$_POST['modeextension']])) { + $headerbitstream .= $MPEGaudioModeExtensionLookup[$_POST['layer']][$_POST['modeextension']]; // J - Mode extension (Only if Joint stereo) + } else { + die('Invalid Mode Extension'); + } - $headerbitstream .= (($_POST['original'] == 'Y') ? '1' : '0'); // L - Original + $headerbitstream .= (($_POST['copyright'] == 'Y') ? '1' : '0'); // K - Copyright - $MPEGaudioEmphasisLookup = ['none'=>'00', '50/15ms'=>'01', 'CCIT J.17'=>'11']; - if (isset($MPEGaudioEmphasisLookup[$_POST['emphasis']])) { - $headerbitstream .= $MPEGaudioEmphasisLookup[$_POST['emphasis']]; // M - Emphasis - } else { - die('Invalid Emphasis'); - } + $headerbitstream .= (($_POST['original'] == 'Y') ? '1' : '0'); // L - Original + + $MPEGaudioEmphasisLookup = array('none'=>'00', '50/15ms'=>'01', 'CCIT J.17'=>'11'); + if (isset($MPEGaudioEmphasisLookup[$_POST['emphasis']])) { + $headerbitstream .= $MPEGaudioEmphasisLookup[$_POST['emphasis']]; // M - Emphasis + } else { + die('Invalid Emphasis'); + } + + echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 0, 8))), 2, '0', STR_PAD_LEFT)).' '; + echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 8, 8))), 2, '0', STR_PAD_LEFT)).' '; + echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 16, 8))), 2, '0', STR_PAD_LEFT)).' '; + echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 24, 8))), 2, '0', STR_PAD_LEFT)).'
'; - echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 0, 8))), 2, '0', STR_PAD_LEFT)).' '; - echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 8, 8))), 2, '0', STR_PAD_LEFT)).' '; - echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 16, 8))), 2, '0', STR_PAD_LEFT)).' '; - echo strtoupper(str_pad(dechex(bindec(substr($headerbitstream, 24, 8))), 2, '0', STR_PAD_LEFT)).'
'; } -function MPEGaudioVersionLookup($rawversion) -{ - $MPEGaudioVersionLookup = ['2.5', false, '2', '1']; - return (isset($MPEGaudioVersionLookup["$rawversion"]) ? $MPEGaudioVersionLookup["$rawversion"] : false); +function MPEGaudioVersionLookup($rawversion) { + $MPEGaudioVersionLookup = array('2.5', FALSE, '2', '1'); + return (isset($MPEGaudioVersionLookup["$rawversion"]) ? $MPEGaudioVersionLookup["$rawversion"] : FALSE); } -function MPEGaudioLayerLookup($rawlayer) -{ - $MPEGaudioLayerLookup = [false, 'III', 'II', 'I']; - return (isset($MPEGaudioLayerLookup["$rawlayer"]) ? $MPEGaudioLayerLookup["$rawlayer"] : false); +function MPEGaudioLayerLookup($rawlayer) { + $MPEGaudioLayerLookup = array(FALSE, 'III', 'II', 'I'); + return (isset($MPEGaudioLayerLookup["$rawlayer"]) ? $MPEGaudioLayerLookup["$rawlayer"] : FALSE); } -function MPEGaudioBitrateLookup($version, $layer, $rawbitrate) -{ - static $MPEGaudioBitrateLookup; - if (empty($MPEGaudioBitrateLookup)) { - $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); - } - return (isset($MPEGaudioBitrateLookup["$version"]["$layer"]["$rawbitrate"]) ? $MPEGaudioBitrateLookup["$version"]["$layer"]["$rawbitrate"] : false); +function MPEGaudioBitrateLookup($version, $layer, $rawbitrate) { + static $MPEGaudioBitrateLookup; + if (empty($MPEGaudioBitrateLookup)) { + $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); + } + return (isset($MPEGaudioBitrateLookup["$version"]["$layer"]["$rawbitrate"]) ? $MPEGaudioBitrateLookup["$version"]["$layer"]["$rawbitrate"] : FALSE); } -function MPEGaudioFrequencyLookup($version, $rawfrequency) -{ - static $MPEGaudioFrequencyLookup; - if (empty($MPEGaudioFrequencyLookup)) { - $MPEGaudioFrequencyLookup = MPEGaudioFrequencyArray(); - } - return (isset($MPEGaudioFrequencyLookup["$version"]["$rawfrequency"]) ? $MPEGaudioFrequencyLookup["$version"]["$rawfrequency"] : false); +function MPEGaudioFrequencyLookup($version, $rawfrequency) { + static $MPEGaudioFrequencyLookup; + if (empty($MPEGaudioFrequencyLookup)) { + $MPEGaudioFrequencyLookup = MPEGaudioFrequencyArray(); + } + return (isset($MPEGaudioFrequencyLookup["$version"]["$rawfrequency"]) ? $MPEGaudioFrequencyLookup["$version"]["$rawfrequency"] : FALSE); } -function MPEGaudioChannelModeLookup($rawchannelmode) -{ - $MPEGaudioChannelModeLookup = ['stereo', 'joint stereo', 'dual channel', 'mono']; - return (isset($MPEGaudioChannelModeLookup["$rawchannelmode"]) ? $MPEGaudioChannelModeLookup["$rawchannelmode"] : false); +function MPEGaudioChannelModeLookup($rawchannelmode) { + $MPEGaudioChannelModeLookup = array('stereo', 'joint stereo', 'dual channel', 'mono'); + return (isset($MPEGaudioChannelModeLookup["$rawchannelmode"]) ? $MPEGaudioChannelModeLookup["$rawchannelmode"] : FALSE); } -function MPEGaudioModeExtensionLookup($layer, $rawmodeextension) -{ - $MPEGaudioModeExtensionLookup['I'] = ['4-31', '8-31', '12-31', '16-31']; - $MPEGaudioModeExtensionLookup['II'] = ['4-31', '8-31', '12-31', '16-31']; - $MPEGaudioModeExtensionLookup['III'] = ['', 'IS', 'MS', 'IS+MS']; - return (isset($MPEGaudioModeExtensionLookup["$layer"]["$rawmodeextension"]) ? $MPEGaudioModeExtensionLookup["$layer"]["$rawmodeextension"] : false); +function MPEGaudioModeExtensionLookup($layer, $rawmodeextension) { + $MPEGaudioModeExtensionLookup['I'] = array('4-31', '8-31', '12-31', '16-31'); + $MPEGaudioModeExtensionLookup['II'] = array('4-31', '8-31', '12-31', '16-31'); + $MPEGaudioModeExtensionLookup['III'] = array('', 'IS', 'MS', 'IS+MS'); + return (isset($MPEGaudioModeExtensionLookup["$layer"]["$rawmodeextension"]) ? $MPEGaudioModeExtensionLookup["$layer"]["$rawmodeextension"] : FALSE); } -function MPEGaudioEmphasisLookup($rawemphasis) -{ - $MPEGaudioEmphasisLookup = ['none', '50/15ms', false, 'CCIT J.17']; - return (isset($MPEGaudioEmphasisLookup["$rawemphasis"]) ? $MPEGaudioEmphasisLookup["$rawemphasis"] : false); +function MPEGaudioEmphasisLookup($rawemphasis) { + $MPEGaudioEmphasisLookup = array('none', '50/15ms', FALSE, 'CCIT J.17'); + return (isset($MPEGaudioEmphasisLookup["$rawemphasis"]) ? $MPEGaudioEmphasisLookup["$rawemphasis"] : FALSE); } -function MPEGaudioCRCLookup($CRCbit) -{ - // inverse boolean cast :) - if ($CRCbit == '0') { - return true; - } else { - return false; - } +function MPEGaudioCRCLookup($CRCbit) { + // inverse boolean cast :) + if ($CRCbit == '0') { + return TRUE; + } else { + return FALSE; + } } ///////////////////////////////////////////////////////////////// @@ -1642,1267 +1586,1304 @@ function MPEGaudioCRCLookup($CRCbit) // mpeg-audio streams define('MPEG_VALID_CHECK_FRAMES', 35); -function getMP3headerFilepointer(&$fd, &$ThisFileInfo) -{ +function getMP3headerFilepointer(&$fd, &$ThisFileInfo) { - getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $ThisFileInfo['avdataoffset']); + getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $ThisFileInfo['avdataoffset']); - if (isset($ThisFileInfo['mpeg']['audio']['bitrate_mode'])) { - $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']); - } + if (isset($ThisFileInfo['mpeg']['audio']['bitrate_mode'])) { + $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']); + } - if (((isset($ThisFileInfo['id3v2']) && ($ThisFileInfo['avdataoffset'] > $ThisFileInfo['id3v2']['headerlength'])) || (!isset($ThisFileInfo['id3v2']) && ($ThisFileInfo['avdataoffset'] > 0)))) { - $ThisFileInfo['warning'] .= "\n".'Unknown data before synch '; - if (isset($ThisFileInfo['id3v2']['headerlength'])) { - $ThisFileInfo['warning'] .= '(ID3v2 header ends at '.$ThisFileInfo['id3v2']['headerlength'].', then '.($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']).' bytes garbage, '; - } else { - $ThisFileInfo['warning'] .= '(should be at beginning of file, '; - } - $ThisFileInfo['warning'] .= 'synch detected at '.$ThisFileInfo['avdataoffset'].')'; - if ($ThisFileInfo['audio']['bitrate_mode'] == 'cbr') { - if (!empty($ThisFileInfo['id3v2']['headerlength']) && (($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']) == $ThisFileInfo['mpeg']['audio']['framelength'])) { - $ThisFileInfo['warning'] .= '. This is a known problem with some versions of LAME (3.91, 3.92) DLL in CBR mode.'; - $ThisFileInfo['audio']['codec'] = 'LAME'; - } elseif (empty($ThisFileInfo['id3v2']['headerlength']) && ($ThisFileInfo['avdataoffset'] == $ThisFileInfo['mpeg']['audio']['framelength'])) { - $ThisFileInfo['warning'] .= '. This is a known problem with some versions of LAME (3.91, 3.92) DLL in CBR mode.'; - $ThisFileInfo['audio']['codec'] = 'LAME'; - } - } - } + if (((isset($ThisFileInfo['id3v2']) && ($ThisFileInfo['avdataoffset'] > $ThisFileInfo['id3v2']['headerlength'])) || (!isset($ThisFileInfo['id3v2']) && ($ThisFileInfo['avdataoffset'] > 0)))) { - if (isset($ThisFileInfo['mpeg']['audio']['layer']) && ($ThisFileInfo['mpeg']['audio']['layer'] == 'II')) { - $ThisFileInfo['audio']['dataformat'] = 'mp2'; - } elseif (isset($ThisFileInfo['mpeg']['audio']['layer']) && ($ThisFileInfo['mpeg']['audio']['layer'] == 'I')) { - $ThisFileInfo['audio']['dataformat'] = 'mp1'; - } - if ($ThisFileInfo['fileformat'] == 'mp3') { - switch ($ThisFileInfo['audio']['dataformat']) { - case 'mp1': - case 'mp2': - case 'mp3': - $ThisFileInfo['fileformat'] = $ThisFileInfo['audio']['dataformat']; - break; + $ThisFileInfo['warning'] .= "\n".'Unknown data before synch '; + if (isset($ThisFileInfo['id3v2']['headerlength'])) { + $ThisFileInfo['warning'] .= '(ID3v2 header ends at '.$ThisFileInfo['id3v2']['headerlength'].', then '.($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']).' bytes garbage, '; + } else { + $ThisFileInfo['warning'] .= '(should be at beginning of file, '; + } + $ThisFileInfo['warning'] .= 'synch detected at '.$ThisFileInfo['avdataoffset'].')'; + if ($ThisFileInfo['audio']['bitrate_mode'] == 'cbr') { + if (!empty($ThisFileInfo['id3v2']['headerlength']) && (($ThisFileInfo['avdataoffset'] - $ThisFileInfo['id3v2']['headerlength']) == $ThisFileInfo['mpeg']['audio']['framelength'])) { + $ThisFileInfo['warning'] .= '. This is a known problem with some versions of LAME (3.91, 3.92) DLL in CBR mode.'; + $ThisFileInfo['audio']['codec'] = 'LAME'; + } elseif (empty($ThisFileInfo['id3v2']['headerlength']) && ($ThisFileInfo['avdataoffset'] == $ThisFileInfo['mpeg']['audio']['framelength'])) { + $ThisFileInfo['warning'] .= '. This is a known problem with some versions of LAME (3.91, 3.92) DLL in CBR mode.'; + $ThisFileInfo['audio']['codec'] = 'LAME'; + } + } - default: - $ThisFileInfo['warning'] .= "\n".'Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$ThisFileInfo['audio']['dataformat'].'"'; - break; - } - } + } - if (empty($ThisFileInfo['fileformat'])) { - $ThisFileInfo['error'] .= "\n".'Synch not found'; - unset($ThisFileInfo['fileformat']); - unset($ThisFileInfo['audio']['bitrate_mode']); - unset($ThisFileInfo['avdataoffset']); - unset($ThisFileInfo['avdataend']); - return false; - } + if (isset($ThisFileInfo['mpeg']['audio']['layer']) && ($ThisFileInfo['mpeg']['audio']['layer'] == 'II')) { + $ThisFileInfo['audio']['dataformat'] = 'mp2'; + } elseif (isset($ThisFileInfo['mpeg']['audio']['layer']) && ($ThisFileInfo['mpeg']['audio']['layer'] == 'I')) { + $ThisFileInfo['audio']['dataformat'] = 'mp1'; + } + if ($ThisFileInfo['fileformat'] == 'mp3') { + switch ($ThisFileInfo['audio']['dataformat']) { + case 'mp1': + case 'mp2': + case 'mp3': + $ThisFileInfo['fileformat'] = $ThisFileInfo['audio']['dataformat']; + break; - $ThisFileInfo['mime_type'] = 'audio/mpeg'; - $ThisFileInfo['audio']['lossless'] = false; + default: + $ThisFileInfo['warning'] .= "\n".'Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$ThisFileInfo['audio']['dataformat'].'"'; + break; + } + } - // Calculate playtime - if (!isset($ThisFileInfo['playtime_seconds']) && isset($ThisFileInfo['audio']['bitrate']) && ($ThisFileInfo['audio']['bitrate'] > 0)) { - $ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8 / $ThisFileInfo['audio']['bitrate']; - } + if (empty($ThisFileInfo['fileformat'])) { + $ThisFileInfo['error'] .= "\n".'Synch not found'; + unset($ThisFileInfo['fileformat']); + unset($ThisFileInfo['audio']['bitrate_mode']); + unset($ThisFileInfo['avdataoffset']); + unset($ThisFileInfo['avdataend']); + return false; + } - if (isset($ThisFileInfo['mpeg']['audio']['LAME'])) { - $ThisFileInfo['audio']['codec'] = 'LAME'; - if (!empty($ThisFileInfo['mpeg']['audio']['LAME']['long_version'])) { - $ThisFileInfo['audio']['encoder'] = trim($ThisFileInfo['mpeg']['audio']['LAME']['long_version']); - } - } + $ThisFileInfo['mime_type'] = 'audio/mpeg'; + $ThisFileInfo['audio']['lossless'] = false; - return true; + // Calculate playtime + if (!isset($ThisFileInfo['playtime_seconds']) && isset($ThisFileInfo['audio']['bitrate']) && ($ThisFileInfo['audio']['bitrate'] > 0)) { + $ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8 / $ThisFileInfo['audio']['bitrate']; + } + + if (isset($ThisFileInfo['mpeg']['audio']['LAME'])) { + $ThisFileInfo['audio']['codec'] = 'LAME'; + if (!empty($ThisFileInfo['mpeg']['audio']['LAME']['long_version'])) { + $ThisFileInfo['audio']['encoder'] = trim($ThisFileInfo['mpeg']['audio']['LAME']['long_version']); + } + } + + return true; } -function decodeMPEGaudioHeader($fd, $offset, &$ThisFileInfo, $recursivesearch = true, $ScanAsCBR = false, $FastMPEGheaderScan = false) -{ - - static $MPEGaudioVersionLookup; - static $MPEGaudioLayerLookup; - static $MPEGaudioBitrateLookup; - static $MPEGaudioFrequencyLookup; - static $MPEGaudioChannelModeLookup; - static $MPEGaudioModeExtensionLookup; - static $MPEGaudioEmphasisLookup; - if (empty($MPEGaudioVersionLookup)) { - $MPEGaudioVersionLookup = MPEGaudioVersionArray(); - $MPEGaudioLayerLookup = MPEGaudioLayerArray(); - $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); - $MPEGaudioFrequencyLookup = MPEGaudioFrequencyArray(); - $MPEGaudioChannelModeLookup = MPEGaudioChannelModeArray(); - $MPEGaudioModeExtensionLookup = MPEGaudioModeExtensionArray(); - $MPEGaudioEmphasisLookup = MPEGaudioEmphasisArray(); - } - - if ($offset >= $ThisFileInfo['avdataend']) { - $ThisFileInfo['error'] .= "\n".'end of file encounter looking for MPEG synch'; - return false; - } - fseek($fd, $offset, SEEK_SET); - $headerstring = fread($fd, 1441); // worse-case max length = 32kHz @ 320kbps layer 3 = 1441 bytes/frame - - // MP3 audio frame structure: - // $aa $aa $aa $aa [$bb $bb] $cc... - // where $aa..$aa is the four-byte mpeg-audio header (below) - // $bb $bb is the optional 2-byte CRC - // and $cc... is the audio data - - $head4 = substr($headerstring, 0, 4); - - static $MPEGaudioHeaderDecodeCache = []; - if (isset($MPEGaudioHeaderDecodeCache[$head4])) { - $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4]; - } else { - $MPEGheaderRawArray = MPEGaudioHeaderDecode($head4); - $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray; - } - - static $MPEGaudioHeaderValidCache = []; - - // Not in cache - if (!isset($MPEGaudioHeaderValidCache[$head4])) { - $MPEGaudioHeaderValidCache[$head4] = MPEGaudioHeaderValid($MPEGheaderRawArray); - } - - if ($MPEGaudioHeaderValidCache[$head4]) { - $ThisFileInfo['mpeg']['audio']['raw'] = $MPEGheaderRawArray; - } else { - $ThisFileInfo['error'] .= "\n".'Invalid MPEG audio header at offset '.$offset; - return false; - } - - if (!$FastMPEGheaderScan) { - $ThisFileInfo['mpeg']['audio']['version'] = $MPEGaudioVersionLookup[$ThisFileInfo['mpeg']['audio']['raw']['version']]; - $ThisFileInfo['mpeg']['audio']['layer'] = $MPEGaudioLayerLookup[$ThisFileInfo['mpeg']['audio']['raw']['layer']]; - - $ThisFileInfo['mpeg']['audio']['channelmode'] = $MPEGaudioChannelModeLookup[$ThisFileInfo['mpeg']['audio']['raw']['channelmode']]; - $ThisFileInfo['mpeg']['audio']['channels'] = (($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') ? 1 : 2); - $ThisFileInfo['mpeg']['audio']['sample_rate'] = $MPEGaudioFrequencyLookup[$ThisFileInfo['mpeg']['audio']['version']][$ThisFileInfo['mpeg']['audio']['raw']['sample_rate']]; - $ThisFileInfo['mpeg']['audio']['protection'] = !$ThisFileInfo['mpeg']['audio']['raw']['protection']; - $ThisFileInfo['mpeg']['audio']['private'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['private']; - $ThisFileInfo['mpeg']['audio']['modeextension'] = $MPEGaudioModeExtensionLookup[$ThisFileInfo['mpeg']['audio']['layer']][$ThisFileInfo['mpeg']['audio']['raw']['modeextension']]; - $ThisFileInfo['mpeg']['audio']['copyright'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['copyright']; - $ThisFileInfo['mpeg']['audio']['original'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['original']; - $ThisFileInfo['mpeg']['audio']['emphasis'] = $MPEGaudioEmphasisLookup[$ThisFileInfo['mpeg']['audio']['raw']['emphasis']]; - - $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels']; - $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate']; - - if ($ThisFileInfo['mpeg']['audio']['protection']) { - $ThisFileInfo['mpeg']['audio']['crc'] = BigEndian2Int(substr($headerstring, 4, 2)); - } - } - - if ($ThisFileInfo['mpeg']['audio']['raw']['bitrate'] == 15) { - // http://www.hydrogenaudio.org/?act=ST&f=16&t=9682&st=0 - $ThisFileInfo['warning'] .= "\n".'Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1'; - $ThisFileInfo['mpeg']['audio']['raw']['bitrate'] = 0; - } - $ThisFileInfo['mpeg']['audio']['padding'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['padding']; - $ThisFileInfo['mpeg']['audio']['bitrate'] = $MPEGaudioBitrateLookup[$ThisFileInfo['mpeg']['audio']['version']][$ThisFileInfo['mpeg']['audio']['layer']][$ThisFileInfo['mpeg']['audio']['raw']['bitrate']]; - - if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') && ($offset == $ThisFileInfo['avdataoffset'])) { - // only skip multiple frame check if free-format bitstream found at beginning of file - // otherwise is quite possibly simply corrupted data - $recursivesearch = false; - } - - // For Layer II there are some combinations of bitrate and mode which are not allowed. - if (!$FastMPEGheaderScan && ($ThisFileInfo['mpeg']['audio']['layer'] == 'II')) { - $ThisFileInfo['audio']['dataformat'] = 'mp2'; - switch ($ThisFileInfo['mpeg']['audio']['channelmode']) { - case 'mono': - if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') || ($ThisFileInfo['mpeg']['audio']['bitrate'] <= 192)) { - // these are ok - } else { - $ThisFileInfo['error'] .= "\n".$ThisFileInfo['mpeg']['audio']['bitrate'].'kbps not allowed in Layer II, '.$ThisFileInfo['mpeg']['audio']['channelmode'].'.'; - return false; - } - break; - - case 'stereo': - case 'joint stereo': - case 'dual channel': - if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') || ($ThisFileInfo['mpeg']['audio']['bitrate'] == 64) || ($ThisFileInfo['mpeg']['audio']['bitrate'] >= 96)) { - // these are ok - } else { - $ThisFileInfo['error'] .= "\n".$ThisFileInfo['mpeg']['audio']['bitrate'].'kbps not allowed in Layer II, '.$ThisFileInfo['mpeg']['audio']['channelmode'].'.'; - return false; - } - break; - } - } - - - if ($ThisFileInfo['audio']['sample_rate'] > 0) { - $ThisFileInfo['mpeg']['audio']['framelength'] = MPEGaudioFrameLength($ThisFileInfo['mpeg']['audio']['bitrate'], $ThisFileInfo['mpeg']['audio']['version'], $ThisFileInfo['mpeg']['audio']['layer'], (int) $ThisFileInfo['mpeg']['audio']['padding'], $ThisFileInfo['audio']['sample_rate']); - } - - if ($ThisFileInfo['mpeg']['audio']['bitrate'] != 'free') { - $ThisFileInfo['audio']['bitrate'] = 1000 * $ThisFileInfo['mpeg']['audio']['bitrate']; - - if (isset($ThisFileInfo['mpeg']['audio']['framelength'])) { - $nextframetestoffset = $offset + $ThisFileInfo['mpeg']['audio']['framelength']; - } else { - $ThisFileInfo['error'] .= "\n".'Frame at offset('.$offset.') is has an invalid frame length.'; - return false; - } - } - - $ExpectedNumberOfAudioBytes = 0; - - //////////////////////////////////////////////////////////////////////////////////// - // Variable-bitrate headers - - if (substr($headerstring, 4 + 32, 4) == 'VBRI') { - // Fraunhofer VBR header is hardcoded 'VBRI' at offset 0x24 (36) - // specs taken from http://minnie.tuhs.org/pipermail/mp3encoder/2001-January/001800.html - - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; - $ThisFileInfo['mpeg']['audio']['VBR_method'] = 'Fraunhofer'; - $ThisFileInfo['audio']['codec'] = 'Fraunhofer'; - - $SideInfoData = substr($headerstring, 4 + 2, 32); - - $FraunhoferVBROffset = 36; - - $ThisFileInfo['mpeg']['audio']['VBR_encoder_version'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 4, 2)); - $ThisFileInfo['mpeg']['audio']['VBR_encoder_delay'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 6, 2)); - $ThisFileInfo['mpeg']['audio']['VBR_quality'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 8, 2)); - $ThisFileInfo['mpeg']['audio']['VBR_bytes'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 10, 4)); - $ThisFileInfo['mpeg']['audio']['VBR_frames'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 14, 4)); - $ThisFileInfo['mpeg']['audio']['VBR_seek_offsets'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 18, 2)); - //$ThisFileInfo['mpeg']['audio']['reserved'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 20, 4)); // hardcoded $00 $01 $00 $02 - purpose unknown - $ThisFileInfo['mpeg']['audio']['VBR_seek_offsets_stride'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 24, 2)); - - $ExpectedNumberOfAudioBytes = $ThisFileInfo['mpeg']['audio']['VBR_bytes']; - - $previousbyteoffset = $offset; - for ($i = 0; $i < $ThisFileInfo['mpeg']['audio']['VBR_seek_offsets']; $i++) { - $Fraunhofer_OffsetN = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset, 2)); - $FraunhoferVBROffset += 2; - $ThisFileInfo['mpeg']['audio']['VBR_offsets_relative'][$i] = $Fraunhofer_OffsetN; - $ThisFileInfo['mpeg']['audio']['VBR_offsets_absolute'][$i] = $Fraunhofer_OffsetN + $previousbyteoffset; - $previousbyteoffset += $Fraunhofer_OffsetN; - } - } else { - // Xing VBR header is hardcoded 'Xing' at a offset 0x0D (13), 0x15 (21) or 0x24 (36) - // depending on MPEG layer and number of channels - - if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { - if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { - // MPEG-1 (mono) - $VBRidOffset = 4 + 17; // 0x15 - $SideInfoData = substr($headerstring, 4 + 2, 17); - } else { - // MPEG-1 (stereo, joint-stereo, dual-channel) - $VBRidOffset = 4 + 32; // 0x24 - $SideInfoData = substr($headerstring, 4 + 2, 32); - } - } else { // 2 or 2.5 - if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { - // MPEG-2, MPEG-2.5 (mono) - $VBRidOffset = 4 + 9; // 0x0D - $SideInfoData = substr($headerstring, 4 + 2, 9); - } else { - // MPEG-2, MPEG-2.5 (stereo, joint-stereo, dual-channel) - $VBRidOffset = 4 + 17; // 0x15 - $SideInfoData = substr($headerstring, 4 + 2, 17); - } - } - - if ((substr($headerstring, $VBRidOffset, strlen('Xing')) == 'Xing') || (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Info')) { - // 'Xing' is traditional Xing VBR frame - // 'Info' is LAME-encoded CBR (This was done to avoid CBR files to be recognized as traditional Xing VBR files by some decoders.) - - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; - $ThisFileInfo['mpeg']['audio']['VBR_method'] = 'Xing'; - - $ThisFileInfo['mpeg']['audio']['xing_flags_raw'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 4, 4)); - - $ThisFileInfo['mpeg']['audio']['xing_flags']['frames'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000001); - $ThisFileInfo['mpeg']['audio']['xing_flags']['bytes'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000002); - $ThisFileInfo['mpeg']['audio']['xing_flags']['toc'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000004); - $ThisFileInfo['mpeg']['audio']['xing_flags']['vbr_scale'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000008); - - if ($ThisFileInfo['mpeg']['audio']['xing_flags']['frames']) { - $ThisFileInfo['mpeg']['audio']['VBR_frames'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 8, 4)); - } - if ($ThisFileInfo['mpeg']['audio']['xing_flags']['bytes']) { - $ThisFileInfo['mpeg']['audio']['VBR_bytes'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 12, 4)); - } - - if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') && !empty($ThisFileInfo['mpeg']['audio']['VBR_frames']) && !empty($ThisFileInfo['mpeg']['audio']['VBR_bytes'])) { - $framelengthfloat = $ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']; - if ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { - // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 - $ThisFileInfo['audio']['bitrate'] = ((($framelengthfloat / 4) - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 12; - } else { - // Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144 - $ThisFileInfo['audio']['bitrate'] = (($framelengthfloat - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 144; - } - $ThisFileInfo['mpeg']['audio']['framelength'] = floor($framelengthfloat); - } - - if ($ThisFileInfo['mpeg']['audio']['xing_flags']['toc']) { - $LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100); - for ($i = 0; $i < 100; $i++) { - $ThisFileInfo['mpeg']['audio']['toc'][$i] = ord($LAMEtocData{$i}); - } - } - if ($ThisFileInfo['mpeg']['audio']['xing_flags']['vbr_scale']) { - $ThisFileInfo['mpeg']['audio']['VBR_scale'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 116, 4)); - } - - // http://gabriel.mp3-tech.org/mp3infotag.html - if (substr($headerstring, $VBRidOffset + 120, 4) == 'LAME') { - $ThisFileInfo['mpeg']['audio']['LAME']['long_version'] = substr($headerstring, $VBRidOffset + 120, 20); - $ThisFileInfo['mpeg']['audio']['LAME']['short_version'] = substr($ThisFileInfo['mpeg']['audio']['LAME']['long_version'], 0, 9); - $ThisFileInfo['mpeg']['audio']['LAME']['long_version'] = rtrim($ThisFileInfo['mpeg']['audio']['LAME']['long_version'], "\x55\xAA"); - - if ($ThisFileInfo['mpeg']['audio']['LAME']['short_version'] >= 'LAME3.90.') { - // It the LAME tag was only introduced in LAME v3.90 - // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933 - - // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html - // are assuming a 'Xing' identifier offset of 0x24, which is the case for - // MPEG-1 non-mono, but not for other combinations - $LAMEtagOffsetContant = $VBRidOffset - 0x24; - - // byte $9B VBR Quality - // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications. - // Actually overwrites original Xing bytes - unset($ThisFileInfo['mpeg']['audio']['VBR_scale']); - $ThisFileInfo['mpeg']['audio']['LAME']['vbr_quality'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1)); - - // bytes $9C-$A4 Encoder short VersionString - $ThisFileInfo['mpeg']['audio']['LAME']['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9); - $ThisFileInfo['mpeg']['audio']['LAME']['long_version'] = $ThisFileInfo['mpeg']['audio']['LAME']['short_version']; - - // byte $A5 Info Tag revision + VBR method - $LAMEtagRevisionVBRmethod = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1)); - - $ThisFileInfo['mpeg']['audio']['LAME']['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4; - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F; - $ThisFileInfo['mpeg']['audio']['LAME']['vbr_method'] = LAMEvbrMethodLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method']); - - // byte $A6 Lowpass filter value - $ThisFileInfo['mpeg']['audio']['LAME']['lowpass_frequency'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100; - - // bytes $A7-$AE Replay Gain - // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html - // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude" - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] = BigEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4)); - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2)); - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2)); - - if ($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] == 0) { - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] = false; - } - - if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] != 0) { - require_once(GETID3_INCLUDEPATH.'getid3.rgad.php'); - - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['name'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0xE000) >> 13; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['originator'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0x1C00) >> 10; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['sign_bit'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0x0200) >> 9; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['gain_adjust'] = $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0x01FF; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['name'] = RGADnameLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['name']); - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['originator'] = RGADoriginatorLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['originator']); - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['gain_db'] = RGADadjustmentLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['gain_adjust'], $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['sign_bit']); - - if ($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] !== false) { - $ThisFileInfo['replay_gain']['radio']['peak'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude']; - } - $ThisFileInfo['replay_gain']['radio']['originator'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['originator']; - $ThisFileInfo['replay_gain']['radio']['adjustment'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['gain_db']; - } - if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] != 0) { - require_once(GETID3_INCLUDEPATH.'getid3.rgad.php'); - - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['name'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0xE000) >> 13; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['originator'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0x1C00) >> 10; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['sign_bit'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0x0200) >> 9; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['gain_adjust'] = $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0x01FF; - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['name'] = RGADnameLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['name']); - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['originator'] = RGADoriginatorLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['originator']); - $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['gain_db'] = RGADadjustmentLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['gain_adjust'], $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['sign_bit']); - - if ($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] !== false) { - $ThisFileInfo['replay_gain']['audiophile']['peak'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude']; - } - $ThisFileInfo['replay_gain']['audiophile']['originator'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['originator']; - $ThisFileInfo['replay_gain']['audiophile']['adjustment'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['gain_db']; - } - - - // byte $AF Encoding flags + ATH Type - $EncodingFlagsATHtype = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1)); - $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nspsytune'] = (bool) ($EncodingFlagsATHtype & 0x10); - $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20); - $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nogap_next'] = (bool) ($EncodingFlagsATHtype & 0x40); - $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nogap_prev'] = (bool) ($EncodingFlagsATHtype & 0x80); - $ThisFileInfo['mpeg']['audio']['LAME']['ath_type'] = $EncodingFlagsATHtype & 0x0F; - - // byte $B0 if ABR {specified bitrate} else {minimal bitrate} - $ABRbitrateMinBitrate = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1)); - if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method'] == 2) { // Average BitRate (ABR) - $ThisFileInfo['mpeg']['audio']['LAME']['bitrate_abr'] = $ABRbitrateMinBitrate; - } elseif ($ABRbitrateMinBitrate > 0) { // Variable BitRate (VBR) - minimum bitrate - $ThisFileInfo['mpeg']['audio']['LAME']['bitrate_min'] = $ABRbitrateMinBitrate; - } - - // bytes $B1-$B3 Encoder delays - $EncoderDelays = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3)); - $ThisFileInfo['mpeg']['audio']['LAME']['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12; - $ThisFileInfo['mpeg']['audio']['LAME']['end_padding'] = $EncoderDelays & 0x000FFF; - - // byte $B4 Misc - $MiscByte = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1)); - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['noise_shaping'] = ($MiscByte & 0x03); - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['stereo_mode'] = ($MiscByte & 0x1C) >> 2; - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['not_optimal_quality'] = ($MiscByte & 0x20) >> 5; - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['source_sample_freq'] = ($MiscByte & 0xC0) >> 6; - $ThisFileInfo['mpeg']['audio']['LAME']['noise_shaping'] = $ThisFileInfo['mpeg']['audio']['LAME']['raw']['noise_shaping']; - $ThisFileInfo['mpeg']['audio']['LAME']['stereo_mode'] = LAMEmiscStereoModeLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['stereo_mode']); - $ThisFileInfo['mpeg']['audio']['LAME']['not_optimal_quality'] = (bool) $ThisFileInfo['mpeg']['audio']['LAME']['raw']['not_optimal_quality']; - $ThisFileInfo['mpeg']['audio']['LAME']['source_sample_freq'] = LAMEmiscSourceSampleFrequencyLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['source_sample_freq']); - - // byte $B5 MP3 Gain - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['mp3_gain'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true); - $ThisFileInfo['mpeg']['audio']['LAME']['mp3_gain_db'] = 1.5 * $ThisFileInfo['mpeg']['audio']['LAME']['raw']['mp3_gain']; - $ThisFileInfo['mpeg']['audio']['LAME']['mp3_gain_factor'] = pow(2, ($ThisFileInfo['mpeg']['audio']['LAME']['mp3_gain_db'] / 6)); - - // bytes $B6-$B7 Preset and surround info - $PresetSurroundBytes = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2)); - // Reserved = ($PresetSurroundBytes & 0xC000); - $ThisFileInfo['mpeg']['audio']['LAME']['raw']['surround_info'] = ($PresetSurroundBytes & 0x3800); - $ThisFileInfo['mpeg']['audio']['LAME']['surround_info'] = LAMEsurroundInfoLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['surround_info']); - $ThisFileInfo['mpeg']['audio']['LAME']['preset_used_id'] = ($PresetSurroundBytes & 0x07FF); - - // bytes $B8-$BB MusicLength - $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4)); - $ExpectedNumberOfAudioBytes = (($ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'] > 0) ? $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'] : $ThisFileInfo['mpeg']['audio']['VBR_bytes']); - - // bytes $BC-$BD MusicCRC - $ThisFileInfo['mpeg']['audio']['LAME']['music_crc'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2)); - - // bytes $BE-$BF CRC-16 of Info Tag - $ThisFileInfo['mpeg']['audio']['LAME']['lame_tag_crc'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2)); - - - // LAME CBR - if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method'] == 1) { - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; - if (empty($ThisFileInfo['mpeg']['audio']['bitrate']) || ($ThisFileInfo['mpeg']['audio']['LAME']['bitrate_min'] != 255)) { - $ThisFileInfo['mpeg']['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['LAME']['bitrate_min']; - } - } - } - } - } else { - // not Fraunhofer or Xing VBR methods, most likely CBR (but could be VBR with no header) - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; - if ($recursivesearch) { - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; - if (RecursiveFrameScanning($fd, $ThisFileInfo, $offset, $nextframetestoffset, true)) { - $recursivesearch = false; - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; - } - if ($ThisFileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr') { - $ThisFileInfo['warning'] .= "\n".'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.'; - } - } - } - } - - if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']))) { - if (($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) == 1) { - $ThisFileInfo['warning'] .= "\n".'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)'; - } elseif ($ExpectedNumberOfAudioBytes > ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) { - $ThisFileInfo['warning'] .= "\n".'Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])).' bytes)'; - } else { - $ThisFileInfo['warning'] .= "\n".'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' ('.(($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'; - } - } - - if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') && empty($ThisFileInfo['audio']['bitrate'])) { - if (($offset == $ThisFileInfo['avdataoffset']) && empty($ThisFileInfo['mpeg']['audio']['VBR_frames'])) { - $framebytelength = FreeFormatFrameLength($fd, $offset, $ThisFileInfo, true); - if ($framebytelength > 0) { - $ThisFileInfo['mpeg']['audio']['framelength'] = $framebytelength; - if ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { - // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 - $ThisFileInfo['audio']['bitrate'] = ((($framebytelength / 4) - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 12; - } else { - // Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144 - $ThisFileInfo['audio']['bitrate'] = (($framebytelength - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 144; - } - } else { - $ThisFileInfo['error'] .= "\n".'Error calculating frame length of free-format MP3 without Xing/LAME header'; - } - } - } - - if (($ThisFileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr') && isset($ThisFileInfo['mpeg']['audio']['VBR_frames']) && ($ThisFileInfo['mpeg']['audio']['VBR_frames'] > 1)) { - $ThisFileInfo['mpeg']['audio']['VBR_frames']--; // don't count the Xing / VBRI frame - if (($ThisFileInfo['mpeg']['audio']['version'] == '1') && ($ThisFileInfo['mpeg']['audio']['layer'] == 'I')) { - $ThisFileInfo['mpeg']['audio']['VBR_bitrate'] = ((($ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 384)) / 1000; - } elseif ((($ThisFileInfo['mpeg']['audio']['version'] == '2') || ($ThisFileInfo['mpeg']['audio']['version'] == '2.5')) && ($ThisFileInfo['mpeg']['audio']['layer'] == 'III')) { - $ThisFileInfo['mpeg']['audio']['VBR_bitrate'] = ((($ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 576)) / 1000; - } else { - $ThisFileInfo['mpeg']['audio']['VBR_bitrate'] = ((($ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 1152)) / 1000; - } - if ($ThisFileInfo['mpeg']['audio']['VBR_bitrate'] > 0) { - $ThisFileInfo['audio']['bitrate'] = 1000 * $ThisFileInfo['mpeg']['audio']['VBR_bitrate']; - $ThisFileInfo['mpeg']['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['VBR_bitrate']; // to avoid confusion - } - } - - // End variable-bitrate headers - //////////////////////////////////////////////////////////////////////////////////// - - if ($recursivesearch) { - if (!RecursiveFrameScanning($fd, $ThisFileInfo, $offset, $nextframetestoffset, $ScanAsCBR)) { - return false; - } - } - - - //if (false) { - // // experimental side info parsing section - not returning anything useful yet - // - // $SideInfoBitstream = BigEndian2Bin($SideInfoData); - // $SideInfoOffset = 0; - // - // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { - // if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { - // // MPEG-1 (mono) - // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 9); - // $SideInfoOffset += 9; - // $SideInfoOffset += 5; - // } else { - // // MPEG-1 (stereo, joint-stereo, dual-channel) - // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 9); - // $SideInfoOffset += 9; - // $SideInfoOffset += 3; - // } - // } else { // 2 or 2.5 - // if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { - // // MPEG-2, MPEG-2.5 (mono) - // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 8); - // $SideInfoOffset += 8; - // $SideInfoOffset += 1; - // } else { - // // MPEG-2, MPEG-2.5 (stereo, joint-stereo, dual-channel) - // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 8); - // $SideInfoOffset += 8; - // $SideInfoOffset += 2; - // } - // } - // - // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { - // for ($channel = 0; $channel < $ThisFileInfo['audio']['channels']; $channel++) { - // for ($scfsi_band = 0; $scfsi_band < 4; $scfsi_band++) { - // $ThisFileInfo['mpeg']['audio']['scfsi'][$channel][$scfsi_band] = substr($SideInfoBitstream, $SideInfoOffset, 1); - // $SideInfoOffset += 2; - // } - // } - // } - // for ($granule = 0; $granule < (($ThisFileInfo['mpeg']['audio']['version'] == '1') ? 2 : 1); $granule++) { - // for ($channel = 0; $channel < $ThisFileInfo['audio']['channels']; $channel++) { - // $ThisFileInfo['mpeg']['audio']['part2_3_length'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 12); - // $SideInfoOffset += 12; - // $ThisFileInfo['mpeg']['audio']['big_values'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 9); - // $SideInfoOffset += 9; - // $ThisFileInfo['mpeg']['audio']['global_gain'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 8); - // $SideInfoOffset += 8; - // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { - // $ThisFileInfo['mpeg']['audio']['scalefac_compress'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 4); - // $SideInfoOffset += 4; - // } else { - // $ThisFileInfo['mpeg']['audio']['scalefac_compress'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 9); - // $SideInfoOffset += 9; - // } - // $ThisFileInfo['mpeg']['audio']['window_switching_flag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); - // $SideInfoOffset += 1; - // - // if ($ThisFileInfo['mpeg']['audio']['window_switching_flag'][$granule][$channel] == '1') { - // - // $ThisFileInfo['mpeg']['audio']['block_type'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 2); - // $SideInfoOffset += 2; - // $ThisFileInfo['mpeg']['audio']['mixed_block_flag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); - // $SideInfoOffset += 1; - // - // for ($region = 0; $region < 2; $region++) { - // $ThisFileInfo['mpeg']['audio']['table_select'][$granule][$channel][$region] = substr($SideInfoBitstream, $SideInfoOffset, 5); - // $SideInfoOffset += 5; - // } - // $ThisFileInfo['mpeg']['audio']['table_select'][$granule][$channel][2] = 0; - // - // for ($window = 0; $window < 3; $window++) { - // $ThisFileInfo['mpeg']['audio']['subblock_gain'][$granule][$channel][$window] = substr($SideInfoBitstream, $SideInfoOffset, 3); - // $SideInfoOffset += 3; - // } - // - // } else { - // - // for ($region = 0; $region < 3; $region++) { - // $ThisFileInfo['mpeg']['audio']['table_select'][$granule][$channel][$region] = substr($SideInfoBitstream, $SideInfoOffset, 5); - // $SideInfoOffset += 5; - // } - // - // $ThisFileInfo['mpeg']['audio']['region0_count'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 4); - // $SideInfoOffset += 4; - // $ThisFileInfo['mpeg']['audio']['region1_count'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 3); - // $SideInfoOffset += 3; - // $ThisFileInfo['mpeg']['audio']['block_type'][$granule][$channel] = 0; - // } - // - // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { - // $ThisFileInfo['mpeg']['audio']['preflag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); - // $SideInfoOffset += 1; - // } - // $ThisFileInfo['mpeg']['audio']['scalefac_scale'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); - // $SideInfoOffset += 1; - // $ThisFileInfo['mpeg']['audio']['count1table_select'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); - // $SideInfoOffset += 1; - // } - // } - //} - - return true; +function decodeMPEGaudioHeader($fd, $offset, &$ThisFileInfo, $recursivesearch=true, $ScanAsCBR=false, $FastMPEGheaderScan=false) { + + static $MPEGaudioVersionLookup; + static $MPEGaudioLayerLookup; + static $MPEGaudioBitrateLookup; + static $MPEGaudioFrequencyLookup; + static $MPEGaudioChannelModeLookup; + static $MPEGaudioModeExtensionLookup; + static $MPEGaudioEmphasisLookup; + if (empty($MPEGaudioVersionLookup)) { + $MPEGaudioVersionLookup = MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); + $MPEGaudioFrequencyLookup = MPEGaudioFrequencyArray(); + $MPEGaudioChannelModeLookup = MPEGaudioChannelModeArray(); + $MPEGaudioModeExtensionLookup = MPEGaudioModeExtensionArray(); + $MPEGaudioEmphasisLookup = MPEGaudioEmphasisArray(); + } + + if ($offset >= $ThisFileInfo['avdataend']) { + $ThisFileInfo['error'] .= "\n".'end of file encounter looking for MPEG synch'; + return false; + } + fseek($fd, $offset, SEEK_SET); + $headerstring = fread($fd, 1441); // worse-case max length = 32kHz @ 320kbps layer 3 = 1441 bytes/frame + + // MP3 audio frame structure: + // $aa $aa $aa $aa [$bb $bb] $cc... + // where $aa..$aa is the four-byte mpeg-audio header (below) + // $bb $bb is the optional 2-byte CRC + // and $cc... is the audio data + + $head4 = substr($headerstring, 0, 4); + + static $MPEGaudioHeaderDecodeCache = array(); + if (isset($MPEGaudioHeaderDecodeCache[$head4])) { + $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4]; + } else { + $MPEGheaderRawArray = MPEGaudioHeaderDecode($head4); + $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray; + } + + static $MPEGaudioHeaderValidCache = array(); + + // Not in cache + if (!isset($MPEGaudioHeaderValidCache[$head4])) { + $MPEGaudioHeaderValidCache[$head4] = MPEGaudioHeaderValid($MPEGheaderRawArray); + } + + if ($MPEGaudioHeaderValidCache[$head4]) { + $ThisFileInfo['mpeg']['audio']['raw'] = $MPEGheaderRawArray; + } else { + $ThisFileInfo['error'] .= "\n".'Invalid MPEG audio header at offset '.$offset; + return false; + } + + if (!$FastMPEGheaderScan) { + + $ThisFileInfo['mpeg']['audio']['version'] = $MPEGaudioVersionLookup[$ThisFileInfo['mpeg']['audio']['raw']['version']]; + $ThisFileInfo['mpeg']['audio']['layer'] = $MPEGaudioLayerLookup[$ThisFileInfo['mpeg']['audio']['raw']['layer']]; + + $ThisFileInfo['mpeg']['audio']['channelmode'] = $MPEGaudioChannelModeLookup[$ThisFileInfo['mpeg']['audio']['raw']['channelmode']]; + $ThisFileInfo['mpeg']['audio']['channels'] = (($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') ? 1 : 2); + $ThisFileInfo['mpeg']['audio']['sample_rate'] = $MPEGaudioFrequencyLookup[$ThisFileInfo['mpeg']['audio']['version']][$ThisFileInfo['mpeg']['audio']['raw']['sample_rate']]; + $ThisFileInfo['mpeg']['audio']['protection'] = !$ThisFileInfo['mpeg']['audio']['raw']['protection']; + $ThisFileInfo['mpeg']['audio']['private'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['private']; + $ThisFileInfo['mpeg']['audio']['modeextension'] = $MPEGaudioModeExtensionLookup[$ThisFileInfo['mpeg']['audio']['layer']][$ThisFileInfo['mpeg']['audio']['raw']['modeextension']]; + $ThisFileInfo['mpeg']['audio']['copyright'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['copyright']; + $ThisFileInfo['mpeg']['audio']['original'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['original']; + $ThisFileInfo['mpeg']['audio']['emphasis'] = $MPEGaudioEmphasisLookup[$ThisFileInfo['mpeg']['audio']['raw']['emphasis']]; + + $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels']; + $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate']; + + if ($ThisFileInfo['mpeg']['audio']['protection']) { + $ThisFileInfo['mpeg']['audio']['crc'] = BigEndian2Int(substr($headerstring, 4, 2)); + } + + } + + if ($ThisFileInfo['mpeg']['audio']['raw']['bitrate'] == 15) { + // http://www.hydrogenaudio.org/?act=ST&f=16&t=9682&st=0 + $ThisFileInfo['warning'] .= "\n".'Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1'; + $ThisFileInfo['mpeg']['audio']['raw']['bitrate'] = 0; + } + $ThisFileInfo['mpeg']['audio']['padding'] = (bool) $ThisFileInfo['mpeg']['audio']['raw']['padding']; + $ThisFileInfo['mpeg']['audio']['bitrate'] = $MPEGaudioBitrateLookup[$ThisFileInfo['mpeg']['audio']['version']][$ThisFileInfo['mpeg']['audio']['layer']][$ThisFileInfo['mpeg']['audio']['raw']['bitrate']]; + + if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') && ($offset == $ThisFileInfo['avdataoffset'])) { + // only skip multiple frame check if free-format bitstream found at beginning of file + // otherwise is quite possibly simply corrupted data + $recursivesearch = false; + } + + // For Layer II there are some combinations of bitrate and mode which are not allowed. + if (!$FastMPEGheaderScan && ($ThisFileInfo['mpeg']['audio']['layer'] == 'II')) { + + $ThisFileInfo['audio']['dataformat'] = 'mp2'; + switch ($ThisFileInfo['mpeg']['audio']['channelmode']) { + + case 'mono': + if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') || ($ThisFileInfo['mpeg']['audio']['bitrate'] <= 192)) { + // these are ok + } else { + $ThisFileInfo['error'] .= "\n".$ThisFileInfo['mpeg']['audio']['bitrate'].'kbps not allowed in Layer II, '.$ThisFileInfo['mpeg']['audio']['channelmode'].'.'; + return false; + } + break; + + case 'stereo': + case 'joint stereo': + case 'dual channel': + if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') || ($ThisFileInfo['mpeg']['audio']['bitrate'] == 64) || ($ThisFileInfo['mpeg']['audio']['bitrate'] >= 96)) { + // these are ok + } else { + $ThisFileInfo['error'] .= "\n".$ThisFileInfo['mpeg']['audio']['bitrate'].'kbps not allowed in Layer II, '.$ThisFileInfo['mpeg']['audio']['channelmode'].'.'; + return false; + } + break; + + } + + } + + + if ($ThisFileInfo['audio']['sample_rate'] > 0) { + $ThisFileInfo['mpeg']['audio']['framelength'] = MPEGaudioFrameLength($ThisFileInfo['mpeg']['audio']['bitrate'], $ThisFileInfo['mpeg']['audio']['version'], $ThisFileInfo['mpeg']['audio']['layer'], (int) $ThisFileInfo['mpeg']['audio']['padding'], $ThisFileInfo['audio']['sample_rate']); + } + + if ($ThisFileInfo['mpeg']['audio']['bitrate'] != 'free') { + + $ThisFileInfo['audio']['bitrate'] = 1000 * $ThisFileInfo['mpeg']['audio']['bitrate']; + + if (isset($ThisFileInfo['mpeg']['audio']['framelength'])) { + $nextframetestoffset = $offset + $ThisFileInfo['mpeg']['audio']['framelength']; + } else { + $ThisFileInfo['error'] .= "\n".'Frame at offset('.$offset.') is has an invalid frame length.'; + return false; + } + + } + + $ExpectedNumberOfAudioBytes = 0; + + //////////////////////////////////////////////////////////////////////////////////// + // Variable-bitrate headers + + if (substr($headerstring, 4 + 32, 4) == 'VBRI') { + // Fraunhofer VBR header is hardcoded 'VBRI' at offset 0x24 (36) + // specs taken from http://minnie.tuhs.org/pipermail/mp3encoder/2001-January/001800.html + + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; + $ThisFileInfo['mpeg']['audio']['VBR_method'] = 'Fraunhofer'; + $ThisFileInfo['audio']['codec'] = 'Fraunhofer'; + + $SideInfoData = substr($headerstring, 4 + 2, 32); + + $FraunhoferVBROffset = 36; + + $ThisFileInfo['mpeg']['audio']['VBR_encoder_version'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 4, 2)); + $ThisFileInfo['mpeg']['audio']['VBR_encoder_delay'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 6, 2)); + $ThisFileInfo['mpeg']['audio']['VBR_quality'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 8, 2)); + $ThisFileInfo['mpeg']['audio']['VBR_bytes'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 10, 4)); + $ThisFileInfo['mpeg']['audio']['VBR_frames'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 14, 4)); + $ThisFileInfo['mpeg']['audio']['VBR_seek_offsets'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 18, 2)); + //$ThisFileInfo['mpeg']['audio']['reserved'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 20, 4)); // hardcoded $00 $01 $00 $02 - purpose unknown + $ThisFileInfo['mpeg']['audio']['VBR_seek_offsets_stride'] = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset + 24, 2)); + + $ExpectedNumberOfAudioBytes = $ThisFileInfo['mpeg']['audio']['VBR_bytes']; + + $previousbyteoffset = $offset; + for ($i = 0; $i < $ThisFileInfo['mpeg']['audio']['VBR_seek_offsets']; $i++) { + $Fraunhofer_OffsetN = BigEndian2Int(substr($headerstring, $FraunhoferVBROffset, 2)); + $FraunhoferVBROffset += 2; + $ThisFileInfo['mpeg']['audio']['VBR_offsets_relative'][$i] = $Fraunhofer_OffsetN; + $ThisFileInfo['mpeg']['audio']['VBR_offsets_absolute'][$i] = $Fraunhofer_OffsetN + $previousbyteoffset; + $previousbyteoffset += $Fraunhofer_OffsetN; + } + + + } else { + + // Xing VBR header is hardcoded 'Xing' at a offset 0x0D (13), 0x15 (21) or 0x24 (36) + // depending on MPEG layer and number of channels + + if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { + if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { + // MPEG-1 (mono) + $VBRidOffset = 4 + 17; // 0x15 + $SideInfoData = substr($headerstring, 4 + 2, 17); + } else { + // MPEG-1 (stereo, joint-stereo, dual-channel) + $VBRidOffset = 4 + 32; // 0x24 + $SideInfoData = substr($headerstring, 4 + 2, 32); + } + } else { // 2 or 2.5 + if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { + // MPEG-2, MPEG-2.5 (mono) + $VBRidOffset = 4 + 9; // 0x0D + $SideInfoData = substr($headerstring, 4 + 2, 9); + } else { + // MPEG-2, MPEG-2.5 (stereo, joint-stereo, dual-channel) + $VBRidOffset = 4 + 17; // 0x15 + $SideInfoData = substr($headerstring, 4 + 2, 17); + } + } + + if ((substr($headerstring, $VBRidOffset, strlen('Xing')) == 'Xing') || (substr($headerstring, $VBRidOffset, strlen('Info')) == 'Info')) { + // 'Xing' is traditional Xing VBR frame + // 'Info' is LAME-encoded CBR (This was done to avoid CBR files to be recognized as traditional Xing VBR files by some decoders.) + + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; + $ThisFileInfo['mpeg']['audio']['VBR_method'] = 'Xing'; + + $ThisFileInfo['mpeg']['audio']['xing_flags_raw'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 4, 4)); + + $ThisFileInfo['mpeg']['audio']['xing_flags']['frames'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000001); + $ThisFileInfo['mpeg']['audio']['xing_flags']['bytes'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000002); + $ThisFileInfo['mpeg']['audio']['xing_flags']['toc'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000004); + $ThisFileInfo['mpeg']['audio']['xing_flags']['vbr_scale'] = (bool) ($ThisFileInfo['mpeg']['audio']['xing_flags_raw'] & 0x00000008); + + if ($ThisFileInfo['mpeg']['audio']['xing_flags']['frames']) { + $ThisFileInfo['mpeg']['audio']['VBR_frames'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 8, 4)); + } + if ($ThisFileInfo['mpeg']['audio']['xing_flags']['bytes']) { + $ThisFileInfo['mpeg']['audio']['VBR_bytes'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 12, 4)); + } + + if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') && !empty($ThisFileInfo['mpeg']['audio']['VBR_frames']) && !empty($ThisFileInfo['mpeg']['audio']['VBR_bytes'])) { + $framelengthfloat = $ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']; + if ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { + // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 + $ThisFileInfo['audio']['bitrate'] = ((($framelengthfloat / 4) - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 12; + } else { + // Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144 + $ThisFileInfo['audio']['bitrate'] = (($framelengthfloat - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 144; + } + $ThisFileInfo['mpeg']['audio']['framelength'] = floor($framelengthfloat); + } + + if ($ThisFileInfo['mpeg']['audio']['xing_flags']['toc']) { + $LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100); + for ($i = 0; $i < 100; $i++) { + $ThisFileInfo['mpeg']['audio']['toc'][$i] = ord($LAMEtocData{$i}); + } + } + if ($ThisFileInfo['mpeg']['audio']['xing_flags']['vbr_scale']) { + $ThisFileInfo['mpeg']['audio']['VBR_scale'] = BigEndian2Int(substr($headerstring, $VBRidOffset + 116, 4)); + } + + // http://gabriel.mp3-tech.org/mp3infotag.html + if (substr($headerstring, $VBRidOffset + 120, 4) == 'LAME') { + $ThisFileInfo['mpeg']['audio']['LAME']['long_version'] = substr($headerstring, $VBRidOffset + 120, 20); + $ThisFileInfo['mpeg']['audio']['LAME']['short_version'] = substr($ThisFileInfo['mpeg']['audio']['LAME']['long_version'], 0, 9); + $ThisFileInfo['mpeg']['audio']['LAME']['long_version'] = rtrim($ThisFileInfo['mpeg']['audio']['LAME']['long_version'], "\x55\xAA"); + + if ($ThisFileInfo['mpeg']['audio']['LAME']['short_version'] >= 'LAME3.90.') { + + // It the LAME tag was only introduced in LAME v3.90 + // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933 + + // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html + // are assuming a 'Xing' identifier offset of 0x24, which is the case for + // MPEG-1 non-mono, but not for other combinations + $LAMEtagOffsetContant = $VBRidOffset - 0x24; + + // byte $9B VBR Quality + // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications. + // Actually overwrites original Xing bytes + unset($ThisFileInfo['mpeg']['audio']['VBR_scale']); + $ThisFileInfo['mpeg']['audio']['LAME']['vbr_quality'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1)); + + // bytes $9C-$A4 Encoder short VersionString + $ThisFileInfo['mpeg']['audio']['LAME']['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9); + $ThisFileInfo['mpeg']['audio']['LAME']['long_version'] = $ThisFileInfo['mpeg']['audio']['LAME']['short_version']; + + // byte $A5 Info Tag revision + VBR method + $LAMEtagRevisionVBRmethod = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1)); + + $ThisFileInfo['mpeg']['audio']['LAME']['tag_revision'] = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4; + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method'] = $LAMEtagRevisionVBRmethod & 0x0F; + $ThisFileInfo['mpeg']['audio']['LAME']['vbr_method'] = LAMEvbrMethodLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method']); + + // byte $A6 Lowpass filter value + $ThisFileInfo['mpeg']['audio']['LAME']['lowpass_frequency'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100; + + // bytes $A7-$AE Replay Gain + // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html + // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude" + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] = BigEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4)); + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2)); + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2)); + + if ($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] == 0) { + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] = false; + } + + if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] != 0) { + require_once(GETID3_INCLUDEPATH.'getid3.rgad.php'); + + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['name'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0xE000) >> 13; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['originator'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0x1C00) >> 10; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['sign_bit'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0x0200) >> 9; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['gain_adjust'] = $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_radio'] & 0x01FF; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['name'] = RGADnameLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['name']); + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['originator'] = RGADoriginatorLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['originator']); + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['gain_db'] = RGADadjustmentLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['gain_adjust'], $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['raw']['sign_bit']); + + if ($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] !== false) { + $ThisFileInfo['replay_gain']['radio']['peak'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude']; + } + $ThisFileInfo['replay_gain']['radio']['originator'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['originator']; + $ThisFileInfo['replay_gain']['radio']['adjustment'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['radio']['gain_db']; + } + if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] != 0) { + require_once(GETID3_INCLUDEPATH.'getid3.rgad.php'); + + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['name'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0xE000) >> 13; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['originator'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0x1C00) >> 10; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['sign_bit'] = ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0x0200) >> 9; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['gain_adjust'] = $ThisFileInfo['mpeg']['audio']['LAME']['raw']['RGAD_audiophile'] & 0x01FF; + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['name'] = RGADnameLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['name']); + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['originator'] = RGADoriginatorLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['originator']); + $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['gain_db'] = RGADadjustmentLookup($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['gain_adjust'], $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['raw']['sign_bit']); + + if ($ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude'] !== false) { + $ThisFileInfo['replay_gain']['audiophile']['peak'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['peak_amplitude']; + } + $ThisFileInfo['replay_gain']['audiophile']['originator'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['originator']; + $ThisFileInfo['replay_gain']['audiophile']['adjustment'] = $ThisFileInfo['mpeg']['audio']['LAME']['RGAD']['audiophile']['gain_db']; + } + + + // byte $AF Encoding flags + ATH Type + $EncodingFlagsATHtype = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1)); + $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nspsytune'] = (bool) ($EncodingFlagsATHtype & 0x10); + $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20); + $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nogap_next'] = (bool) ($EncodingFlagsATHtype & 0x40); + $ThisFileInfo['mpeg']['audio']['LAME']['encoding_flags']['nogap_prev'] = (bool) ($EncodingFlagsATHtype & 0x80); + $ThisFileInfo['mpeg']['audio']['LAME']['ath_type'] = $EncodingFlagsATHtype & 0x0F; + + // byte $B0 if ABR {specified bitrate} else {minimal bitrate} + $ABRbitrateMinBitrate = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1)); + if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method'] == 2) { // Average BitRate (ABR) + $ThisFileInfo['mpeg']['audio']['LAME']['bitrate_abr'] = $ABRbitrateMinBitrate; + } elseif ($ABRbitrateMinBitrate > 0) { // Variable BitRate (VBR) - minimum bitrate + $ThisFileInfo['mpeg']['audio']['LAME']['bitrate_min'] = $ABRbitrateMinBitrate; + } + + // bytes $B1-$B3 Encoder delays + $EncoderDelays = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3)); + $ThisFileInfo['mpeg']['audio']['LAME']['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12; + $ThisFileInfo['mpeg']['audio']['LAME']['end_padding'] = $EncoderDelays & 0x000FFF; + + // byte $B4 Misc + $MiscByte = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1)); + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['noise_shaping'] = ($MiscByte & 0x03); + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['stereo_mode'] = ($MiscByte & 0x1C) >> 2; + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['not_optimal_quality'] = ($MiscByte & 0x20) >> 5; + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['source_sample_freq'] = ($MiscByte & 0xC0) >> 6; + $ThisFileInfo['mpeg']['audio']['LAME']['noise_shaping'] = $ThisFileInfo['mpeg']['audio']['LAME']['raw']['noise_shaping']; + $ThisFileInfo['mpeg']['audio']['LAME']['stereo_mode'] = LAMEmiscStereoModeLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['stereo_mode']); + $ThisFileInfo['mpeg']['audio']['LAME']['not_optimal_quality'] = (bool) $ThisFileInfo['mpeg']['audio']['LAME']['raw']['not_optimal_quality']; + $ThisFileInfo['mpeg']['audio']['LAME']['source_sample_freq'] = LAMEmiscSourceSampleFrequencyLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['source_sample_freq']); + + // byte $B5 MP3 Gain + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['mp3_gain'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true); + $ThisFileInfo['mpeg']['audio']['LAME']['mp3_gain_db'] = 1.5 * $ThisFileInfo['mpeg']['audio']['LAME']['raw']['mp3_gain']; + $ThisFileInfo['mpeg']['audio']['LAME']['mp3_gain_factor'] = pow(2, ($ThisFileInfo['mpeg']['audio']['LAME']['mp3_gain_db'] / 6)); + + // bytes $B6-$B7 Preset and surround info + $PresetSurroundBytes = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2)); + // Reserved = ($PresetSurroundBytes & 0xC000); + $ThisFileInfo['mpeg']['audio']['LAME']['raw']['surround_info'] = ($PresetSurroundBytes & 0x3800); + $ThisFileInfo['mpeg']['audio']['LAME']['surround_info'] = LAMEsurroundInfoLookup($ThisFileInfo['mpeg']['audio']['LAME']['raw']['surround_info']); + $ThisFileInfo['mpeg']['audio']['LAME']['preset_used_id'] = ($PresetSurroundBytes & 0x07FF); + + // bytes $B8-$BB MusicLength + $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4)); + $ExpectedNumberOfAudioBytes = (($ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'] > 0) ? $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'] : $ThisFileInfo['mpeg']['audio']['VBR_bytes']); + + // bytes $BC-$BD MusicCRC + $ThisFileInfo['mpeg']['audio']['LAME']['music_crc'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2)); + + // bytes $BE-$BF CRC-16 of Info Tag + $ThisFileInfo['mpeg']['audio']['LAME']['lame_tag_crc'] = BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2)); + + + // LAME CBR + if ($ThisFileInfo['mpeg']['audio']['LAME']['raw']['vbr_method'] == 1) { + + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; + if (empty($ThisFileInfo['mpeg']['audio']['bitrate']) || ($ThisFileInfo['mpeg']['audio']['LAME']['bitrate_min'] != 255)) { + $ThisFileInfo['mpeg']['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['LAME']['bitrate_min']; + } + + } + + } + } + + } else { + + // not Fraunhofer or Xing VBR methods, most likely CBR (but could be VBR with no header) + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; + if ($recursivesearch) { + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; + if (RecursiveFrameScanning($fd, $ThisFileInfo, $offset, $nextframetestoffset, true)) { + $recursivesearch = false; + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; + } + if ($ThisFileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr') { + $ThisFileInfo['warning'] .= "\n".'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.'; + } + } + + } + + } + + if (($ExpectedNumberOfAudioBytes > 0) && ($ExpectedNumberOfAudioBytes != ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']))) { + if (($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) == 1) { + $ThisFileInfo['warning'] .= "\n".'Last byte of data truncated (this is a known bug in Meracl ID3 Tag Writer before v1.3.5)'; + } elseif ($ExpectedNumberOfAudioBytes > ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])) { + $ThisFileInfo['warning'] .= "\n".'Probable truncated file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, only found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' (short by '.($ExpectedNumberOfAudioBytes - ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'])).' bytes)'; + } else { + $ThisFileInfo['warning'] .= "\n".'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']).' ('.(($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'; + } + } + + if (($ThisFileInfo['mpeg']['audio']['bitrate'] == 'free') && empty($ThisFileInfo['audio']['bitrate'])) { + if (($offset == $ThisFileInfo['avdataoffset']) && empty($ThisFileInfo['mpeg']['audio']['VBR_frames'])) { + $framebytelength = FreeFormatFrameLength($fd, $offset, $ThisFileInfo, true); + if ($framebytelength > 0) { + $ThisFileInfo['mpeg']['audio']['framelength'] = $framebytelength; + if ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { + // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 + $ThisFileInfo['audio']['bitrate'] = ((($framebytelength / 4) - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 12; + } else { + // Bitrate = ((FrameLengthInBytes - Padding) * SampleRate) / 144 + $ThisFileInfo['audio']['bitrate'] = (($framebytelength - intval($ThisFileInfo['mpeg']['audio']['padding'])) * $ThisFileInfo['mpeg']['audio']['sample_rate']) / 144; + } + } else { + $ThisFileInfo['error'] .= "\n".'Error calculating frame length of free-format MP3 without Xing/LAME header'; + } + } + } + + if (($ThisFileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr') && isset($ThisFileInfo['mpeg']['audio']['VBR_frames']) && ($ThisFileInfo['mpeg']['audio']['VBR_frames'] > 1)) { + $ThisFileInfo['mpeg']['audio']['VBR_frames']--; // don't count the Xing / VBRI frame + if (($ThisFileInfo['mpeg']['audio']['version'] == '1') && ($ThisFileInfo['mpeg']['audio']['layer'] == 'I')) { + $ThisFileInfo['mpeg']['audio']['VBR_bitrate'] = ((($ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 384)) / 1000; + } elseif ((($ThisFileInfo['mpeg']['audio']['version'] == '2') || ($ThisFileInfo['mpeg']['audio']['version'] == '2.5')) && ($ThisFileInfo['mpeg']['audio']['layer'] == 'III')) { + $ThisFileInfo['mpeg']['audio']['VBR_bitrate'] = ((($ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 576)) / 1000; + } else { + $ThisFileInfo['mpeg']['audio']['VBR_bitrate'] = ((($ThisFileInfo['mpeg']['audio']['VBR_bytes'] / $ThisFileInfo['mpeg']['audio']['VBR_frames']) * 8) * ($ThisFileInfo['audio']['sample_rate'] / 1152)) / 1000; + } + if ($ThisFileInfo['mpeg']['audio']['VBR_bitrate'] > 0) { + $ThisFileInfo['audio']['bitrate'] = 1000 * $ThisFileInfo['mpeg']['audio']['VBR_bitrate']; + $ThisFileInfo['mpeg']['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['VBR_bitrate']; // to avoid confusion + } + } + + // End variable-bitrate headers + //////////////////////////////////////////////////////////////////////////////////// + + if ($recursivesearch) { + + if (!RecursiveFrameScanning($fd, $ThisFileInfo, $offset, $nextframetestoffset, $ScanAsCBR)) { + return false; + } + + } + + + //if (false) { + // // experimental side info parsing section - not returning anything useful yet + // + // $SideInfoBitstream = BigEndian2Bin($SideInfoData); + // $SideInfoOffset = 0; + // + // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { + // if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { + // // MPEG-1 (mono) + // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // $SideInfoOffset += 5; + // } else { + // // MPEG-1 (stereo, joint-stereo, dual-channel) + // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // $SideInfoOffset += 3; + // } + // } else { // 2 or 2.5 + // if ($ThisFileInfo['mpeg']['audio']['channelmode'] == 'mono') { + // // MPEG-2, MPEG-2.5 (mono) + // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 8); + // $SideInfoOffset += 8; + // $SideInfoOffset += 1; + // } else { + // // MPEG-2, MPEG-2.5 (stereo, joint-stereo, dual-channel) + // $ThisFileInfo['mpeg']['audio']['side_info']['main_data_begin'] = substr($SideInfoBitstream, $SideInfoOffset, 8); + // $SideInfoOffset += 8; + // $SideInfoOffset += 2; + // } + // } + // + // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { + // for ($channel = 0; $channel < $ThisFileInfo['audio']['channels']; $channel++) { + // for ($scfsi_band = 0; $scfsi_band < 4; $scfsi_band++) { + // $ThisFileInfo['mpeg']['audio']['scfsi'][$channel][$scfsi_band] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 2; + // } + // } + // } + // for ($granule = 0; $granule < (($ThisFileInfo['mpeg']['audio']['version'] == '1') ? 2 : 1); $granule++) { + // for ($channel = 0; $channel < $ThisFileInfo['audio']['channels']; $channel++) { + // $ThisFileInfo['mpeg']['audio']['part2_3_length'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 12); + // $SideInfoOffset += 12; + // $ThisFileInfo['mpeg']['audio']['big_values'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // $ThisFileInfo['mpeg']['audio']['global_gain'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 8); + // $SideInfoOffset += 8; + // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { + // $ThisFileInfo['mpeg']['audio']['scalefac_compress'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 4); + // $SideInfoOffset += 4; + // } else { + // $ThisFileInfo['mpeg']['audio']['scalefac_compress'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 9); + // $SideInfoOffset += 9; + // } + // $ThisFileInfo['mpeg']['audio']['window_switching_flag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // + // if ($ThisFileInfo['mpeg']['audio']['window_switching_flag'][$granule][$channel] == '1') { + // + // $ThisFileInfo['mpeg']['audio']['block_type'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 2); + // $SideInfoOffset += 2; + // $ThisFileInfo['mpeg']['audio']['mixed_block_flag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // + // for ($region = 0; $region < 2; $region++) { + // $ThisFileInfo['mpeg']['audio']['table_select'][$granule][$channel][$region] = substr($SideInfoBitstream, $SideInfoOffset, 5); + // $SideInfoOffset += 5; + // } + // $ThisFileInfo['mpeg']['audio']['table_select'][$granule][$channel][2] = 0; + // + // for ($window = 0; $window < 3; $window++) { + // $ThisFileInfo['mpeg']['audio']['subblock_gain'][$granule][$channel][$window] = substr($SideInfoBitstream, $SideInfoOffset, 3); + // $SideInfoOffset += 3; + // } + // + // } else { + // + // for ($region = 0; $region < 3; $region++) { + // $ThisFileInfo['mpeg']['audio']['table_select'][$granule][$channel][$region] = substr($SideInfoBitstream, $SideInfoOffset, 5); + // $SideInfoOffset += 5; + // } + // + // $ThisFileInfo['mpeg']['audio']['region0_count'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 4); + // $SideInfoOffset += 4; + // $ThisFileInfo['mpeg']['audio']['region1_count'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 3); + // $SideInfoOffset += 3; + // $ThisFileInfo['mpeg']['audio']['block_type'][$granule][$channel] = 0; + // } + // + // if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { + // $ThisFileInfo['mpeg']['audio']['preflag'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // } + // $ThisFileInfo['mpeg']['audio']['scalefac_scale'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // $ThisFileInfo['mpeg']['audio']['count1table_select'][$granule][$channel] = substr($SideInfoBitstream, $SideInfoOffset, 1); + // $SideInfoOffset += 1; + // } + // } + //} + + return true; } -function RecursiveFrameScanning(&$fd, &$ThisFileInfo, &$offset, &$nextframetestoffset, $ScanAsCBR) -{ - for ($i = 0; $i < MPEG_VALID_CHECK_FRAMES; $i++) { - // check next MPEG_VALID_CHECK_FRAMES frames for validity, to make sure we haven't run across a false synch - if (($nextframetestoffset + 4) >= $ThisFileInfo['avdataend']) { - // end of file - return true; - } +function RecursiveFrameScanning(&$fd, &$ThisFileInfo, &$offset, &$nextframetestoffset, $ScanAsCBR) { + for ($i = 0; $i < MPEG_VALID_CHECK_FRAMES; $i++) { + // check next MPEG_VALID_CHECK_FRAMES frames for validity, to make sure we haven't run across a false synch + if (($nextframetestoffset + 4) >= $ThisFileInfo['avdataend']) { + // end of file + return true; + } - $nextframetestarray = ['error'=>'', 'warning'=>'', 'avdataend'=>$ThisFileInfo['avdataend'], 'avdataoffset'=>$ThisFileInfo['avdataoffset']]; - if (decodeMPEGaudioHeader($fd, $nextframetestoffset, $nextframetestarray, false)) { - if ($ScanAsCBR) { - // force CBR mode, used for trying to pick out invalid audio streams with - // valid(?) VBR headers, or VBR streams with no VBR header - if (!isset($nextframetestarray['mpeg']['audio']['bitrate']) || !isset($ThisFileInfo['mpeg']['audio']['bitrate']) || ($nextframetestarray['mpeg']['audio']['bitrate'] != $ThisFileInfo['mpeg']['audio']['bitrate'])) { - return false; - } - } + $nextframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$ThisFileInfo['avdataend'], 'avdataoffset'=>$ThisFileInfo['avdataoffset']); + if (decodeMPEGaudioHeader($fd, $nextframetestoffset, $nextframetestarray, false)) { + if ($ScanAsCBR) { + // force CBR mode, used for trying to pick out invalid audio streams with + // valid(?) VBR headers, or VBR streams with no VBR header + if (!isset($nextframetestarray['mpeg']['audio']['bitrate']) || !isset($ThisFileInfo['mpeg']['audio']['bitrate']) || ($nextframetestarray['mpeg']['audio']['bitrate'] != $ThisFileInfo['mpeg']['audio']['bitrate'])) { + return false; + } + } - // next frame is OK, get ready to check the one after that - if (isset($nextframetestarray['mpeg']['audio']['framelength']) && ($nextframetestarray['mpeg']['audio']['framelength'] > 0)) { - $nextframetestoffset += $nextframetestarray['mpeg']['audio']['framelength']; - } else { - $ThisFileInfo['error'] .= "\n".'Frame at offset ('.$offset.') is has an invalid frame length.'; - return false; - } - } else { - // next frame is not valid, note the error and fail, so scanning can contiue for a valid frame sequence - $ThisFileInfo['error'] .= "\n".'Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.'; + // next frame is OK, get ready to check the one after that + if (isset($nextframetestarray['mpeg']['audio']['framelength']) && ($nextframetestarray['mpeg']['audio']['framelength'] > 0)) { + $nextframetestoffset += $nextframetestarray['mpeg']['audio']['framelength']; + } else { + $ThisFileInfo['error'] .= "\n".'Frame at offset ('.$offset.') is has an invalid frame length.'; + return false; + } - return false; - } - } - return true; + } else { + + // next frame is not valid, note the error and fail, so scanning can contiue for a valid frame sequence + $ThisFileInfo['error'] .= "\n".'Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.'; + + return false; + } + } + return true; } -function FreeFormatFrameLength($fd, $offset, &$ThisFileInfo, $deepscan = false) -{ - fseek($fd, $offset, SEEK_SET); - $MPEGaudioData = fread($fd, 32768); +function FreeFormatFrameLength($fd, $offset, &$ThisFileInfo, $deepscan=false) { + fseek($fd, $offset, SEEK_SET); + $MPEGaudioData = fread($fd, 32768); - $SyncPattern1 = substr($MPEGaudioData, 0, 4); - // may be different pattern due to padding - $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) | 0x02).$SyncPattern1{3}; - if ($SyncPattern2 === $SyncPattern1) { - $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) & 0xFD).$SyncPattern1{3}; - } + $SyncPattern1 = substr($MPEGaudioData, 0, 4); + // may be different pattern due to padding + $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) | 0x02).$SyncPattern1{3}; + if ($SyncPattern2 === $SyncPattern1) { + $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) & 0xFD).$SyncPattern1{3}; + } - $framelength = false; - $framelength1 = strpos($MPEGaudioData, $SyncPattern1, 4); - $framelength2 = strpos($MPEGaudioData, $SyncPattern2, 4); - if ($framelength1 > 4) { - $framelength = $framelength1; - } - if (($framelength2 > 4) && ($framelength2 < $framelength1)) { - $framelength = $framelength2; - } - if (!$framelength) { - // LAME 3.88 has a different value for modeextension on the first frame vs the rest - $framelength1 = strpos($MPEGaudioData, substr($SyncPattern1, 0, 3), 4); - $framelength2 = strpos($MPEGaudioData, substr($SyncPattern2, 0, 3), 4); + $framelength = false; + $framelength1 = strpos($MPEGaudioData, $SyncPattern1, 4); + $framelength2 = strpos($MPEGaudioData, $SyncPattern2, 4); + if ($framelength1 > 4) { + $framelength = $framelength1; + } + if (($framelength2 > 4) && ($framelength2 < $framelength1)) { + $framelength = $framelength2; + } + if (!$framelength) { - if ($framelength1 > 4) { - $framelength = $framelength1; - } - if (($framelength2 > 4) && ($framelength2 < $framelength1)) { - $framelength = $framelength2; - } - if (!$framelength) { - $ThisFileInfo['error'] .= "\n".'Cannot find next free-format synch pattern ('.PrintHexBytes($SyncPattern1).' or '.PrintHexBytes($SyncPattern2).') after offset '.$offset; - return false; - } else { - $ThisFileInfo['warning'] .= "\n".'ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)'; - $ThisFileInfo['audio']['codec'] = 'LAME'; - $ThisFileInfo['audio']['encoder'] = 'LAME3.88'; - $SyncPattern1 = substr($SyncPattern1, 0, 3); - $SyncPattern2 = substr($SyncPattern2, 0, 3); - } - } + // LAME 3.88 has a different value for modeextension on the first frame vs the rest + $framelength1 = strpos($MPEGaudioData, substr($SyncPattern1, 0, 3), 4); + $framelength2 = strpos($MPEGaudioData, substr($SyncPattern2, 0, 3), 4); - if ($deepscan) { - $ActualFrameLengthValues = []; - $nextoffset = $offset + $framelength; - while ($nextoffset < ($ThisFileInfo['avdataend'] - 6)) { - fseek($fd, $nextoffset - 1, SEEK_SET); - $NextSyncPattern = fread($fd, 6); - if ((substr($NextSyncPattern, 1, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 1, strlen($SyncPattern2)) == $SyncPattern2)) { - // good - found where expected - $ActualFrameLengthValues[] = $framelength; - } elseif ((substr($NextSyncPattern, 0, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 0, strlen($SyncPattern2)) == $SyncPattern2)) { - // ok - found one byte earlier than expected (last frame wasn't padded, first frame was) - $ActualFrameLengthValues[] = ($framelength - 1); - $nextoffset--; - } elseif ((substr($NextSyncPattern, 2, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 2, strlen($SyncPattern2)) == $SyncPattern2)) { - // ok - found one byte later than expected (last frame was padded, first frame wasn't) - $ActualFrameLengthValues[] = ($framelength + 1); - $nextoffset++; - } else { - $ThisFileInfo['error'] .= "\n".'Did not find expected free-format sync pattern at offset '.$nextoffset; - return false; - } - $nextoffset += $framelength; - } - if (count($ActualFrameLengthValues) > 0) { - $framelength = round(array_sum($ActualFrameLengthValues) / count($ActualFrameLengthValues)); - } - } - return $framelength; + if ($framelength1 > 4) { + $framelength = $framelength1; + } + if (($framelength2 > 4) && ($framelength2 < $framelength1)) { + $framelength = $framelength2; + } + if (!$framelength) { + $ThisFileInfo['error'] .= "\n".'Cannot find next free-format synch pattern ('.PrintHexBytes($SyncPattern1).' or '.PrintHexBytes($SyncPattern2).') after offset '.$offset; + return false; + } else { + $ThisFileInfo['warning'] .= "\n".'ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)'; + $ThisFileInfo['audio']['codec'] = 'LAME'; + $ThisFileInfo['audio']['encoder'] = 'LAME3.88'; + $SyncPattern1 = substr($SyncPattern1, 0, 3); + $SyncPattern2 = substr($SyncPattern2, 0, 3); + } + } + + if ($deepscan) { + + $ActualFrameLengthValues = array(); + $nextoffset = $offset + $framelength; + while ($nextoffset < ($ThisFileInfo['avdataend'] - 6)) { + fseek($fd, $nextoffset - 1, SEEK_SET); + $NextSyncPattern = fread($fd, 6); + if ((substr($NextSyncPattern, 1, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 1, strlen($SyncPattern2)) == $SyncPattern2)) { + // good - found where expected + $ActualFrameLengthValues[] = $framelength; + } elseif ((substr($NextSyncPattern, 0, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 0, strlen($SyncPattern2)) == $SyncPattern2)) { + // ok - found one byte earlier than expected (last frame wasn't padded, first frame was) + $ActualFrameLengthValues[] = ($framelength - 1); + $nextoffset--; + } elseif ((substr($NextSyncPattern, 2, strlen($SyncPattern1)) == $SyncPattern1) || (substr($NextSyncPattern, 2, strlen($SyncPattern2)) == $SyncPattern2)) { + // ok - found one byte later than expected (last frame was padded, first frame wasn't) + $ActualFrameLengthValues[] = ($framelength + 1); + $nextoffset++; + } else { + $ThisFileInfo['error'] .= "\n".'Did not find expected free-format sync pattern at offset '.$nextoffset; + return false; + } + $nextoffset += $framelength; + } + if (count($ActualFrameLengthValues) > 0) { + $framelength = round(array_sum($ActualFrameLengthValues) / count($ActualFrameLengthValues)); + } + } + return $framelength; } -function getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram = false) -{ - // looks for synch, decodes MPEG audio header +function getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram=false) { + // looks for synch, decodes MPEG audio header - fseek($fd, $avdataoffset, SEEK_SET); - $header = ''; - $SynchSeekOffset = 0; + fseek($fd, $avdataoffset, SEEK_SET); + $header = ''; + $SynchSeekOffset = 0; - if (!defined('CONST_FF')) { - define('CONST_FF', chr(0xFF)); - define('CONST_E0', chr(0xE0)); - } + if (!defined('CONST_FF')) { + define('CONST_FF', chr(0xFF)); + define('CONST_E0', chr(0xE0)); + } - static $MPEGaudioVersionLookup; - static $MPEGaudioLayerLookup; - static $MPEGaudioBitrateLookup; - if (empty($MPEGaudioVersionLookup)) { - $MPEGaudioVersionLookup = MPEGaudioVersionArray(); - $MPEGaudioLayerLookup = MPEGaudioLayerArray(); - $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); - } + static $MPEGaudioVersionLookup; + static $MPEGaudioLayerLookup; + static $MPEGaudioBitrateLookup; + if (empty($MPEGaudioVersionLookup)) { + $MPEGaudioVersionLookup = MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); - $header_len = strlen($header) - round(32768 / 2); - while (true) { - if (($SynchSeekOffset > $header_len) && (($avdataoffset + $SynchSeekOffset) < $ThisFileInfo['avdataend']) && !feof($fd)) { - if ($SynchSeekOffset > 131072) { - // if a synch's not found within the first 128k bytes, then give up - $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch within the first 131072 bytes'; - if (isset($ThisFileInfo['audio']['bitrate'])) { - unset($ThisFileInfo['audio']['bitrate']); - } - if (isset($ThisFileInfo['mpeg']['audio'])) { - unset($ThisFileInfo['mpeg']['audio']); - } - if (isset($ThisFileInfo['mpeg']) && (!is_array($ThisFileInfo['mpeg']) || (count($ThisFileInfo['mpeg']) == 0))) { - unset($ThisFileInfo['mpeg']); - } - return false; - } elseif ($header .= fread($fd, 32768)) { - // great - $header_len = strlen($header) - round(32768 / 2); - } else { - $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch before end of file'; - if (isset($ThisFileInfo['audio']['bitrate'])) { - unset($ThisFileInfo['audio']['bitrate']); - } - if (isset($ThisFileInfo['mpeg']['audio'])) { - unset($ThisFileInfo['mpeg']['audio']); - } - if (isset($ThisFileInfo['mpeg']) && (!is_array($ThisFileInfo['mpeg']) || (count($ThisFileInfo['mpeg']) == 0))) { - unset($ThisFileInfo['mpeg']); - } - return false; - } - } + } - if (($SynchSeekOffset + 1) >= strlen($header)) { - $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch before end of file'; - return false; - } + $header_len = strlen($header) - round(32768 / 2); + while (true) { - if (($header{$SynchSeekOffset} == CONST_FF) && ($header{($SynchSeekOffset + 1)} > CONST_E0)) { // synch detected + if (($SynchSeekOffset > $header_len) && (($avdataoffset + $SynchSeekOffset) < $ThisFileInfo['avdataend']) && !feof($fd)) { - if (!isset($FirstFrameThisfileInfo) && !isset($ThisFileInfo['mpeg']['audio'])) { - $FirstFrameThisfileInfo = $ThisFileInfo; - $FirstFrameAVDataOffset = $avdataoffset + $SynchSeekOffset; - if (!decodeMPEGaudioHeader($fd, $avdataoffset + $SynchSeekOffset, $FirstFrameThisfileInfo, false)) { - // if this is the first valid MPEG-audio frame, save it in case it's a VBR header frame and there's - // garbage between this frame and a valid sequence of MPEG-audio frames, to be restored below - unset($FirstFrameThisfileInfo); - } - } - $dummy = $ThisFileInfo; // only overwrite real data if valid header found + if ($SynchSeekOffset > 131072) { + // if a synch's not found within the first 128k bytes, then give up + $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch within the first 131072 bytes'; + if (isset($ThisFileInfo['audio']['bitrate'])) { + unset($ThisFileInfo['audio']['bitrate']); + } + if (isset($ThisFileInfo['mpeg']['audio'])) { + unset($ThisFileInfo['mpeg']['audio']); + } + if (isset($ThisFileInfo['mpeg']) && (!is_array($ThisFileInfo['mpeg']) || (count($ThisFileInfo['mpeg']) == 0))) { + unset($ThisFileInfo['mpeg']); + } + return false; - if (decodeMPEGaudioHeader($fd, $avdataoffset + $SynchSeekOffset, $dummy, true)) { - $ThisFileInfo = $dummy; - $ThisFileInfo['avdataoffset'] = $avdataoffset + $SynchSeekOffset; - switch ($ThisFileInfo['fileformat']) { - case '': - case 'id3': - case 'ape': - case 'mp3': - $ThisFileInfo['fileformat'] = 'mp3'; - $ThisFileInfo['audio']['dataformat'] = 'mp3'; - } - if (isset($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode']) && ($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr')) { - if (!CloseMatch($ThisFileInfo['audio']['bitrate'], $FirstFrameThisfileInfo['audio']['bitrate'], 1)) { - // If there is garbage data between a valid VBR header frame and a sequence - // of valid MPEG-audio frames the VBR data is no longer discarded. - $ThisFileInfo = $FirstFrameThisfileInfo; - $ThisFileInfo['avdataoffset'] = $FirstFrameAVDataOffset; - $ThisFileInfo['fileformat'] = 'mp3'; - $ThisFileInfo['audio']['dataformat'] = 'mp3'; - $dummy = $ThisFileInfo; - unset($dummy['mpeg']['audio']); - $GarbageOffsetStart = $FirstFrameAVDataOffset + $FirstFrameThisfileInfo['mpeg']['audio']['framelength']; - $GarbageOffsetEnd = $avdataoffset + $SynchSeekOffset; - if (decodeMPEGaudioHeader($fd, $GarbageOffsetEnd, $dummy, true, true)) { - $ThisFileInfo = $dummy; - $ThisFileInfo['avdataoffset'] = $GarbageOffsetEnd; - $ThisFileInfo['warning'] .= "\n".'apparently-valid VBR header not used because could not find '.MPEG_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd; - } else { - $ThisFileInfo['warning'] .= "\n".'using data from VBR header even though could not find '.MPEG_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')'; - } - } - } + } elseif ($header .= fread($fd, 32768)) { - if (isset($ThisFileInfo['mpeg']['audio']['bitrate_mode']) && ($ThisFileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr') && !isset($ThisFileInfo['mpeg']['audio']['VBR_method'])) { - // VBR file with no VBR header - $BitrateHistogram = true; - } + // great + $header_len = strlen($header) - round(32768 / 2); - if ($BitrateHistogram) { - $ThisFileInfo['mpeg']['audio']['stereo_distribution'] = ['stereo'=>0, 'joint stereo'=>0, 'dual channel'=>0, 'mono'=>0]; - $ThisFileInfo['mpeg']['audio']['version_distribution'] = ['1'=>0, '2'=>0, '2.5'=>0]; + } else { - if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { - if ($ThisFileInfo['mpeg']['audio']['layer'] == 'III') { - $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = ['free'=>0, 32=>0, 40=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 160=>0, 192=>0, 224=>0, 256=>0, 320=>0]; - } elseif ($ThisFileInfo['mpeg']['audio']['layer'] == 'II') { - $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = ['free'=>0, 32=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 160=>0, 192=>0, 224=>0, 256=>0, 320=>0, 384=>0]; - } elseif ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { - $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = ['free'=>0, 32=>0, 64=>0, 96=>0, 128=>0, 160=>0, 192=>0, 224=>0, 256=>0, 288=>0, 320=>0, 352=>0, 384=>0, 416=>0, 448=>0]; - } - } elseif ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { - $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = ['free'=>0, 32=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 144=>0, 160=>0, 176=>0, 192=>0, 224=>0, 256=>0]; - } else { - $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = ['free'=>0, 8=>0, 16=>0, 24=>0, 32=>0, 40=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 144=>0, 160=>0]; - } + $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch before end of file'; + if (isset($ThisFileInfo['audio']['bitrate'])) { + unset($ThisFileInfo['audio']['bitrate']); + } + if (isset($ThisFileInfo['mpeg']['audio'])) { + unset($ThisFileInfo['mpeg']['audio']); + } + if (isset($ThisFileInfo['mpeg']) && (!is_array($ThisFileInfo['mpeg']) || (count($ThisFileInfo['mpeg']) == 0))) { + unset($ThisFileInfo['mpeg']); + } + return false; - $dummy = ['error'=>$ThisFileInfo['error'], 'warning'=>$ThisFileInfo['warning'], 'avdataend'=>$ThisFileInfo['avdataend'], 'avdataoffset'=>$ThisFileInfo['avdataoffset']]; - $synchstartoffset = $ThisFileInfo['avdataoffset']; + } + } - $FastMode = false; - while (decodeMPEGaudioHeader($fd, $synchstartoffset, $dummy, false, false, $FastMode)) { - $FastMode = true; - $thisframebitrate = $MPEGaudioBitrateLookup[$MPEGaudioVersionLookup[$dummy['mpeg']['audio']['raw']['version']]][$MPEGaudioLayerLookup[$dummy['mpeg']['audio']['raw']['layer']]][$dummy['mpeg']['audio']['raw']['bitrate']]; + if (($SynchSeekOffset + 1) >= strlen($header)) { + $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch before end of file'; + return false; + } - $ThisFileInfo['mpeg']['audio']['bitrate_distribution'][$thisframebitrate]++; - $ThisFileInfo['mpeg']['audio']['stereo_distribution'][$dummy['mpeg']['audio']['channelmode']]++; - $ThisFileInfo['mpeg']['audio']['version_distribution'][$dummy['mpeg']['audio']['version']]++; - if (empty($dummy['mpeg']['audio']['framelength'])) { - $ThisFileInfo['warning'] .= "\n".'Invalid/missing framelength in histogram analysis - aborting'; - $synchstartoffset += 4; + if (($header{$SynchSeekOffset} == CONST_FF) && ($header{($SynchSeekOffset + 1)} > CONST_E0)) { // synch detected + + if (!isset($FirstFrameThisfileInfo) && !isset($ThisFileInfo['mpeg']['audio'])) { + $FirstFrameThisfileInfo = $ThisFileInfo; + $FirstFrameAVDataOffset = $avdataoffset + $SynchSeekOffset; + if (!decodeMPEGaudioHeader($fd, $avdataoffset + $SynchSeekOffset, $FirstFrameThisfileInfo, false)) { + // if this is the first valid MPEG-audio frame, save it in case it's a VBR header frame and there's + // garbage between this frame and a valid sequence of MPEG-audio frames, to be restored below + unset($FirstFrameThisfileInfo); + } + } + $dummy = $ThisFileInfo; // only overwrite real data if valid header found + + if (decodeMPEGaudioHeader($fd, $avdataoffset + $SynchSeekOffset, $dummy, true)) { + + $ThisFileInfo = $dummy; + $ThisFileInfo['avdataoffset'] = $avdataoffset + $SynchSeekOffset; + switch ($ThisFileInfo['fileformat']) { + case '': + case 'id3': + case 'ape': + case 'mp3': + $ThisFileInfo['fileformat'] = 'mp3'; + $ThisFileInfo['audio']['dataformat'] = 'mp3'; + } + if (isset($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode']) && ($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr')) { + if (!CloseMatch($ThisFileInfo['audio']['bitrate'], $FirstFrameThisfileInfo['audio']['bitrate'], 1)) { + // If there is garbage data between a valid VBR header frame and a sequence + // of valid MPEG-audio frames the VBR data is no longer discarded. + $ThisFileInfo = $FirstFrameThisfileInfo; + $ThisFileInfo['avdataoffset'] = $FirstFrameAVDataOffset; + $ThisFileInfo['fileformat'] = 'mp3'; + $ThisFileInfo['audio']['dataformat'] = 'mp3'; + $dummy = $ThisFileInfo; + unset($dummy['mpeg']['audio']); + $GarbageOffsetStart = $FirstFrameAVDataOffset + $FirstFrameThisfileInfo['mpeg']['audio']['framelength']; + $GarbageOffsetEnd = $avdataoffset + $SynchSeekOffset; + if (decodeMPEGaudioHeader($fd, $GarbageOffsetEnd, $dummy, true, true)) { + + $ThisFileInfo = $dummy; + $ThisFileInfo['avdataoffset'] = $GarbageOffsetEnd; + $ThisFileInfo['warning'] .= "\n".'apparently-valid VBR header not used because could not find '.MPEG_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd; + + } else { + + $ThisFileInfo['warning'] .= "\n".'using data from VBR header even though could not find '.MPEG_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')'; + + } + } + } + + if (isset($ThisFileInfo['mpeg']['audio']['bitrate_mode']) && ($ThisFileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr') && !isset($ThisFileInfo['mpeg']['audio']['VBR_method'])) { + // VBR file with no VBR header + $BitrateHistogram = true; + } + + if ($BitrateHistogram) { + + $ThisFileInfo['mpeg']['audio']['stereo_distribution'] = array('stereo'=>0, 'joint stereo'=>0, 'dual channel'=>0, 'mono'=>0); + $ThisFileInfo['mpeg']['audio']['version_distribution'] = array('1'=>0, '2'=>0, '2.5'=>0); + + if ($ThisFileInfo['mpeg']['audio']['version'] == '1') { + if ($ThisFileInfo['mpeg']['audio']['layer'] == 'III') { + $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32=>0, 40=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 160=>0, 192=>0, 224=>0, 256=>0, 320=>0); + } elseif ($ThisFileInfo['mpeg']['audio']['layer'] == 'II') { + $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 160=>0, 192=>0, 224=>0, 256=>0, 320=>0, 384=>0); + } elseif ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { + $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32=>0, 64=>0, 96=>0, 128=>0, 160=>0, 192=>0, 224=>0, 256=>0, 288=>0, 320=>0, 352=>0, 384=>0, 416=>0, 448=>0); + } + } elseif ($ThisFileInfo['mpeg']['audio']['layer'] == 'I') { + $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 32=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 144=>0, 160=>0, 176=>0, 192=>0, 224=>0, 256=>0); + } else { + $ThisFileInfo['mpeg']['audio']['bitrate_distribution'] = array('free'=>0, 8=>0, 16=>0, 24=>0, 32=>0, 40=>0, 48=>0, 56=>0, 64=>0, 80=>0, 96=>0, 112=>0, 128=>0, 144=>0, 160=>0); + } + + $dummy = array('error'=>$ThisFileInfo['error'], 'warning'=>$ThisFileInfo['warning'], 'avdataend'=>$ThisFileInfo['avdataend'], 'avdataoffset'=>$ThisFileInfo['avdataoffset']); + $synchstartoffset = $ThisFileInfo['avdataoffset']; + + $FastMode = false; + while (decodeMPEGaudioHeader($fd, $synchstartoffset, $dummy, false, false, $FastMode)) { + $FastMode = true; + $thisframebitrate = $MPEGaudioBitrateLookup[$MPEGaudioVersionLookup[$dummy['mpeg']['audio']['raw']['version']]][$MPEGaudioLayerLookup[$dummy['mpeg']['audio']['raw']['layer']]][$dummy['mpeg']['audio']['raw']['bitrate']]; + + $ThisFileInfo['mpeg']['audio']['bitrate_distribution'][$thisframebitrate]++; + $ThisFileInfo['mpeg']['audio']['stereo_distribution'][$dummy['mpeg']['audio']['channelmode']]++; + $ThisFileInfo['mpeg']['audio']['version_distribution'][$dummy['mpeg']['audio']['version']]++; + if (empty($dummy['mpeg']['audio']['framelength'])) { + $ThisFileInfo['warning'] .= "\n".'Invalid/missing framelength in histogram analysis - aborting'; +$synchstartoffset += 4; // return false; - } - $synchstartoffset += $dummy['mpeg']['audio']['framelength']; - } + } + $synchstartoffset += $dummy['mpeg']['audio']['framelength']; + } - $bittotal = 0; - $framecounter = 0; - foreach ($ThisFileInfo['mpeg']['audio']['bitrate_distribution'] as $bitratevalue => $bitratecount) { - $framecounter += $bitratecount; - if ($bitratevalue != 'free') { - $bittotal += ($bitratevalue * $bitratecount); - } - } - if ($framecounter == 0) { - $ThisFileInfo['error'] .= "\n".'Corrupt MP3 file: framecounter == zero'; - return false; - } - $ThisFileInfo['mpeg']['audio']['frame_count'] = $framecounter; - $ThisFileInfo['mpeg']['audio']['bitrate'] = 1000 * ($bittotal / $framecounter); + $bittotal = 0; + $framecounter = 0; + foreach ($ThisFileInfo['mpeg']['audio']['bitrate_distribution'] as $bitratevalue => $bitratecount) { + $framecounter += $bitratecount; + if ($bitratevalue != 'free') { + $bittotal += ($bitratevalue * $bitratecount); + } + } + if ($framecounter == 0) { + $ThisFileInfo['error'] .= "\n".'Corrupt MP3 file: framecounter == zero'; + return false; + } + $ThisFileInfo['mpeg']['audio']['frame_count'] = $framecounter; + $ThisFileInfo['mpeg']['audio']['bitrate'] = 1000 * ($bittotal / $framecounter); - $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate']; + $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate']; - // Definitively set VBR vs CBR, even if the Xing/LAME/VBRI header says differently - $distinct_bitrates = 0; - foreach ($ThisFileInfo['mpeg']['audio']['bitrate_distribution'] as $bitrate_value => $bitrate_count) { - if ($bitrate_count > 0) { - $distinct_bitrates++; - } - } - if ($distinct_bitrates > 1) { - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; - } else { - $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; - } - $ThisFileInfo['audio']['bitrate_mode'] = $ThisFileInfo['mpeg']['audio']['bitrate_mode']; - } + // Definitively set VBR vs CBR, even if the Xing/LAME/VBRI header says differently + $distinct_bitrates = 0; + foreach ($ThisFileInfo['mpeg']['audio']['bitrate_distribution'] as $bitrate_value => $bitrate_count) { + if ($bitrate_count > 0) { + $distinct_bitrates++; + } + } + if ($distinct_bitrates > 1) { + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'vbr'; + } else { + $ThisFileInfo['mpeg']['audio']['bitrate_mode'] = 'cbr'; + } + $ThisFileInfo['audio']['bitrate_mode'] = $ThisFileInfo['mpeg']['audio']['bitrate_mode']; - break; // exit while() - } - } + } - $SynchSeekOffset++; - if (($avdataoffset + $SynchSeekOffset) >= $ThisFileInfo['avdataend']) { - // end of file/data + break; // exit while() + } + } - if (empty($ThisFileInfo['mpeg']['audio'])) { - $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch before end of file'; - if (isset($ThisFileInfo['audio']['bitrate'])) { - unset($ThisFileInfo['audio']['bitrate']); - } - if (isset($ThisFileInfo['mpeg']['audio'])) { - unset($ThisFileInfo['mpeg']['audio']); - } - if (isset($ThisFileInfo['mpeg']) && (!is_array($ThisFileInfo['mpeg']) || empty($ThisFileInfo['mpeg']))) { - unset($ThisFileInfo['mpeg']); - } - return false; - } - break; - } - } - $ThisFileInfo['audio']['bits_per_sample'] = 16; - $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels']; - $ThisFileInfo['audio']['channelmode'] = $ThisFileInfo['mpeg']['audio']['channelmode']; - $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate']; - return true; + $SynchSeekOffset++; + if (($avdataoffset + $SynchSeekOffset) >= $ThisFileInfo['avdataend']) { + // end of file/data + + if (empty($ThisFileInfo['mpeg']['audio'])) { + + $ThisFileInfo['error'] .= "\n".'could not find valid MPEG synch before end of file'; + if (isset($ThisFileInfo['audio']['bitrate'])) { + unset($ThisFileInfo['audio']['bitrate']); + } + if (isset($ThisFileInfo['mpeg']['audio'])) { + unset($ThisFileInfo['mpeg']['audio']); + } + if (isset($ThisFileInfo['mpeg']) && (!is_array($ThisFileInfo['mpeg']) || empty($ThisFileInfo['mpeg']))) { + unset($ThisFileInfo['mpeg']); + } + return false; + + } + break; + } + + } + $ThisFileInfo['audio']['bits_per_sample'] = 16; + $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels']; + $ThisFileInfo['audio']['channelmode'] = $ThisFileInfo['mpeg']['audio']['channelmode']; + $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate']; + return true; } -function MPEGaudioVersionArray() -{ - static $MPEGaudioVersion = ['2.5', false, '2', '1']; - return $MPEGaudioVersion; +function MPEGaudioVersionArray() { + static $MPEGaudioVersion = array('2.5', false, '2', '1'); + return $MPEGaudioVersion; } -function MPEGaudioLayerArray() -{ - static $MPEGaudioLayer = [false, 'III', 'II', 'I']; - return $MPEGaudioLayer; +function MPEGaudioLayerArray() { + static $MPEGaudioLayer = array(false, 'III', 'II', 'I'); + return $MPEGaudioLayer; } -function MPEGaudioBitrateArray() -{ - static $MPEGaudioBitrate; - if (empty($MPEGaudioBitrate)) { - $MPEGaudioBitrate['1']['I'] = ['free', 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448]; - $MPEGaudioBitrate['1']['II'] = ['free', 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384]; - $MPEGaudioBitrate['1']['III'] = ['free', 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320]; - $MPEGaudioBitrate['2']['I'] = ['free', 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256]; - $MPEGaudioBitrate['2']['II'] = ['free', 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160]; - $MPEGaudioBitrate['2']['III'] = $MPEGaudioBitrate['2']['II']; - $MPEGaudioBitrate['2.5']['I'] = $MPEGaudioBitrate['2']['I']; - $MPEGaudioBitrate['2.5']['II'] = $MPEGaudioBitrate['2']['II']; - $MPEGaudioBitrate['2.5']['III'] = $MPEGaudioBitrate['2']['III']; - } - return $MPEGaudioBitrate; +function MPEGaudioBitrateArray() { + static $MPEGaudioBitrate; + if (empty($MPEGaudioBitrate)) { + $MPEGaudioBitrate['1']['I'] = array('free', 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448); + $MPEGaudioBitrate['1']['II'] = array('free', 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384); + $MPEGaudioBitrate['1']['III'] = array('free', 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320); + $MPEGaudioBitrate['2']['I'] = array('free', 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256); + $MPEGaudioBitrate['2']['II'] = array('free', 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160); + $MPEGaudioBitrate['2']['III'] = $MPEGaudioBitrate['2']['II']; + $MPEGaudioBitrate['2.5']['I'] = $MPEGaudioBitrate['2']['I']; + $MPEGaudioBitrate['2.5']['II'] = $MPEGaudioBitrate['2']['II']; + $MPEGaudioBitrate['2.5']['III'] = $MPEGaudioBitrate['2']['III']; + } + return $MPEGaudioBitrate; } -function MPEGaudioFrequencyArray() -{ - static $MPEGaudioFrequency; - if (empty($MPEGaudioFrequency)) { - $MPEGaudioFrequency['1'] = [44100, 48000, 32000]; - $MPEGaudioFrequency['2'] = [22050, 24000, 16000]; - $MPEGaudioFrequency['2.5'] = [11025, 12000, 8000]; - } - return $MPEGaudioFrequency; +function MPEGaudioFrequencyArray() { + static $MPEGaudioFrequency; + if (empty($MPEGaudioFrequency)) { + $MPEGaudioFrequency['1'] = array(44100, 48000, 32000); + $MPEGaudioFrequency['2'] = array(22050, 24000, 16000); + $MPEGaudioFrequency['2.5'] = array(11025, 12000, 8000); + } + return $MPEGaudioFrequency; } -function MPEGaudioChannelModeArray() -{ - static $MPEGaudioChannelMode = ['stereo', 'joint stereo', 'dual channel', 'mono']; - return $MPEGaudioChannelMode; +function MPEGaudioChannelModeArray() { + static $MPEGaudioChannelMode = array('stereo', 'joint stereo', 'dual channel', 'mono'); + return $MPEGaudioChannelMode; } -function MPEGaudioModeExtensionArray() -{ - static $MPEGaudioModeExtension; - if (empty($MPEGaudioModeExtension)) { - $MPEGaudioModeExtension['I'] = ['4-31', '8-31', '12-31', '16-31']; - $MPEGaudioModeExtension['II'] = ['4-31', '8-31', '12-31', '16-31']; - $MPEGaudioModeExtension['III'] = ['', 'IS', 'MS', 'IS+MS']; - } - return $MPEGaudioModeExtension; +function MPEGaudioModeExtensionArray() { + static $MPEGaudioModeExtension; + if (empty($MPEGaudioModeExtension)) { + $MPEGaudioModeExtension['I'] = array('4-31', '8-31', '12-31', '16-31'); + $MPEGaudioModeExtension['II'] = array('4-31', '8-31', '12-31', '16-31'); + $MPEGaudioModeExtension['III'] = array('', 'IS', 'MS', 'IS+MS'); + } + return $MPEGaudioModeExtension; } -function MPEGaudioEmphasisArray() -{ - static $MPEGaudioEmphasis = ['none', '50/15ms', false, 'CCIT J.17']; - return $MPEGaudioEmphasis; +function MPEGaudioEmphasisArray() { + static $MPEGaudioEmphasis = array('none', '50/15ms', false, 'CCIT J.17'); + return $MPEGaudioEmphasis; } -function MPEGaudioHeaderBytesValid($head4) -{ - return MPEGaudioHeaderValid(MPEGaudioHeaderDecode($head4)); +function MPEGaudioHeaderBytesValid($head4) { + return MPEGaudioHeaderValid(MPEGaudioHeaderDecode($head4)); } -function MPEGaudioHeaderValid($rawarray, $echoerrors = false) -{ +function MPEGaudioHeaderValid($rawarray, $echoerrors=false) { - if (($rawarray['synch'] & 0x0FFE) != 0x0FFE) { - return false; - } + if (($rawarray['synch'] & 0x0FFE) != 0x0FFE) { + return false; + } - static $MPEGaudioVersionLookup; - static $MPEGaudioLayerLookup; - static $MPEGaudioBitrateLookup; - static $MPEGaudioFrequencyLookup; - static $MPEGaudioChannelModeLookup; - static $MPEGaudioModeExtensionLookup; - static $MPEGaudioEmphasisLookup; - if (empty($MPEGaudioVersionLookup)) { - $MPEGaudioVersionLookup = MPEGaudioVersionArray(); - $MPEGaudioLayerLookup = MPEGaudioLayerArray(); - $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); - $MPEGaudioFrequencyLookup = MPEGaudioFrequencyArray(); - $MPEGaudioChannelModeLookup = MPEGaudioChannelModeArray(); - $MPEGaudioModeExtensionLookup = MPEGaudioModeExtensionArray(); - $MPEGaudioEmphasisLookup = MPEGaudioEmphasisArray(); - } + static $MPEGaudioVersionLookup; + static $MPEGaudioLayerLookup; + static $MPEGaudioBitrateLookup; + static $MPEGaudioFrequencyLookup; + static $MPEGaudioChannelModeLookup; + static $MPEGaudioModeExtensionLookup; + static $MPEGaudioEmphasisLookup; + if (empty($MPEGaudioVersionLookup)) { + $MPEGaudioVersionLookup = MPEGaudioVersionArray(); + $MPEGaudioLayerLookup = MPEGaudioLayerArray(); + $MPEGaudioBitrateLookup = MPEGaudioBitrateArray(); + $MPEGaudioFrequencyLookup = MPEGaudioFrequencyArray(); + $MPEGaudioChannelModeLookup = MPEGaudioChannelModeArray(); + $MPEGaudioModeExtensionLookup = MPEGaudioModeExtensionArray(); + $MPEGaudioEmphasisLookup = MPEGaudioEmphasisArray(); + } - if (isset($MPEGaudioVersionLookup[$rawarray['version']])) { - $decodedVersion = $MPEGaudioVersionLookup[$rawarray['version']]; - } else { - if ($echoerrors) { - echo "\n".'invalid Version ('.$rawarray['version'].')'; - } - return false; - } - if (isset($MPEGaudioLayerLookup[$rawarray['layer']])) { - $decodedLayer = $MPEGaudioLayerLookup[$rawarray['layer']]; - } else { - if ($echoerrors) { - echo "\n".'invalid Layer ('.$rawarray['layer'].')'; - } - return false; - } - if (!isset($MPEGaudioBitrateLookup[$decodedVersion][$decodedLayer][$rawarray['bitrate']])) { - if ($echoerrors) { - echo "\n".'invalid Bitrate ('.$rawarray['bitrate'].')'; - } - if ($rawarray['bitrate'] == 15) { - // known issue in LAME 3.90 - 3.93.1 where free-format has bitrate ID of 15 instead of 0 - // let it go through here otherwise file will not be identified - } else { - return false; - } - } - if (!isset($MPEGaudioFrequencyLookup[$decodedVersion][$rawarray['sample_rate']])) { - if ($echoerrors) { - echo "\n".'invalid Frequency ('.$rawarray['sample_rate'].')'; - } - return false; - } - if (!isset($MPEGaudioChannelModeLookup[$rawarray['channelmode']])) { - if ($echoerrors) { - echo "\n".'invalid ChannelMode ('.$rawarray['channelmode'].')'; - } - return false; - } - if (!isset($MPEGaudioModeExtensionLookup[$decodedLayer][$rawarray['modeextension']])) { - if ($echoerrors) { - echo "\n".'invalid Mode Extension ('.$rawarray['modeextension'].')'; - } - return false; - } - if (!isset($MPEGaudioEmphasisLookup[$rawarray['emphasis']])) { - if ($echoerrors) { - echo "\n".'invalid Emphasis ('.$rawarray['emphasis'].')'; - } - return false; - } - // These are just either set or not set, you can't mess that up :) - // $rawarray['protection']; - // $rawarray['padding']; - // $rawarray['private']; - // $rawarray['copyright']; - // $rawarray['original']; + if (isset($MPEGaudioVersionLookup[$rawarray['version']])) { + $decodedVersion = $MPEGaudioVersionLookup[$rawarray['version']]; + } else { + if ($echoerrors) { + echo "\n".'invalid Version ('.$rawarray['version'].')'; + } + return false; + } + if (isset($MPEGaudioLayerLookup[$rawarray['layer']])) { + $decodedLayer = $MPEGaudioLayerLookup[$rawarray['layer']]; + } else { + if ($echoerrors) { + echo "\n".'invalid Layer ('.$rawarray['layer'].')'; + } + return false; + } + if (!isset($MPEGaudioBitrateLookup[$decodedVersion][$decodedLayer][$rawarray['bitrate']])) { + if ($echoerrors) { + echo "\n".'invalid Bitrate ('.$rawarray['bitrate'].')'; + } + if ($rawarray['bitrate'] == 15) { + // known issue in LAME 3.90 - 3.93.1 where free-format has bitrate ID of 15 instead of 0 + // let it go through here otherwise file will not be identified + } else { + return false; + } + } + if (!isset($MPEGaudioFrequencyLookup[$decodedVersion][$rawarray['sample_rate']])) { + if ($echoerrors) { + echo "\n".'invalid Frequency ('.$rawarray['sample_rate'].')'; + } + return false; + } + if (!isset($MPEGaudioChannelModeLookup[$rawarray['channelmode']])) { + if ($echoerrors) { + echo "\n".'invalid ChannelMode ('.$rawarray['channelmode'].')'; + } + return false; + } + if (!isset($MPEGaudioModeExtensionLookup[$decodedLayer][$rawarray['modeextension']])) { + if ($echoerrors) { + echo "\n".'invalid Mode Extension ('.$rawarray['modeextension'].')'; + } + return false; + } + if (!isset($MPEGaudioEmphasisLookup[$rawarray['emphasis']])) { + if ($echoerrors) { + echo "\n".'invalid Emphasis ('.$rawarray['emphasis'].')'; + } + return false; + } + // These are just either set or not set, you can't mess that up :) + // $rawarray['protection']; + // $rawarray['padding']; + // $rawarray['private']; + // $rawarray['copyright']; + // $rawarray['original']; - return true; + return true; } -function MPEGaudioHeaderDecode($Header4Bytes) -{ - // AAAA AAAA AAAB BCCD EEEE FFGH IIJJ KLMM - // A - Frame sync (all bits set) - // B - MPEG Audio version ID - // C - Layer description - // D - Protection bit - // E - Bitrate index - // F - Sampling rate frequency index - // G - Padding bit - // H - Private bit - // I - Channel Mode - // J - Mode extension (Only if Joint stereo) - // K - Copyright - // L - Original - // M - Emphasis +function MPEGaudioHeaderDecode($Header4Bytes) { + // AAAA AAAA AAAB BCCD EEEE FFGH IIJJ KLMM + // A - Frame sync (all bits set) + // B - MPEG Audio version ID + // C - Layer description + // D - Protection bit + // E - Bitrate index + // F - Sampling rate frequency index + // G - Padding bit + // H - Private bit + // I - Channel Mode + // J - Mode extension (Only if Joint stereo) + // K - Copyright + // L - Original + // M - Emphasis - if (strlen($Header4Bytes) != 4) { - return false; - } + if (strlen($Header4Bytes) != 4) { + return false; + } - $MPEGrawHeader['synch'] = (BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4; - $MPEGrawHeader['version'] = (ord($Header4Bytes{1}) & 0x18) >> 3; // BB - $MPEGrawHeader['layer'] = (ord($Header4Bytes{1}) & 0x06) >> 1; // CC - $MPEGrawHeader['protection'] = (ord($Header4Bytes{1}) & 0x01); // D - $MPEGrawHeader['bitrate'] = (ord($Header4Bytes{2}) & 0xF0) >> 4; // EEEE - $MPEGrawHeader['sample_rate'] = (ord($Header4Bytes{2}) & 0x0C) >> 2; // FF - $MPEGrawHeader['padding'] = (ord($Header4Bytes{2}) & 0x02) >> 1; // G - $MPEGrawHeader['private'] = (ord($Header4Bytes{2}) & 0x01); // H - $MPEGrawHeader['channelmode'] = (ord($Header4Bytes{3}) & 0xC0) >> 6; // II - $MPEGrawHeader['modeextension'] = (ord($Header4Bytes{3}) & 0x30) >> 4; // JJ - $MPEGrawHeader['copyright'] = (ord($Header4Bytes{3}) & 0x08) >> 3; // K - $MPEGrawHeader['original'] = (ord($Header4Bytes{3}) & 0x04) >> 2; // L - $MPEGrawHeader['emphasis'] = (ord($Header4Bytes{3}) & 0x03); // MM + $MPEGrawHeader['synch'] = (BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4; + $MPEGrawHeader['version'] = (ord($Header4Bytes{1}) & 0x18) >> 3; // BB + $MPEGrawHeader['layer'] = (ord($Header4Bytes{1}) & 0x06) >> 1; // CC + $MPEGrawHeader['protection'] = (ord($Header4Bytes{1}) & 0x01); // D + $MPEGrawHeader['bitrate'] = (ord($Header4Bytes{2}) & 0xF0) >> 4; // EEEE + $MPEGrawHeader['sample_rate'] = (ord($Header4Bytes{2}) & 0x0C) >> 2; // FF + $MPEGrawHeader['padding'] = (ord($Header4Bytes{2}) & 0x02) >> 1; // G + $MPEGrawHeader['private'] = (ord($Header4Bytes{2}) & 0x01); // H + $MPEGrawHeader['channelmode'] = (ord($Header4Bytes{3}) & 0xC0) >> 6; // II + $MPEGrawHeader['modeextension'] = (ord($Header4Bytes{3}) & 0x30) >> 4; // JJ + $MPEGrawHeader['copyright'] = (ord($Header4Bytes{3}) & 0x08) >> 3; // K + $MPEGrawHeader['original'] = (ord($Header4Bytes{3}) & 0x04) >> 2; // L + $MPEGrawHeader['emphasis'] = (ord($Header4Bytes{3}) & 0x03); // MM - return $MPEGrawHeader; + return $MPEGrawHeader; } -function MPEGaudioFrameLength(&$bitrate, &$version, &$layer, $padding, &$samplerate) -{ - static $AudioFrameLengthCache = []; +function MPEGaudioFrameLength(&$bitrate, &$version, &$layer, $padding, &$samplerate) { + static $AudioFrameLengthCache = array(); - if (!isset($AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate])) { - $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate] = false; - if ($bitrate != 'free') { - if ($version == '1') { - if ($layer == 'I') { - // For Layer I slot is 32 bits long - $FrameLengthCoefficient = 48; - $SlotLength = 4; - } else { // Layer II / III + if (!isset($AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate])) { + $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate] = false; + if ($bitrate != 'free') { - // for Layer II and Layer III slot is 8 bits long. - $FrameLengthCoefficient = 144; - $SlotLength = 1; - } - } else { // MPEG-2 / MPEG-2.5 + if ($version == '1') { - if ($layer == 'I') { - // For Layer I slot is 32 bits long - $FrameLengthCoefficient = 24; - $SlotLength = 4; - } elseif ($layer == 'II') { - // for Layer II and Layer III slot is 8 bits long. - $FrameLengthCoefficient = 144; - $SlotLength = 1; - } else { // III + if ($layer == 'I') { - // for Layer II and Layer III slot is 8 bits long. - $FrameLengthCoefficient = 72; - $SlotLength = 1; - } - } + // For Layer I slot is 32 bits long + $FrameLengthCoefficient = 48; + $SlotLength = 4; - // FrameLengthInBytes = ((Coefficient * BitRate) / SampleRate) + Padding - // http://66.96.216.160/cgi-bin/YaBB.pl?board=c&action=display&num=1018474068 - // -> [Finding the next frame synch] on www.r3mix.net forums if the above link goes dead - if ($samplerate > 0) { - $NewFramelength = ($FrameLengthCoefficient * $bitrate * 1000) / $samplerate; - $NewFramelength = floor($NewFramelength / $SlotLength) * $SlotLength; // round to next-lower multiple of SlotLength (1 byte for Layer II/III, 4 bytes for Layer I) - if ($padding) { - $NewFramelength += $SlotLength; - } - $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate] = (int) $NewFramelength; - } - } - } - return $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate]; + } else { // Layer II / III + + // for Layer II and Layer III slot is 8 bits long. + $FrameLengthCoefficient = 144; + $SlotLength = 1; + + } + + } else { // MPEG-2 / MPEG-2.5 + + if ($layer == 'I') { + + // For Layer I slot is 32 bits long + $FrameLengthCoefficient = 24; + $SlotLength = 4; + + } elseif ($layer == 'II') { + + // for Layer II and Layer III slot is 8 bits long. + $FrameLengthCoefficient = 144; + $SlotLength = 1; + + } else { // III + + // for Layer II and Layer III slot is 8 bits long. + $FrameLengthCoefficient = 72; + $SlotLength = 1; + + } + + } + + // FrameLengthInBytes = ((Coefficient * BitRate) / SampleRate) + Padding + // http://66.96.216.160/cgi-bin/YaBB.pl?board=c&action=display&num=1018474068 + // -> [Finding the next frame synch] on www.r3mix.net forums if the above link goes dead + if ($samplerate > 0) { + $NewFramelength = ($FrameLengthCoefficient * $bitrate * 1000) / $samplerate; + $NewFramelength = floor($NewFramelength / $SlotLength) * $SlotLength; // round to next-lower multiple of SlotLength (1 byte for Layer II/III, 4 bytes for Layer I) + if ($padding) { + $NewFramelength += $SlotLength; + } + $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate] = (int) $NewFramelength; + } + } + } + return $AudioFrameLengthCache[$bitrate][$version][$layer][$padding][$samplerate]; } -function LAMEvbrMethodLookup($VBRmethodID) -{ - static $LAMEvbrMethodLookup = []; - if (empty($LAMEvbrMethodLookup)) { - $LAMEvbrMethodLookup[0x00] = 'unknown'; - $LAMEvbrMethodLookup[0x01] = 'cbr'; - $LAMEvbrMethodLookup[0x02] = 'abr'; - $LAMEvbrMethodLookup[0x03] = 'vbr-old / vbr-rh'; - $LAMEvbrMethodLookup[0x04] = 'vbr-mtrh'; - $LAMEvbrMethodLookup[0x05] = 'vbr-new / vbr-mt'; - } - return (isset($LAMEvbrMethodLookup[$VBRmethodID]) ? $LAMEvbrMethodLookup[$VBRmethodID] : ''); +function LAMEvbrMethodLookup($VBRmethodID) { + static $LAMEvbrMethodLookup = array(); + if (empty($LAMEvbrMethodLookup)) { + $LAMEvbrMethodLookup[0x00] = 'unknown'; + $LAMEvbrMethodLookup[0x01] = 'cbr'; + $LAMEvbrMethodLookup[0x02] = 'abr'; + $LAMEvbrMethodLookup[0x03] = 'vbr-old / vbr-rh'; + $LAMEvbrMethodLookup[0x04] = 'vbr-mtrh'; + $LAMEvbrMethodLookup[0x05] = 'vbr-new / vbr-mt'; + } + return (isset($LAMEvbrMethodLookup[$VBRmethodID]) ? $LAMEvbrMethodLookup[$VBRmethodID] : ''); } -function LAMEmiscStereoModeLookup($StereoModeID) -{ - static $LAMEmiscStereoModeLookup = []; - if (empty($LAMEmiscStereoModeLookup)) { - $LAMEmiscStereoModeLookup[0] = 'mono'; - $LAMEmiscStereoModeLookup[1] = 'stereo'; - $LAMEmiscStereoModeLookup[2] = 'dual'; - $LAMEmiscStereoModeLookup[3] = 'joint'; - $LAMEmiscStereoModeLookup[4] = 'forced'; - $LAMEmiscStereoModeLookup[5] = 'auto'; - $LAMEmiscStereoModeLookup[6] = 'intensity'; - $LAMEmiscStereoModeLookup[7] = 'other'; - } - return (isset($LAMEmiscStereoModeLookup[$StereoModeID]) ? $LAMEmiscStereoModeLookup[$StereoModeID] : ''); +function LAMEmiscStereoModeLookup($StereoModeID) { + static $LAMEmiscStereoModeLookup = array(); + if (empty($LAMEmiscStereoModeLookup)) { + $LAMEmiscStereoModeLookup[0] = 'mono'; + $LAMEmiscStereoModeLookup[1] = 'stereo'; + $LAMEmiscStereoModeLookup[2] = 'dual'; + $LAMEmiscStereoModeLookup[3] = 'joint'; + $LAMEmiscStereoModeLookup[4] = 'forced'; + $LAMEmiscStereoModeLookup[5] = 'auto'; + $LAMEmiscStereoModeLookup[6] = 'intensity'; + $LAMEmiscStereoModeLookup[7] = 'other'; + } + return (isset($LAMEmiscStereoModeLookup[$StereoModeID]) ? $LAMEmiscStereoModeLookup[$StereoModeID] : ''); } -function LAMEmiscSourceSampleFrequencyLookup($SourceSampleFrequencyID) -{ - static $LAMEmiscSourceSampleFrequencyLookup = []; - if (empty($LAMEmiscSourceSampleFrequencyLookup)) { - $LAMEmiscSourceSampleFrequencyLookup[0] = '<= 32 kHz'; - $LAMEmiscSourceSampleFrequencyLookup[1] = '44.1 kHz'; - $LAMEmiscSourceSampleFrequencyLookup[2] = '48 kHz'; - $LAMEmiscSourceSampleFrequencyLookup[3] = '> 48kHz'; - } - return (isset($LAMEmiscSourceSampleFrequencyLookup[$SourceSampleFrequencyID]) ? $LAMEmiscSourceSampleFrequencyLookup[$SourceSampleFrequencyID] : ''); +function LAMEmiscSourceSampleFrequencyLookup($SourceSampleFrequencyID) { + static $LAMEmiscSourceSampleFrequencyLookup = array(); + if (empty($LAMEmiscSourceSampleFrequencyLookup)) { + $LAMEmiscSourceSampleFrequencyLookup[0] = '<= 32 kHz'; + $LAMEmiscSourceSampleFrequencyLookup[1] = '44.1 kHz'; + $LAMEmiscSourceSampleFrequencyLookup[2] = '48 kHz'; + $LAMEmiscSourceSampleFrequencyLookup[3] = '> 48kHz'; + } + return (isset($LAMEmiscSourceSampleFrequencyLookup[$SourceSampleFrequencyID]) ? $LAMEmiscSourceSampleFrequencyLookup[$SourceSampleFrequencyID] : ''); } -function LAMEsurroundInfoLookup($SurroundInfoID) -{ - static $LAMEsurroundInfoLookup = []; - if (empty($LAMEsurroundInfoLookup)) { - $LAMEsurroundInfoLookup[0] = 'no surround info'; - $LAMEsurroundInfoLookup[1] = 'DPL encoding'; - $LAMEsurroundInfoLookup[2] = 'DPL2 encoding'; - $LAMEsurroundInfoLookup[3] = 'Ambisonic encoding'; - } - return (isset($LAMEsurroundInfoLookup[$SurroundInfoID]) ? $LAMEsurroundInfoLookup[$SurroundInfoID] : 'reserved'); +function LAMEsurroundInfoLookup($SurroundInfoID) { + static $LAMEsurroundInfoLookup = array(); + if (empty($LAMEsurroundInfoLookup)) { + $LAMEsurroundInfoLookup[0] = 'no surround info'; + $LAMEsurroundInfoLookup[1] = 'DPL encoding'; + $LAMEsurroundInfoLookup[2] = 'DPL2 encoding'; + $LAMEsurroundInfoLookup[3] = 'Ambisonic encoding'; + } + return (isset($LAMEsurroundInfoLookup[$SurroundInfoID]) ? $LAMEsurroundInfoLookup[$SurroundInfoID] : 'reserved'); } for ($i = 0x00; $i <= 0xFF; $i++) { - $head4 = "\xFF\xFE".chr($i)."\x00"; - $isvalid = MPEGaudioHeaderBytesValid($head4); - echo '
'.str_pad(strtoupper(dechex($i)), 2, '0', STR_PAD_LEFT).' = '.htmlentities(chr($i)).' = '.($isvalid ? 'valid' : 'INVALID').'
'; + $head4 = "\xFF\xFE".chr($i)."\x00"; + $isvalid = MPEGaudioHeaderBytesValid($head4); + echo '
'.str_pad(strtoupper(dechex($i)), 2, '0', STR_PAD_LEFT).' = '.htmlentities(chr($i)).' = '.($isvalid ? 'valid' : 'INVALID').'
'; } diff --git a/app/Library/getid3/demos/demo.mysql.php b/app/Library/getid3/demos/demo.mysql.php index bff1fc9b..24443994 100644 --- a/app/Library/getid3/demos/demo.mysql.php +++ b/app/Library/getid3/demos/demo.mysql.php @@ -21,1933 +21,2117 @@ $getid3_demo_mysql_encoding = 'ISO-8859-1'; $getid3_demo_mysql_md5_data = false; // All data hashes are by far the slowest part of scanning $getid3_demo_mysql_md5_file = false; -define('GETID3_DB_HOST', 'localhost'); -define('GETID3_DB_USER', 'root'); -define('GETID3_DB_PASS', 'password'); -define('GETID3_DB_DB', 'getid3'); +define('GETID3_DB_HOST', 'localhost'); +define('GETID3_DB_USER', 'root'); +define('GETID3_DB_PASS', 'password'); +define('GETID3_DB_DB', 'getid3'); define('GETID3_DB_TABLE', 'files'); // CREATE DATABASE `getid3`; ob_start(); if (!mysql_connect(GETID3_DB_HOST, GETID3_DB_USER, GETID3_DB_PASS)) { - $errormessage = ob_get_contents(); - ob_end_clean(); - die('Could not connect to MySQL host:
'.mysql_error().'
'); + $errormessage = ob_get_contents(); + ob_end_clean(); + die('Could not connect to MySQL host:
'.mysql_error().'
'); } if (!mysql_select_db(GETID3_DB_DB)) { - $errormessage = ob_get_contents(); - ob_end_clean(); - die('Could not select database:
'.mysql_error().'
'); + $errormessage = ob_get_contents(); + ob_end_clean(); + die('Could not select database:
'.mysql_error().'
'); } ob_end_clean(); $getid3PHP_filename = realpath('../getid3/getid3.php'); if (!file_exists($getid3PHP_filename) || !include_once($getid3PHP_filename)) { - die('Cannot open '.$getid3PHP_filename); + die('Cannot open '.$getid3PHP_filename); } // Initialize getID3 engine $getID3 = new getID3; -$getID3->setOption([ - 'option_md5_data' => $getid3_demo_mysql_md5_data, - 'encoding' => $getid3_demo_mysql_encoding, -]); +$getID3->setOption(array( + 'option_md5_data' => $getid3_demo_mysql_md5_data, + 'encoding' => $getid3_demo_mysql_encoding, +)); -function RemoveAccents($string) -{ - // Revised version by markstewardØhotmail*com - return strtr(strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'), ['Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u']); +function RemoveAccents($string) { + // Revised version by markstewardØhotmail*com + return strtr(strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'), array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u')); } -function BitrateColor($bitrate, $BitrateMaxScale = 768) -{ - // $BitrateMaxScale is bitrate of maximum-quality color (bright green) - // below this is gradient, above is solid green +function BitrateColor($bitrate, $BitrateMaxScale=768) { + // $BitrateMaxScale is bitrate of maximum-quality color (bright green) + // below this is gradient, above is solid green - $bitrate *= (256 / $BitrateMaxScale); // scale from 1-[768]kbps to 1-256 - $bitrate = round(min(max($bitrate, 1), 256)); - $bitrate--; // scale from 1-256kbps to 0-255kbps + $bitrate *= (256 / $BitrateMaxScale); // scale from 1-[768]kbps to 1-256 + $bitrate = round(min(max($bitrate, 1), 256)); + $bitrate--; // scale from 1-256kbps to 0-255kbps - $Rcomponent = max(255 - ($bitrate * 2), 0); - $Gcomponent = max(($bitrate * 2) - 255, 0); - if ($bitrate > 127) { - $Bcomponent = max((255 - $bitrate) * 2, 0); - } else { - $Bcomponent = max($bitrate * 2, 0); - } - return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT); + $Rcomponent = max(255 - ($bitrate * 2), 0); + $Gcomponent = max(($bitrate * 2) - 255, 0); + if ($bitrate > 127) { + $Bcomponent = max((255 - $bitrate) * 2, 0); + } else { + $Bcomponent = max($bitrate * 2, 0); + } + return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT); } -function BitrateText($bitrate, $decimals = 0) -{ - return ''.number_format($bitrate, $decimals).' kbps'; +function BitrateText($bitrate, $decimals=0) { + return ''.number_format($bitrate, $decimals).' kbps'; } -function fileextension($filename, $numextensions = 1) -{ - if (strstr($filename, '.')) { - $reversedfilename = strrev($filename); - $offset = 0; - for ($i = 0; $i < $numextensions; $i++) { - $offset = strpos($reversedfilename, '.', $offset + 1); - if ($offset === false) { - return ''; - } - } - return strrev(substr($reversedfilename, 0, $offset)); - } - return ''; +function fileextension($filename, $numextensions=1) { + if (strstr($filename, '.')) { + $reversedfilename = strrev($filename); + $offset = 0; + for ($i = 0; $i < $numextensions; $i++) { + $offset = strpos($reversedfilename, '.', $offset + 1); + if ($offset === false) { + return ''; + } + } + return strrev(substr($reversedfilename, 0, $offset)); + } + return ''; } -function RenameFileFromTo($from, $to, &$results) -{ - $success = true; - if ($from === $to) { - $results = 'Source and Destination filenames identical
FAILED to rename'; - } elseif (!file_exists($from)) { - $results = 'Source file does not exist
FAILED to rename'; - } elseif (file_exists($to) && (strtolower($from) !== strtolower($to))) { - $results = 'Destination file already exists
FAILED to rename'; - } else { - ob_start(); - if (rename($from, $to)) { - ob_end_clean(); - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($from).'")'; - mysql_query_safe($SQLquery); - $results = 'Successfully renamed'; - } else { - $errormessage = ob_get_contents(); - ob_end_clean(); - $results = '
FAILED to rename'; - $success = false; - } - } - $results .= ' from:
'.$from.'
to:
'.$to.'

'; - return $success; +function RenameFileFromTo($from, $to, &$results) { + $success = true; + if ($from === $to) { + $results = 'Source and Destination filenames identical
FAILED to rename'; + } elseif (!file_exists($from)) { + $results = 'Source file does not exist
FAILED to rename'; + } elseif (file_exists($to) && (strtolower($from) !== strtolower($to))) { + $results = 'Destination file already exists
FAILED to rename'; + } else { + ob_start(); + if (rename($from, $to)) { + ob_end_clean(); + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($from).'")'; + mysql_query_safe($SQLquery); + $results = 'Successfully renamed'; + } else { + $errormessage = ob_get_contents(); + ob_end_clean(); + $results = '
FAILED to rename'; + $success = false; + } + } + $results .= ' from:
'.$from.'
to:
'.$to.'

'; + return $success; } if (!empty($_REQUEST['renamefilefrom']) && !empty($_REQUEST['renamefileto'])) { - $results = ''; - RenameFileFromTo($_REQUEST['renamefilefrom'], $_REQUEST['renamefileto'], $results); - echo $results; - exit; + + $results = ''; + RenameFileFromTo($_REQUEST['renamefilefrom'], $_REQUEST['renamefileto'], $results); + echo $results; + exit; + } elseif (!empty($_REQUEST['m3ufilename'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - echo WindowsShareSlashTranslate($_REQUEST['m3ufilename'])."\n"; - exit; + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + echo WindowsShareSlashTranslate($_REQUEST['m3ufilename'])."\n"; + exit; + } elseif (!isset($_REQUEST['m3u']) && !isset($_REQUEST['m3uartist']) && !isset($_REQUEST['m3utitle'])) { - echo ''; - echo 'getID3() demo - /demo/mysql.php'; + + echo ''; + echo 'getID3() demo - /demo/mysql.php'; + } -function WindowsShareSlashTranslate($filename) -{ - if (substr($filename, 0, 2) == '//') { - return str_replace('/', '\\', $filename); - } - return $filename; +function WindowsShareSlashTranslate($filename) { + if (substr($filename, 0, 2) == '//') { + return str_replace('/', '\\', $filename); + } + return $filename; } -function mysql_query_safe($SQLquery) -{ - static $TimeSpentQuerying = 0; - if ($SQLquery === null) { - return $TimeSpentQuerying; - } - $starttime = microtime(true); - $result = mysql_query($SQLquery); - $TimeSpentQuerying += (microtime(true) - $starttime); - if (mysql_error()) { - die('
SQL error:
'.htmlentities(mysql_error()).'

'.htmlentities($SQLquery).'
'); - } - return $result; +function mysql_query_safe($SQLquery) { + static $TimeSpentQuerying = 0; + if ($SQLquery === null) { + return $TimeSpentQuerying; + } + $starttime = microtime(true); + $result = mysql_query($SQLquery); + $TimeSpentQuerying += (microtime(true) - $starttime); + if (mysql_error()) { + die('
SQL error:
'.htmlentities(mysql_error()).'

'.htmlentities($SQLquery).'
'); + } + return $result; } -function mysql_table_exists($tablename) -{ - return (bool) mysql_query('DESCRIBE '.$tablename); +function mysql_table_exists($tablename) { + return (bool) mysql_query('DESCRIBE '.$tablename); } -function AcceptableExtensions($fileformat, $audio_dataformat = '', $video_dataformat = '') -{ - static $AcceptableExtensionsAudio = []; - if (empty($AcceptableExtensionsAudio)) { - $AcceptableExtensionsAudio['mp3']['mp3'] = ['mp3']; - $AcceptableExtensionsAudio['mp2']['mp2'] = ['mp2']; - $AcceptableExtensionsAudio['mp1']['mp1'] = ['mp1']; - $AcceptableExtensionsAudio['asf']['asf'] = ['asf']; - $AcceptableExtensionsAudio['asf']['wma'] = ['wma']; - $AcceptableExtensionsAudio['riff']['mp3'] = ['wav']; - $AcceptableExtensionsAudio['riff']['wav'] = ['wav']; - } - static $AcceptableExtensionsVideo = []; - if (empty($AcceptableExtensionsVideo)) { - $AcceptableExtensionsVideo['mp3']['mp3'] = ['mp3']; - $AcceptableExtensionsVideo['mp2']['mp2'] = ['mp2']; - $AcceptableExtensionsVideo['mp1']['mp1'] = ['mp1']; - $AcceptableExtensionsVideo['asf']['asf'] = ['asf']; - $AcceptableExtensionsVideo['asf']['wmv'] = ['wmv']; - $AcceptableExtensionsVideo['gif']['gif'] = ['gif']; - $AcceptableExtensionsVideo['jpg']['jpg'] = ['jpg']; - $AcceptableExtensionsVideo['png']['png'] = ['png']; - $AcceptableExtensionsVideo['bmp']['bmp'] = ['bmp']; - } - if (!empty($video_dataformat)) { - return (isset($AcceptableExtensionsVideo[$fileformat][$video_dataformat]) ? $AcceptableExtensionsVideo[$fileformat][$video_dataformat] : []); - } else { - return (isset($AcceptableExtensionsAudio[$fileformat][$audio_dataformat]) ? $AcceptableExtensionsAudio[$fileformat][$audio_dataformat] : []); - } +function AcceptableExtensions($fileformat, $audio_dataformat='', $video_dataformat='') { + static $AcceptableExtensionsAudio = array(); + if (empty($AcceptableExtensionsAudio)) { + $AcceptableExtensionsAudio['mp3']['mp3'] = array('mp3'); + $AcceptableExtensionsAudio['mp2']['mp2'] = array('mp2'); + $AcceptableExtensionsAudio['mp1']['mp1'] = array('mp1'); + $AcceptableExtensionsAudio['asf']['asf'] = array('asf'); + $AcceptableExtensionsAudio['asf']['wma'] = array('wma'); + $AcceptableExtensionsAudio['riff']['mp3'] = array('wav'); + $AcceptableExtensionsAudio['riff']['wav'] = array('wav'); + } + static $AcceptableExtensionsVideo = array(); + if (empty($AcceptableExtensionsVideo)) { + $AcceptableExtensionsVideo['mp3']['mp3'] = array('mp3'); + $AcceptableExtensionsVideo['mp2']['mp2'] = array('mp2'); + $AcceptableExtensionsVideo['mp1']['mp1'] = array('mp1'); + $AcceptableExtensionsVideo['asf']['asf'] = array('asf'); + $AcceptableExtensionsVideo['asf']['wmv'] = array('wmv'); + $AcceptableExtensionsVideo['gif']['gif'] = array('gif'); + $AcceptableExtensionsVideo['jpg']['jpg'] = array('jpg'); + $AcceptableExtensionsVideo['png']['png'] = array('png'); + $AcceptableExtensionsVideo['bmp']['bmp'] = array('bmp'); + } + if (!empty($video_dataformat)) { + return (isset($AcceptableExtensionsVideo[$fileformat][$video_dataformat]) ? $AcceptableExtensionsVideo[$fileformat][$video_dataformat] : array()); + } else { + return (isset($AcceptableExtensionsAudio[$fileformat][$audio_dataformat]) ? $AcceptableExtensionsAudio[$fileformat][$audio_dataformat] : array()); + } } if (!empty($_REQUEST['scan'])) { - if (mysql_table_exists(GETID3_DB_TABLE)) { - $SQLquery = 'DROP TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - mysql_query_safe($SQLquery); - } + if (mysql_table_exists(GETID3_DB_TABLE)) { + $SQLquery = 'DROP TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + mysql_query_safe($SQLquery); + } } if (!mysql_table_exists(GETID3_DB_TABLE)) { - $SQLquery = "CREATE TABLE `".mysql_real_escape_string(GETID3_DB_TABLE)."` ("; - $SQLquery .= " `ID` int(11) unsigned NOT NULL auto_increment,"; - $SQLquery .= " `filename` text NOT NULL,"; - $SQLquery .= " `last_modified` int(11) NOT NULL default '0',"; - $SQLquery .= " `md5_file` varchar(32) NOT NULL default '',"; - $SQLquery .= " `md5_data` varchar(32) NOT NULL default '',"; - $SQLquery .= " `md5_data_source` varchar(32) NOT NULL default '',"; - $SQLquery .= " `filesize` int(10) unsigned NOT NULL default '0',"; - $SQLquery .= " `fileformat` varchar(255) NOT NULL default '',"; - $SQLquery .= " `audio_dataformat` varchar(255) NOT NULL default '',"; - $SQLquery .= " `video_dataformat` varchar(255) NOT NULL default '',"; - $SQLquery .= " `audio_bitrate` float NOT NULL default '0',"; - $SQLquery .= " `video_bitrate` float NOT NULL default '0',"; - $SQLquery .= " `playtime_seconds` varchar(255) NOT NULL default '',"; - $SQLquery .= " `tags` varchar(255) NOT NULL default '',"; - $SQLquery .= " `artist` varchar(255) NOT NULL default '',"; - $SQLquery .= " `title` varchar(255) NOT NULL default '',"; - $SQLquery .= " `remix` varchar(255) NOT NULL default '',"; - $SQLquery .= " `album` varchar(255) NOT NULL default '',"; - $SQLquery .= " `genre` varchar(255) NOT NULL default '',"; - $SQLquery .= " `comment` text NOT NULL,"; - $SQLquery .= " `track` varchar(7) NOT NULL default '',"; - $SQLquery .= " `comments_all` longtext NOT NULL,"; - $SQLquery .= " `comments_id3v2` longtext NOT NULL,"; - $SQLquery .= " `comments_ape` longtext NOT NULL,"; - $SQLquery .= " `comments_lyrics3` longtext NOT NULL,"; - $SQLquery .= " `comments_id3v1` text NOT NULL,"; - $SQLquery .= " `warning` longtext NOT NULL,"; - $SQLquery .= " `error` longtext NOT NULL,"; - $SQLquery .= " `track_volume` float NOT NULL default '0',"; - $SQLquery .= " `encoder_options` varchar(255) NOT NULL default '',"; - $SQLquery .= " `vbr_method` varchar(255) NOT NULL default '',"; - $SQLquery .= " PRIMARY KEY (`ID`)"; - $SQLquery .= ")"; - mysql_query_safe($SQLquery); + $SQLquery = "CREATE TABLE `".mysql_real_escape_string(GETID3_DB_TABLE)."` ("; + $SQLquery .= " `ID` int(11) unsigned NOT NULL auto_increment,"; + $SQLquery .= " `filename` text NOT NULL,"; + $SQLquery .= " `last_modified` int(11) NOT NULL default '0',"; + $SQLquery .= " `md5_file` varchar(32) NOT NULL default '',"; + $SQLquery .= " `md5_data` varchar(32) NOT NULL default '',"; + $SQLquery .= " `md5_data_source` varchar(32) NOT NULL default '',"; + $SQLquery .= " `filesize` int(10) unsigned NOT NULL default '0',"; + $SQLquery .= " `fileformat` varchar(255) NOT NULL default '',"; + $SQLquery .= " `audio_dataformat` varchar(255) NOT NULL default '',"; + $SQLquery .= " `video_dataformat` varchar(255) NOT NULL default '',"; + $SQLquery .= " `audio_bitrate` float NOT NULL default '0',"; + $SQLquery .= " `video_bitrate` float NOT NULL default '0',"; + $SQLquery .= " `playtime_seconds` varchar(255) NOT NULL default '',"; + $SQLquery .= " `tags` varchar(255) NOT NULL default '',"; + $SQLquery .= " `artist` varchar(255) NOT NULL default '',"; + $SQLquery .= " `title` varchar(255) NOT NULL default '',"; + $SQLquery .= " `remix` varchar(255) NOT NULL default '',"; + $SQLquery .= " `album` varchar(255) NOT NULL default '',"; + $SQLquery .= " `genre` varchar(255) NOT NULL default '',"; + $SQLquery .= " `comment` text NOT NULL,"; + $SQLquery .= " `track` varchar(7) NOT NULL default '',"; + $SQLquery .= " `comments_all` longtext NOT NULL,"; + $SQLquery .= " `comments_id3v2` longtext NOT NULL,"; + $SQLquery .= " `comments_ape` longtext NOT NULL,"; + $SQLquery .= " `comments_lyrics3` longtext NOT NULL,"; + $SQLquery .= " `comments_id3v1` text NOT NULL,"; + $SQLquery .= " `warning` longtext NOT NULL,"; + $SQLquery .= " `error` longtext NOT NULL,"; + $SQLquery .= " `track_volume` float NOT NULL default '0',"; + $SQLquery .= " `encoder_options` varchar(255) NOT NULL default '',"; + $SQLquery .= " `vbr_method` varchar(255) NOT NULL default '',"; + $SQLquery .= " PRIMARY KEY (`ID`)"; + $SQLquery .= ")"; + mysql_query_safe($SQLquery); } -$ExistingTableFields = []; +$ExistingTableFields = array(); $result = mysql_query_safe('DESCRIBE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); while ($row = mysql_fetch_array($result)) { - $ExistingTableFields[$row['Field']] = $row; + $ExistingTableFields[$row['Field']] = $row; } if (!isset($ExistingTableFields['encoder_options'])) { // Added in 1.7.0b2 - echo 'adding field `encoder_options`
'; - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `encoder_options` VARCHAR(255) default "" NOT NULL AFTER `error`'); - mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); + echo 'adding field `encoder_options`
'; + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `encoder_options` VARCHAR(255) default "" NOT NULL AFTER `error`'); + mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); } if (isset($ExistingTableFields['track']) && ($ExistingTableFields['track']['Type'] != 'varchar(7)')) { // Changed in 1.7.0b2 - echo 'changing field `track` to VARCHAR(7)
'; - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `track` `track` VARCHAR(7) default "" NOT NULL'); - mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); + echo 'changing field `track` to VARCHAR(7)
'; + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `track` `track` VARCHAR(7) default "" NOT NULL'); + mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); } if (!isset($ExistingTableFields['track_volume'])) { // Added in 1.7.0b5 - echo '

WARNING! You should erase your database and rescan everything because the comment storing has been changed since the last version


'; - echo 'adding field `track_volume`
'; - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `track_volume` FLOAT NOT NULL AFTER `error`'); - mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); + echo '

WARNING! You should erase your database and rescan everything because the comment storing has been changed since the last version


'; + echo 'adding field `track_volume`
'; + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `track_volume` FLOAT NOT NULL AFTER `error`'); + mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); } if (!isset($ExistingTableFields['remix'])) { // Added in 1.7.3b1 - echo 'adding field `encoder_options`, `alternate_name`, `parody`
'; - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `remix` VARCHAR(255) default "" NOT NULL AFTER `title`'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `alternate_name` VARCHAR(255) default "" NOT NULL AFTER `track`'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `parody` VARCHAR(255) default "" NOT NULL AFTER `alternate_name`'); - mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); + echo 'adding field `encoder_options`, `alternate_name`, `parody`
'; + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `remix` VARCHAR(255) default "" NOT NULL AFTER `title`'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `alternate_name` VARCHAR(255) default "" NOT NULL AFTER `track`'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` ADD `parody` VARCHAR(255) default "" NOT NULL AFTER `alternate_name`'); + mysql_query_safe('OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'); } if (isset($ExistingTableFields['comments_all']) && ($ExistingTableFields['comments_all']['Type'] != 'longtext')) { // Changed in 1.9.0 - echo 'changing comments fields from text to longtext
'; - // no need to change id3v1 - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_all` `comments_all` LONGTEXT NOT NULL'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_id3v2` `comments_id3v2` LONGTEXT NOT NULL'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_ape` `comments_ape` LONGTEXT NOT NULL'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_lyrics3` `comments_lyrics3` LONGTEXT NOT NULL'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `warning` `warning` LONGTEXT NOT NULL'); - mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `error` `error` LONGTEXT NOT NULL'); + echo 'changing comments fields from text to longtext
'; + // no need to change id3v1 + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_all` `comments_all` LONGTEXT NOT NULL'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_id3v2` `comments_id3v2` LONGTEXT NOT NULL'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_ape` `comments_ape` LONGTEXT NOT NULL'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `comments_lyrics3` `comments_lyrics3` LONGTEXT NOT NULL'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `warning` `warning` LONGTEXT NOT NULL'); + mysql_query_safe('ALTER TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` CHANGE `error` `error` LONGTEXT NOT NULL'); } -function SynchronizeAllTags($filename, $synchronizefrom = 'all', $synchronizeto = 'A12', &$errors) -{ - global $getID3; +function SynchronizeAllTags($filename, $synchronizefrom='all', $synchronizeto='A12', &$errors) { + global $getID3; - set_time_limit(30); + set_time_limit(30); - $ThisFileInfo = $getID3->analyze($filename); - getid3_lib::CopyTagsToComments($ThisFileInfo); + $ThisFileInfo = $getID3->analyze($filename); + getid3_lib::CopyTagsToComments($ThisFileInfo); - if ($synchronizefrom == 'all') { - $SourceArray = (!empty($ThisFileInfo['comments']) ? $ThisFileInfo['comments'] : []); - } elseif (!empty($ThisFileInfo['tags'][$synchronizefrom])) { - $SourceArray = (!empty($ThisFileInfo['tags'][$synchronizefrom]) ? $ThisFileInfo['tags'][$synchronizefrom] : []); - } else { - die('ERROR: $ThisFileInfo[tags]['.$synchronizefrom.'] does not exist'); - } + if ($synchronizefrom == 'all') { + $SourceArray = (!empty($ThisFileInfo['comments']) ? $ThisFileInfo['comments'] : array()); + } elseif (!empty($ThisFileInfo['tags'][$synchronizefrom])) { + $SourceArray = (!empty($ThisFileInfo['tags'][$synchronizefrom]) ? $ThisFileInfo['tags'][$synchronizefrom] : array()); + } else { + die('ERROR: $ThisFileInfo[tags]['.$synchronizefrom.'] does not exist'); + } - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($filename).'")'; - mysql_query_safe($SQLquery); + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($filename).'")'; + mysql_query_safe($SQLquery); - $TagFormatsToWrite = []; - if ((strpos($synchronizeto, '2') !== false) && ($synchronizefrom != 'id3v2')) { - $TagFormatsToWrite[] = 'id3v2.3'; - } - if ((strpos($synchronizeto, 'A') !== false) && ($synchronizefrom != 'ape')) { - $TagFormatsToWrite[] = 'ape'; - } - if ((strpos($synchronizeto, 'L') !== false) && ($synchronizefrom != 'lyrics3')) { - $TagFormatsToWrite[] = 'lyrics3'; - } - if ((strpos($synchronizeto, '1') !== false) && ($synchronizefrom != 'id3v1')) { - $TagFormatsToWrite[] = 'id3v1'; - } + $TagFormatsToWrite = array(); + if ((strpos($synchronizeto, '2') !== false) && ($synchronizefrom != 'id3v2')) { + $TagFormatsToWrite[] = 'id3v2.3'; + } + if ((strpos($synchronizeto, 'A') !== false) && ($synchronizefrom != 'ape')) { + $TagFormatsToWrite[] = 'ape'; + } + if ((strpos($synchronizeto, 'L') !== false) && ($synchronizefrom != 'lyrics3')) { + $TagFormatsToWrite[] = 'lyrics3'; + } + if ((strpos($synchronizeto, '1') !== false) && ($synchronizefrom != 'id3v1')) { + $TagFormatsToWrite[] = 'id3v1'; + } - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.php', __FILE__, true); - $tagwriter = new getid3_writetags; - $tagwriter->filename = $filename; - $tagwriter->tagformats = $TagFormatsToWrite; - $tagwriter->overwrite_tags = true; - $tagwriter->tag_encoding = $getID3->encoding; - $tagwriter->tag_data = $SourceArray; + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.php', __FILE__, true); + $tagwriter = new getid3_writetags; + $tagwriter->filename = $filename; + $tagwriter->tagformats = $TagFormatsToWrite; + $tagwriter->overwrite_tags = true; + $tagwriter->tag_encoding = $getID3->encoding; + $tagwriter->tag_data = $SourceArray; - if ($tagwriter->WriteTags()) { - $errors = $tagwriter->errors; - return true; - } - $errors = $tagwriter->errors; - return false; + if ($tagwriter->WriteTags()) { + $errors = $tagwriter->errors; + return true; + } + $errors = $tagwriter->errors; + return false; } -$IgnoreNoTagFormats = ['', 'png', 'jpg', 'gif', 'bmp', 'swf', 'pdf', 'zip', 'rar', 'mid', 'mod', 'xm', 'it', 's3m']; +$IgnoreNoTagFormats = array('', 'png', 'jpg', 'gif', 'bmp', 'swf', 'pdf', 'zip', 'rar', 'mid', 'mod', 'xm', 'it', 's3m'); if (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan']) || !empty($_REQUEST['rescanerrors'])) { - $SQLquery = 'DELETE from `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` = "")'; - mysql_query_safe($SQLquery); - $FilesInDir = []; + $SQLquery = 'DELETE from `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` = "")'; + mysql_query_safe($SQLquery); - if (!empty($_REQUEST['rescanerrors'])) { - echo 'abort
'; + $FilesInDir = array(); - echo 'Re-scanning all media files already in database that had errors and/or warnings in last scan
'; + if (!empty($_REQUEST['rescanerrors'])) { - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`error` <> "")'; - $SQLquery .= ' OR (`warning` <> "")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - while ($row = mysql_fetch_array($result)) { - if (!file_exists($row['filename'])) { - echo 'File missing: '.$row['filename'].'
'; - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; - mysql_query_safe($SQLquery); - } else { - $FilesInDir[] = $row['filename']; - } - } - } elseif (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan'])) { - echo 'abort
'; + echo 'abort
'; - echo 'Scanning all media files in '.str_replace('\\', '/', realpath(!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : $_REQUEST['newscan'])).' (and subdirectories)
'; + echo 'Re-scanning all media files already in database that had errors and/or warnings in last scan
'; - $SQLquery = 'SELECT COUNT(*) AS `num`, `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' GROUP BY `filename`'; - $SQLquery .= ' HAVING (`num` > 1)'; - $SQLquery .= ' ORDER BY `num` DESC'; - $result = mysql_query_safe($SQLquery); - $DupesDeleted = 0; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE `filename` LIKE "'.mysql_real_escape_string($row['filename']).'"'; - mysql_query_safe($SQLquery); - $DupesDeleted++; - } - if ($DupesDeleted > 0) { - echo 'Deleted '.number_format($DupesDeleted).' duplicate filenames
'; - } + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`error` <> "")'; + $SQLquery .= ' OR (`warning` <> "")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + while ($row = mysql_fetch_array($result)) { - if (!empty($_REQUEST['newscan'])) { - $AlreadyInDatabase = []; - set_time_limit(60); - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - while ($row = mysql_fetch_array($result)) { - //$AlreadyInDatabase[] = strtolower($row['filename']); - $AlreadyInDatabase[] = $row['filename']; - } - } + if (!file_exists($row['filename'])) { + echo 'File missing: '.$row['filename'].'
'; + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; + mysql_query_safe($SQLquery); + } else { + $FilesInDir[] = $row['filename']; + } - $DirectoriesToScan = [!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : $_REQUEST['newscan']]; - $DirectoriesScanned = []; - while (count($DirectoriesToScan) > 0) { - foreach ($DirectoriesToScan as $DirectoryKey => $startingdir) { - if ($dir = opendir($startingdir)) { - set_time_limit(30); - echo ''.str_replace('\\', '/', $startingdir).'
'; - flush(); - while (($file = readdir($dir)) !== false) { - if (($file != '.') && ($file != '..')) { - $RealPathName = realpath($startingdir.'/'.$file); - if (is_dir($RealPathName)) { - if (!in_array($RealPathName, $DirectoriesScanned) && !in_array($RealPathName, $DirectoriesToScan)) { - $DirectoriesToScan[] = $RealPathName; - } - } elseif (is_file($RealPathName)) { - if (!empty($_REQUEST['newscan'])) { - if (!in_array(str_replace('\\', '/', $RealPathName), $AlreadyInDatabase)) { - $FilesInDir[] = $RealPathName; - } - } elseif (!empty($_REQUEST['scan'])) { - $FilesInDir[] = $RealPathName; - } - } - } - } - closedir($dir); - } else { - echo '
Failed to open directory "'.htmlentities($startingdir).'"

'; - } - $DirectoriesScanned[] = $startingdir; - unset($DirectoriesToScan[$DirectoryKey]); - } - } - echo 'List of files to scan complete (added '.number_format(count($FilesInDir)).' files to scan)
'; - flush(); - } + } - $FilesInDir = array_unique($FilesInDir); - sort($FilesInDir); + } elseif (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan'])) { - $starttime = time(); - $rowcounter = 0; - $totaltoprocess = count($FilesInDir); + echo 'abort
'; - foreach ($FilesInDir as $filename) { - set_time_limit(300); + echo 'Scanning all media files in '.str_replace('\\', '/', realpath(!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : $_REQUEST['newscan'])).' (and subdirectories)
'; - echo '
'.date('H:i:s').' ['.number_format(++$rowcounter).' / '.number_format($totaltoprocess).'] '.str_replace('\\', '/', $filename); + $SQLquery = 'SELECT COUNT(*) AS `num`, `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' GROUP BY `filename`'; + $SQLquery .= ' HAVING (`num` > 1)'; + $SQLquery .= ' ORDER BY `num` DESC'; + $result = mysql_query_safe($SQLquery); + $DupesDeleted = 0; + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE `filename` LIKE "'.mysql_real_escape_string($row['filename']).'"'; + mysql_query_safe($SQLquery); + $DupesDeleted++; + } + if ($DupesDeleted > 0) { + echo 'Deleted '.number_format($DupesDeleted).' duplicate filenames
'; + } - $ThisFileInfo = $getID3->analyze($filename); - getid3_lib::CopyTagsToComments($ThisFileInfo); + if (!empty($_REQUEST['newscan'])) { + $AlreadyInDatabase = array(); + set_time_limit(60); + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + while ($row = mysql_fetch_array($result)) { + //$AlreadyInDatabase[] = strtolower($row['filename']); + $AlreadyInDatabase[] = $row['filename']; + } + } - if (file_exists($filename)) { - $ThisFileInfo['file_modified_time'] = filemtime($filename); - $ThisFileInfo['md5_file'] = ($getid3_demo_mysql_md5_file ? md5_file($filename) : ''); - } + $DirectoriesToScan = array(!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : $_REQUEST['newscan']); + $DirectoriesScanned = array(); + while (count($DirectoriesToScan) > 0) { + foreach ($DirectoriesToScan as $DirectoryKey => $startingdir) { + if ($dir = opendir($startingdir)) { + set_time_limit(30); + echo ''.str_replace('\\', '/', $startingdir).'
'; + flush(); + while (($file = readdir($dir)) !== false) { + if (($file != '.') && ($file != '..')) { + $RealPathName = realpath($startingdir.'/'.$file); + if (is_dir($RealPathName)) { + if (!in_array($RealPathName, $DirectoriesScanned) && !in_array($RealPathName, $DirectoriesToScan)) { + $DirectoriesToScan[] = $RealPathName; + } + } elseif (is_file($RealPathName)) { + if (!empty($_REQUEST['newscan'])) { + if (!in_array(str_replace('\\', '/', $RealPathName), $AlreadyInDatabase)) { + $FilesInDir[] = $RealPathName; + } + } elseif (!empty($_REQUEST['scan'])) { + $FilesInDir[] = $RealPathName; + } + } + } + } + closedir($dir); + } else { + echo '
Failed to open directory "'.htmlentities($startingdir).'"

'; + } + $DirectoriesScanned[] = $startingdir; + unset($DirectoriesToScan[$DirectoryKey]); + } + } + echo 'List of files to scan complete (added '.number_format(count($FilesInDir)).' files to scan)
'; + flush(); + } - if (empty($ThisFileInfo['fileformat'])) { - echo ' (unknown file type)'; - } else { - if (!empty($ThisFileInfo['error'])) { - echo ' (errors)'; - } elseif (!empty($ThisFileInfo['warning'])) { - echo ' (warnings)'; - } else { - echo ' (OK)'; - } + $FilesInDir = array_unique($FilesInDir); + sort($FilesInDir); - $this_track_track = ''; - if (!empty($ThisFileInfo['comments']['track'])) { - foreach ($ThisFileInfo['comments']['track'] as $key => $value) { - if (strlen($value) > strlen($this_track_track)) { - $this_track_track = str_pad($value, 2, '0', STR_PAD_LEFT); - } - } - if (preg_match('#^([0-9]+)/([0-9]+)$#', $this_track_track, $matches)) { - // change "1/5"->"01/05", "3/12"->"03/12", etc - $this_track_track = str_pad($matches[1], 2, '0', STR_PAD_LEFT).'/'.str_pad($matches[2], 2, '0', STR_PAD_LEFT); - } - } + $starttime = time(); + $rowcounter = 0; + $totaltoprocess = count($FilesInDir); - $this_track_remix = ''; - $this_track_title = ''; - if (!empty($ThisFileInfo['comments']['title'])) { - foreach ($ThisFileInfo['comments']['title'] as $possible_title) { - if (strlen($possible_title) > strlen($this_track_title)) { - $this_track_title = $possible_title; - } - } - } + foreach ($FilesInDir as $filename) { + set_time_limit(300); - $ParenthesesPairs = ['()', '[]', '{}']; - foreach ($ParenthesesPairs as $pair) { - if (preg_match_all('/(.*) '.preg_quote($pair{0}).'(([^'.preg_quote($pair).']*[\- '.preg_quote($pair{0}).'])?(cut|dub|edit|version|live|reprise|[a-z]*mix))'.preg_quote($pair{1}).'/iU', $this_track_title, $matches)) { - $this_track_title = $matches[1][0]; - $this_track_remix = implode("\t", $matches[2]); - } - } + echo '
'.date('H:i:s').' ['.number_format(++$rowcounter).' / '.number_format($totaltoprocess).'] '.str_replace('\\', '/', $filename); + + $ThisFileInfo = $getID3->analyze($filename); + getid3_lib::CopyTagsToComments($ThisFileInfo); + + if (file_exists($filename)) { + $ThisFileInfo['file_modified_time'] = filemtime($filename); + $ThisFileInfo['md5_file'] = ($getid3_demo_mysql_md5_file ? md5_file($filename) : ''); + } + + if (empty($ThisFileInfo['fileformat'])) { + + echo ' (unknown file type)'; + + } else { + + if (!empty($ThisFileInfo['error'])) { + echo ' (errors)'; + } elseif (!empty($ThisFileInfo['warning'])) { + echo ' (warnings)'; + } else { + echo ' (OK)'; + } + + $this_track_track = ''; + if (!empty($ThisFileInfo['comments']['track'])) { + foreach ($ThisFileInfo['comments']['track'] as $key => $value) { + if (strlen($value) > strlen($this_track_track)) { + $this_track_track = str_pad($value, 2, '0', STR_PAD_LEFT); + } + } + if (preg_match('#^([0-9]+)/([0-9]+)$#', $this_track_track, $matches)) { + // change "1/5"->"01/05", "3/12"->"03/12", etc + $this_track_track = str_pad($matches[1], 2, '0', STR_PAD_LEFT).'/'.str_pad($matches[2], 2, '0', STR_PAD_LEFT); + } + } + + $this_track_remix = ''; + $this_track_title = ''; + if (!empty($ThisFileInfo['comments']['title'])) { + foreach ($ThisFileInfo['comments']['title'] as $possible_title) { + if (strlen($possible_title) > strlen($this_track_title)) { + $this_track_title = $possible_title; + } + } + } + + $ParenthesesPairs = array('()', '[]', '{}'); + foreach ($ParenthesesPairs as $pair) { + if (preg_match_all('/(.*) '.preg_quote($pair{0}).'(([^'.preg_quote($pair).']*[\- '.preg_quote($pair{0}).'])?(cut|dub|edit|version|live|reprise|[a-z]*mix))'.preg_quote($pair{1}).'/iU', $this_track_title, $matches)) { + $this_track_title = $matches[1][0]; + $this_track_remix = implode("\t", $matches[2]); + } + } - if (!empty($_REQUEST['rescanerrors'])) { - $SQLquery = 'UPDATE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` SET '; - $SQLquery .= ' `last_modified` = "'. mysql_real_escape_string(!empty($ThisFileInfo['file_modified_time']) ? $ThisFileInfo['file_modified_time'] : '').'"'; - $SQLquery .= ', `md5_file` = "'. mysql_real_escape_string(!empty($ThisFileInfo['md5_file']) ? $ThisFileInfo['md5_file'] : '').'"'; - $SQLquery .= ', `md5_data` = "'. mysql_real_escape_string(!empty($ThisFileInfo['md5_data']) ? $ThisFileInfo['md5_data'] : '').'"'; - $SQLquery .= ', `md5_data_source` = "'. mysql_real_escape_string(!empty($ThisFileInfo['md5_data_source']) ? $ThisFileInfo['md5_data_source'] : '').'"'; - $SQLquery .= ', `filesize` = "'. mysql_real_escape_string(!empty($ThisFileInfo['filesize']) ? $ThisFileInfo['filesize'] : 0).'"'; - $SQLquery .= ', `fileformat` = "'. mysql_real_escape_string(!empty($ThisFileInfo['fileformat']) ? $ThisFileInfo['fileformat'] : '').'"'; - $SQLquery .= ', `audio_dataformat` = "'.mysql_real_escape_string(!empty($ThisFileInfo['audio']['dataformat']) ? $ThisFileInfo['audio']['dataformat'] : '').'"'; - $SQLquery .= ', `video_dataformat` = "'.mysql_real_escape_string(!empty($ThisFileInfo['video']['dataformat']) ? $ThisFileInfo['video']['dataformat'] : '').'"'; - $SQLquery .= ', `vbr_method` = "'. mysql_real_escape_string(!empty($ThisFileInfo['mpeg']['audio']['VBR_method']) ? $ThisFileInfo['mpeg']['audio']['VBR_method'] : '').'"'; - $SQLquery .= ', `audio_bitrate` = "'. mysql_real_escape_string(!empty($ThisFileInfo['audio']['bitrate']) ? floatval($ThisFileInfo['audio']['bitrate']) : 0).'"'; - $SQLquery .= ', `video_bitrate` = "'. mysql_real_escape_string(!empty($ThisFileInfo['video']['bitrate']) ? floatval($ThisFileInfo['video']['bitrate']) : 0).'"'; - $SQLquery .= ', `playtime_seconds` = "'.mysql_real_escape_string(!empty($ThisFileInfo['playtime_seconds']) ? floatval($ThisFileInfo['playtime_seconds']) : 0).'"'; - $SQLquery .= ', `track_volume` = "'. mysql_real_escape_string(!empty($ThisFileInfo['replay_gain']['track']['volume']) ? floatval($ThisFileInfo['replay_gain']['track']['volume']) : 0).'"'; - $SQLquery .= ', `comments_all` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']) ? serialize($ThisFileInfo['comments']) : '').'"'; - $SQLquery .= ', `comments_id3v2` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v2']) ? serialize($ThisFileInfo['tags']['id3v2']) : '').'"'; - $SQLquery .= ', `comments_ape` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']['ape']) ? serialize($ThisFileInfo['tags']['ape']) : '').'"'; - $SQLquery .= ', `comments_lyrics3` = "'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['lyrics3']) ? serialize($ThisFileInfo['tags']['lyrics3']) : '').'"'; - $SQLquery .= ', `comments_id3v1` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v1']) ? serialize($ThisFileInfo['tags']['id3v1']) : '').'"'; - $SQLquery .= ', `warning` = "'. mysql_real_escape_string(!empty($ThisFileInfo['warning']) ? implode("\t", $ThisFileInfo['warning']) : '').'"'; - $SQLquery .= ', `error` = "'. mysql_real_escape_string(!empty($ThisFileInfo['error']) ? implode("\t", $ThisFileInfo['error']) : '').'"'; - $SQLquery .= ', `album` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['album']) ? implode("\t", $ThisFileInfo['comments']['album']) : '').'"'; - $SQLquery .= ', `genre` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['genre']) ? implode("\t", $ThisFileInfo['comments']['genre']) : '').'"'; - $SQLquery .= ', `comment` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['comment']) ? implode("\t", $ThisFileInfo['comments']['comment']) : '').'"'; - $SQLquery .= ', `artist` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['artist']) ? implode("\t", $ThisFileInfo['comments']['artist']) : '').'"'; - $SQLquery .= ', `tags` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']) ? implode("\t", array_keys($ThisFileInfo['tags'])) : '').'"'; - $SQLquery .= ', `encoder_options` = "'. mysql_real_escape_string(trim((!empty($ThisFileInfo['audio']['encoder']) ? $ThisFileInfo['audio']['encoder'] : '').' '.(!empty($ThisFileInfo['audio']['encoder_options']) ? $ThisFileInfo['audio']['encoder_options'] : ''))).'"'; - $SQLquery .= ', `title` = "'. mysql_real_escape_string($this_track_title).'"'; - $SQLquery .= ', `remix` = "'. mysql_real_escape_string($this_track_remix).'"'; - $SQLquery .= ', `track` = "'. mysql_real_escape_string($this_track_track).'"'; - $SQLquery .= 'WHERE (`filename` = "'. mysql_real_escape_string(isset($ThisFileInfo['filenamepath']) ? $ThisFileInfo['filenamepath'] : '').'")'; - } elseif (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan'])) { - //$SQLquery = 'INSERT INTO `'.mysql_real_escape_string(GETID3_DB_TABLE).'` (`filename`, `last_modified`, `md5_file`, `md5_data`, `md5_data_source`, `filesize`, `fileformat`, `audio_dataformat`, `video_dataformat`, `audio_bitrate`, `video_bitrate`, `playtime_seconds`, `artist`, `title`, `remix`, `album`, `genre`, `comment`, `track`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`, `warning`, `error`, `encoder_options`, `vbr_method`, `track_volume`) VALUES ('; - $SQLquery = 'INSERT INTO `'.mysql_real_escape_string(GETID3_DB_TABLE).'` (`filename`, `last_modified`, `md5_file`, `md5_data`, `md5_data_source`, `filesize`, `fileformat`, `audio_dataformat`, `video_dataformat`, `audio_bitrate`, `video_bitrate`, `playtime_seconds`, `tags`, `artist`, `title`, `remix`, `album`, `genre`, `comment`, `track`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`, `warning`, `error`, `encoder_options`, `vbr_method`, `track_volume`) VALUES ('; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['filenamepath']) ? $ThisFileInfo['filenamepath'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['file_modified_time']) ? $ThisFileInfo['file_modified_time'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['md5_file']) ? $ThisFileInfo['md5_file'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['md5_data']) ? $ThisFileInfo['md5_data'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['md5_data_source']) ? $ThisFileInfo['md5_data_source'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['filesize']) ? $ThisFileInfo['filesize'] : 0).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['fileformat']) ? $ThisFileInfo['fileformat'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['audio']['dataformat']) ? $ThisFileInfo['audio']['dataformat'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['video']['dataformat']) ? $ThisFileInfo['video']['dataformat'] : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['audio']['bitrate']) ? floatval($ThisFileInfo['audio']['bitrate']) : 0).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['video']['bitrate']) ? floatval($ThisFileInfo['video']['bitrate']) : 0).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['playtime_seconds']) ? floatval($ThisFileInfo['playtime_seconds']) : 0).'", '; - //$SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags'] ) ? implode("\t", $ThisFileInfo['tags']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']) ? implode("\t", array_keys($ThisFileInfo['tags'])) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['artist']) ? implode("\t", $ThisFileInfo['comments']['artist']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string($this_track_title).'", '; - $SQLquery .= '"'.mysql_real_escape_string($this_track_remix).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['album']) ? implode("\t", $ThisFileInfo['comments']['album']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['genre']) ? implode("\t", $ThisFileInfo['comments']['genre']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['comment']) ? implode("\t", $ThisFileInfo['comments']['comment']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string($this_track_track).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']) ? serialize($ThisFileInfo['comments']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v2']) ? serialize($ThisFileInfo['tags']['id3v2']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['ape']) ? serialize($ThisFileInfo['tags']['ape']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['lyrics3']) ? serialize($ThisFileInfo['tags']['lyrics3']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v1']) ? serialize($ThisFileInfo['tags']['id3v1']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['warning']) ? implode("\t", $ThisFileInfo['warning']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['error']) ? implode("\t", $ThisFileInfo['error']) : '').'", '; - $SQLquery .= '"'.mysql_real_escape_string(trim((!empty($ThisFileInfo['audio']['encoder']) ? $ThisFileInfo['audio']['encoder'] : '').' '.(!empty($ThisFileInfo['audio']['encoder_options']) ? $ThisFileInfo['audio']['encoder_options'] : ''))).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['mpeg']['audio']['LAME']) ? 'LAME' : (!empty($ThisFileInfo['mpeg']['audio']['VBR_method']) ? $ThisFileInfo['mpeg']['audio']['VBR_method'] : '')).'", '; - $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['replay_gain']['track']['volume']) ? floatval($ThisFileInfo['replay_gain']['track']['volume']) : 0).'")'; - } - flush(); - mysql_query_safe($SQLquery); - } - } + if (!empty($_REQUEST['rescanerrors'])) { - $SQLquery = 'OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - mysql_query_safe($SQLquery); + $SQLquery = 'UPDATE `'.mysql_real_escape_string(GETID3_DB_TABLE).'` SET '; + $SQLquery .= ' `last_modified` = "'. mysql_real_escape_string(!empty($ThisFileInfo['file_modified_time'] ) ? $ThisFileInfo['file_modified_time'] : '').'"'; + $SQLquery .= ', `md5_file` = "'. mysql_real_escape_string(!empty($ThisFileInfo['md5_file'] ) ? $ThisFileInfo['md5_file'] : '').'"'; + $SQLquery .= ', `md5_data` = "'. mysql_real_escape_string(!empty($ThisFileInfo['md5_data'] ) ? $ThisFileInfo['md5_data'] : '').'"'; + $SQLquery .= ', `md5_data_source` = "'. mysql_real_escape_string(!empty($ThisFileInfo['md5_data_source'] ) ? $ThisFileInfo['md5_data_source'] : '').'"'; + $SQLquery .= ', `filesize` = "'. mysql_real_escape_string(!empty($ThisFileInfo['filesize'] ) ? $ThisFileInfo['filesize'] : 0).'"'; + $SQLquery .= ', `fileformat` = "'. mysql_real_escape_string(!empty($ThisFileInfo['fileformat'] ) ? $ThisFileInfo['fileformat'] : '').'"'; + $SQLquery .= ', `audio_dataformat` = "'.mysql_real_escape_string(!empty($ThisFileInfo['audio']['dataformat'] ) ? $ThisFileInfo['audio']['dataformat'] : '').'"'; + $SQLquery .= ', `video_dataformat` = "'.mysql_real_escape_string(!empty($ThisFileInfo['video']['dataformat'] ) ? $ThisFileInfo['video']['dataformat'] : '').'"'; + $SQLquery .= ', `vbr_method` = "'. mysql_real_escape_string(!empty($ThisFileInfo['mpeg']['audio']['VBR_method'] ) ? $ThisFileInfo['mpeg']['audio']['VBR_method'] : '').'"'; + $SQLquery .= ', `audio_bitrate` = "'. mysql_real_escape_string(!empty($ThisFileInfo['audio']['bitrate'] ) ? floatval($ThisFileInfo['audio']['bitrate']) : 0).'"'; + $SQLquery .= ', `video_bitrate` = "'. mysql_real_escape_string(!empty($ThisFileInfo['video']['bitrate'] ) ? floatval($ThisFileInfo['video']['bitrate']) : 0).'"'; + $SQLquery .= ', `playtime_seconds` = "'.mysql_real_escape_string(!empty($ThisFileInfo['playtime_seconds'] ) ? floatval($ThisFileInfo['playtime_seconds']) : 0).'"'; + $SQLquery .= ', `track_volume` = "'. mysql_real_escape_string(!empty($ThisFileInfo['replay_gain']['track']['volume']) ? floatval($ThisFileInfo['replay_gain']['track']['volume']) : 0).'"'; + $SQLquery .= ', `comments_all` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments'] ) ? serialize($ThisFileInfo['comments']) : '').'"'; + $SQLquery .= ', `comments_id3v2` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v2'] ) ? serialize($ThisFileInfo['tags']['id3v2']) : '').'"'; + $SQLquery .= ', `comments_ape` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']['ape'] ) ? serialize($ThisFileInfo['tags']['ape']) : '').'"'; + $SQLquery .= ', `comments_lyrics3` = "'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['lyrics3'] ) ? serialize($ThisFileInfo['tags']['lyrics3']) : '').'"'; + $SQLquery .= ', `comments_id3v1` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v1'] ) ? serialize($ThisFileInfo['tags']['id3v1']) : '').'"'; + $SQLquery .= ', `warning` = "'. mysql_real_escape_string(!empty($ThisFileInfo['warning'] ) ? implode("\t", $ThisFileInfo['warning']) : '').'"'; + $SQLquery .= ', `error` = "'. mysql_real_escape_string(!empty($ThisFileInfo['error'] ) ? implode("\t", $ThisFileInfo['error']) : '').'"'; + $SQLquery .= ', `album` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['album'] ) ? implode("\t", $ThisFileInfo['comments']['album']) : '').'"'; + $SQLquery .= ', `genre` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['genre'] ) ? implode("\t", $ThisFileInfo['comments']['genre']) : '').'"'; + $SQLquery .= ', `comment` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['comment'] ) ? implode("\t", $ThisFileInfo['comments']['comment']) : '').'"'; + $SQLquery .= ', `artist` = "'. mysql_real_escape_string(!empty($ThisFileInfo['comments']['artist'] ) ? implode("\t", $ThisFileInfo['comments']['artist']) : '').'"'; + $SQLquery .= ', `tags` = "'. mysql_real_escape_string(!empty($ThisFileInfo['tags'] ) ? implode("\t", array_keys($ThisFileInfo['tags'])) : '').'"'; + $SQLquery .= ', `encoder_options` = "'. mysql_real_escape_string(trim((!empty($ThisFileInfo['audio']['encoder']) ? $ThisFileInfo['audio']['encoder'] : '').' '.(!empty($ThisFileInfo['audio']['encoder_options']) ? $ThisFileInfo['audio']['encoder_options'] : ''))).'"'; + $SQLquery .= ', `title` = "'. mysql_real_escape_string($this_track_title).'"'; + $SQLquery .= ', `remix` = "'. mysql_real_escape_string($this_track_remix).'"'; + $SQLquery .= ', `track` = "'. mysql_real_escape_string($this_track_track).'"'; + $SQLquery .= 'WHERE (`filename` = "'. mysql_real_escape_string(isset($ThisFileInfo['filenamepath']) ? $ThisFileInfo['filenamepath'] : '').'")'; + + } elseif (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan'])) { + + //$SQLquery = 'INSERT INTO `'.mysql_real_escape_string(GETID3_DB_TABLE).'` (`filename`, `last_modified`, `md5_file`, `md5_data`, `md5_data_source`, `filesize`, `fileformat`, `audio_dataformat`, `video_dataformat`, `audio_bitrate`, `video_bitrate`, `playtime_seconds`, `artist`, `title`, `remix`, `album`, `genre`, `comment`, `track`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`, `warning`, `error`, `encoder_options`, `vbr_method`, `track_volume`) VALUES ('; + $SQLquery = 'INSERT INTO `'.mysql_real_escape_string(GETID3_DB_TABLE).'` (`filename`, `last_modified`, `md5_file`, `md5_data`, `md5_data_source`, `filesize`, `fileformat`, `audio_dataformat`, `video_dataformat`, `audio_bitrate`, `video_bitrate`, `playtime_seconds`, `tags`, `artist`, `title`, `remix`, `album`, `genre`, `comment`, `track`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`, `warning`, `error`, `encoder_options`, `vbr_method`, `track_volume`) VALUES ('; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['filenamepath'] ) ? $ThisFileInfo['filenamepath'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['file_modified_time'] ) ? $ThisFileInfo['file_modified_time'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['md5_file'] ) ? $ThisFileInfo['md5_file'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['md5_data'] ) ? $ThisFileInfo['md5_data'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['md5_data_source'] ) ? $ThisFileInfo['md5_data_source'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['filesize'] ) ? $ThisFileInfo['filesize'] : 0).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['fileformat'] ) ? $ThisFileInfo['fileformat'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['audio']['dataformat'] ) ? $ThisFileInfo['audio']['dataformat'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['video']['dataformat'] ) ? $ThisFileInfo['video']['dataformat'] : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['audio']['bitrate'] ) ? floatval($ThisFileInfo['audio']['bitrate']) : 0).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['video']['bitrate'] ) ? floatval($ThisFileInfo['video']['bitrate']) : 0).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['playtime_seconds'] ) ? floatval($ThisFileInfo['playtime_seconds']) : 0).'", '; + //$SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags'] ) ? implode("\t", $ThisFileInfo['tags']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags'] ) ? implode("\t", array_keys($ThisFileInfo['tags'])) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['artist'] ) ? implode("\t", $ThisFileInfo['comments']['artist']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string($this_track_title).'", '; + $SQLquery .= '"'.mysql_real_escape_string($this_track_remix).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['album'] ) ? implode("\t", $ThisFileInfo['comments']['album']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['genre'] ) ? implode("\t", $ThisFileInfo['comments']['genre']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments']['comment'] ) ? implode("\t", $ThisFileInfo['comments']['comment']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string($this_track_track).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['comments'] ) ? serialize($ThisFileInfo['comments']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v2'] ) ? serialize($ThisFileInfo['tags']['id3v2']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['ape'] ) ? serialize($ThisFileInfo['tags']['ape']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['lyrics3'] ) ? serialize($ThisFileInfo['tags']['lyrics3']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['tags']['id3v1'] ) ? serialize($ThisFileInfo['tags']['id3v1']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['warning'] ) ? implode("\t", $ThisFileInfo['warning']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['error'] ) ? implode("\t", $ThisFileInfo['error']) : '').'", '; + $SQLquery .= '"'.mysql_real_escape_string(trim((!empty($ThisFileInfo['audio']['encoder']) ? $ThisFileInfo['audio']['encoder'] : '').' '.(!empty($ThisFileInfo['audio']['encoder_options']) ? $ThisFileInfo['audio']['encoder_options'] : ''))).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['mpeg']['audio']['LAME']) ? 'LAME' : (!empty($ThisFileInfo['mpeg']['audio']['VBR_method']) ? $ThisFileInfo['mpeg']['audio']['VBR_method'] : '')).'", '; + $SQLquery .= '"'.mysql_real_escape_string(!empty($ThisFileInfo['replay_gain']['track']['volume']) ? floatval($ThisFileInfo['replay_gain']['track']['volume']) : 0).'")'; + + } + flush(); + mysql_query_safe($SQLquery); + } + + } + + $SQLquery = 'OPTIMIZE TABLE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + mysql_query_safe($SQLquery); + + echo '
Done scanning!
'; - echo '
Done scanning!
'; } elseif (!empty($_REQUEST['missingtrackvolume'])) { - $MissingTrackVolumeFilesScanned = 0; - $MissingTrackVolumeFilesAdjusted = 0; - $MissingTrackVolumeFilesDeleted = 0; - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`track_volume` = 0)'; - $SQLquery .= ' AND (`audio_bitrate` > 0)'; - $result = mysql_query_safe($SQLquery); - echo 'Scanning 0 / '.number_format(mysql_num_rows($result)).' files for track volume information:
'; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - echo '. '; - flush(); - if (file_exists($row['filename'])) { - $ThisFileInfo = $getID3->analyze($row['filename']); - if (!empty($ThisFileInfo['replay_gain']['track']['volume'])) { - $MissingTrackVolumeFilesAdjusted++; - $SQLquery = 'UPDATE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' SET `track_volume` = "'.$ThisFileInfo['replay_gain']['track']['volume'].'"'; - $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; - mysql_query_safe($SQLquery); - } - } else { - $MissingTrackVolumeFilesDeleted++; - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; - mysql_query_safe($SQLquery); - } - } - echo '
Scanned '.number_format($MissingTrackVolumeFilesScanned).' files with no track volume information.
'; - echo 'Found track volume information for '.number_format($MissingTrackVolumeFilesAdjusted).' of them (could not find info for '.number_format($MissingTrackVolumeFilesScanned - $MissingTrackVolumeFilesAdjusted).' files; deleted '.number_format($MissingTrackVolumeFilesDeleted).' records of missing files)
'; + + $MissingTrackVolumeFilesScanned = 0; + $MissingTrackVolumeFilesAdjusted = 0; + $MissingTrackVolumeFilesDeleted = 0; + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`track_volume` = 0)'; + $SQLquery .= ' AND (`audio_bitrate` > 0)'; + $result = mysql_query_safe($SQLquery); + echo 'Scanning 0 / '.number_format(mysql_num_rows($result)).' files for track volume information:
'; + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + echo '. '; + flush(); + if (file_exists($row['filename'])) { + + $ThisFileInfo = $getID3->analyze($row['filename']); + if (!empty($ThisFileInfo['replay_gain']['track']['volume'])) { + $MissingTrackVolumeFilesAdjusted++; + $SQLquery = 'UPDATE `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' SET `track_volume` = "'.$ThisFileInfo['replay_gain']['track']['volume'].'"'; + $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; + mysql_query_safe($SQLquery); + } + + } else { + + $MissingTrackVolumeFilesDeleted++; + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; + mysql_query_safe($SQLquery); + + } + } + echo '
Scanned '.number_format($MissingTrackVolumeFilesScanned).' files with no track volume information.
'; + echo 'Found track volume information for '.number_format($MissingTrackVolumeFilesAdjusted).' of them (could not find info for '.number_format($MissingTrackVolumeFilesScanned - $MissingTrackVolumeFilesAdjusted).' files; deleted '.number_format($MissingTrackVolumeFilesDeleted).' records of missing files)
'; + } elseif (!empty($_REQUEST['deadfilescheck'])) { - $SQLquery = 'SELECT COUNT(*) AS `num`, `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' GROUP BY `filename`'; - $SQLquery .= ' ORDER BY `num` DESC'; - $result = mysql_query_safe($SQLquery); - $DupesDeleted = 0; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - if ($row['num'] <= 1) { - break; - } - echo '
'.htmlentities($row['filename']).' (duplicate)'; - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE `filename` LIKE "'.mysql_real_escape_string($row['filename']).'"'; - mysql_query_safe($SQLquery); - $DupesDeleted++; - } - if ($DupesDeleted > 0) { - echo '
Deleted '.number_format($DupesDeleted).' duplicate filenames
'; - } - $SQLquery = 'SELECT `filename`, `filesize`, `last_modified`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - $totalchecked = 0; - $totalremoved = 0; - $previousdir = ''; - while ($row = mysql_fetch_array($result)) { - $totalchecked++; - set_time_limit(30); - $reason = ''; - if (!file_exists($row['filename'])) { - $reason = 'deleted'; - } elseif (filesize($row['filename']) != $row['filesize']) { - $reason = 'filesize changed'; - } elseif (filemtime($row['filename']) != $row['last_modified']) { - if (abs(filemtime($row['filename']) - $row['last_modified']) != 3600) { - // off by exactly one hour == daylight savings time - $reason = 'last-modified time changed'; - } - } + $SQLquery = 'SELECT COUNT(*) AS `num`, `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' GROUP BY `filename`'; + $SQLquery .= ' ORDER BY `num` DESC'; + $result = mysql_query_safe($SQLquery); + $DupesDeleted = 0; + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + if ($row['num'] <= 1) { + break; + } + echo '
'.htmlentities($row['filename']).' (duplicate)'; + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE `filename` LIKE "'.mysql_real_escape_string($row['filename']).'"'; + mysql_query_safe($SQLquery); + $DupesDeleted++; + } + if ($DupesDeleted > 0) { + echo '
Deleted '.number_format($DupesDeleted).' duplicate filenames
'; + } - $thisdir = dirname($row['filename']); - if ($reason) { - $totalremoved++; - echo '
'.htmlentities($row['filename']).' ('.$reason.')'; - flush(); - $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; - mysql_query_safe($SQLquery); - } elseif ($thisdir != $previousdir) { - echo '. '; - flush(); - } - $previousdir = $thisdir; - } + $SQLquery = 'SELECT `filename`, `filesize`, `last_modified`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + $totalchecked = 0; + $totalremoved = 0; + $previousdir = ''; + while ($row = mysql_fetch_array($result)) { + $totalchecked++; + set_time_limit(30); + $reason = ''; + if (!file_exists($row['filename'])) { + $reason = 'deleted'; + } elseif (filesize($row['filename']) != $row['filesize']) { + $reason = 'filesize changed'; + } elseif (filemtime($row['filename']) != $row['last_modified']) { + if (abs(filemtime($row['filename']) - $row['last_modified']) != 3600) { + // off by exactly one hour == daylight savings time + $reason = 'last-modified time changed'; + } + } + + $thisdir = dirname($row['filename']); + if ($reason) { + + $totalremoved++; + echo '
'.htmlentities($row['filename']).' ('.$reason.')'; + flush(); + $SQLquery = 'DELETE FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`filename` = "'.mysql_real_escape_string($row['filename']).'")'; + mysql_query_safe($SQLquery); + + } elseif ($thisdir != $previousdir) { + + echo '. '; + flush(); + + } + $previousdir = $thisdir; + } + + echo '
'.number_format($totalremoved).' of '.number_format($totalchecked).' files in database no longer exist, or have been altered since last scan. Removed from database.
'; - echo '
'.number_format($totalremoved).' of '.number_format($totalchecked).' files in database no longer exist, or have been altered since last scan. Removed from database.
'; } elseif (!empty($_REQUEST['encodedbydistribution'])) { - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - $SQLquery = 'SELECT `filename`, `comments_id3v2`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`encoder_options` = "'.mysql_real_escape_string($_REQUEST['encodedbydistribution']).'")'; - $result = mysql_query_safe($SQLquery); - $NonBlankEncodedBy = ''; - $BlankEncodedBy = ''; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - $CommentArray = unserialize($row['comments_id3v2']); - if (isset($CommentArray['encoded_by'][0])) { - $NonBlankEncodedBy .= WindowsShareSlashTranslate($row['filename'])."\n"; - } else { - $BlankEncodedBy .= WindowsShareSlashTranslate($row['filename'])."\n"; - } - } - echo $NonBlankEncodedBy; - echo $BlankEncodedBy; - exit; - } elseif (!empty($_REQUEST['showfiles'])) { - echo 'show all
'; - echo ''; + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + + $SQLquery = 'SELECT `filename`, `comments_id3v2`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`encoder_options` = "'.mysql_real_escape_string($_REQUEST['encodedbydistribution']).'")'; + $result = mysql_query_safe($SQLquery); + $NonBlankEncodedBy = ''; + $BlankEncodedBy = ''; + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + $CommentArray = unserialize($row['comments_id3v2']); + if (isset($CommentArray['encoded_by'][0])) { + $NonBlankEncodedBy .= WindowsShareSlashTranslate($row['filename'])."\n"; + } else { + $BlankEncodedBy .= WindowsShareSlashTranslate($row['filename'])."\n"; + } + } + echo $NonBlankEncodedBy; + echo $BlankEncodedBy; + exit; + + } elseif (!empty($_REQUEST['showfiles'])) { + + echo 'show all
'; + echo '
'; + + $SQLquery = 'SELECT `filename`, `comments_id3v2`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $result = mysql_query_safe($SQLquery); + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + $CommentArray = unserialize($row['comments_id3v2']); + if (($_REQUEST['encodedbydistribution'] == '%') || (!empty($CommentArray['encoded_by'][0]) && ($_REQUEST['encodedbydistribution'] == $CommentArray['encoded_by'][0]))) { + echo ''; + echo ''; + } + } + echo '
m3u'.htmlentities($row['filename']).'
'; + + } else { + + $SQLquery = 'SELECT `encoder_options`, `comments_id3v2`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' ORDER BY (`encoder_options` LIKE "LAME%") DESC, (`encoder_options` LIKE "CBR%") DESC'; + $result = mysql_query_safe($SQLquery); + $EncodedBy = array(); + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + $CommentArray = unserialize($row['comments_id3v2']); + if (isset($CommentArray['encoded_by'][0])) { + if (isset($EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]])) { + $EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]]++; + } else { + $EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]] = 1; + } + } + } + echo '.m3u version
'; + echo ''; + foreach ($EncodedBy as $key => $value) { + echo ''; + echo ''; + echo ''; + } + echo '
m3uEncoder OptionsEncoded By (ID3v2)
m3u'.$key.''; + arsort($value); + foreach ($value as $string => $count) { + echo ''; + echo ''; + } + echo '
'.number_format($count).' '.$string.'
'; + + } - $SQLquery = 'SELECT `filename`, `comments_id3v2`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $result = mysql_query_safe($SQLquery); - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - $CommentArray = unserialize($row['comments_id3v2']); - if (($_REQUEST['encodedbydistribution'] == '%') || (!empty($CommentArray['encoded_by'][0]) && ($_REQUEST['encodedbydistribution'] == $CommentArray['encoded_by'][0]))) { - echo 'm3u'; - echo ''.htmlentities($row['filename']).''; - } - } - echo ''; - } else { - $SQLquery = 'SELECT `encoder_options`, `comments_id3v2`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' ORDER BY (`encoder_options` LIKE "LAME%") DESC, (`encoder_options` LIKE "CBR%") DESC'; - $result = mysql_query_safe($SQLquery); - $EncodedBy = []; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - $CommentArray = unserialize($row['comments_id3v2']); - if (isset($CommentArray['encoded_by'][0])) { - if (isset($EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]])) { - $EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]]++; - } else { - $EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]] = 1; - } - } - } - echo '.m3u version
'; - echo ''; - foreach ($EncodedBy as $key => $value) { - echo ''; - echo ''; - echo ''; - } - echo '
m3uEncoder OptionsEncoded By (ID3v2)
m3u'.$key.''; - arsort($value); - foreach ($value as $string => $count) { - echo ''; - echo ''; - } - echo '
'.number_format($count).' '.$string.'
'; - } } elseif (!empty($_REQUEST['audiobitrates'])) { - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); - $BitrateDistribution = []; - $SQLquery = 'SELECT ROUND(audio_bitrate / 1000) AS `RoundBitrate`, COUNT(*) AS `num`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`audio_bitrate` > 0)'; - $SQLquery .= ' GROUP BY `RoundBitrate`'; - $result = mysql_query_safe($SQLquery); - while ($row = mysql_fetch_array($result)) { - $this_bitrate = getid3_mp3::ClosestStandardMP3Bitrate($row['RoundBitrate'] * 1000); - if (isset($BitrateDistribution[$this_bitrate])) { - $BitrateDistribution[$this_bitrate] += $row['num']; - } else { - $BitrateDistribution[$this_bitrate] = $row['num']; - } - } - echo ''; - echo ''; - foreach ($BitrateDistribution as $Bitrate => $Count) { - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
BitrateCount
'.round($Bitrate / 1000).' kbps'.number_format($Count).'
'; + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true); + $BitrateDistribution = array(); + $SQLquery = 'SELECT ROUND(audio_bitrate / 1000) AS `RoundBitrate`, COUNT(*) AS `num`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`audio_bitrate` > 0)'; + $SQLquery .= ' GROUP BY `RoundBitrate`'; + $result = mysql_query_safe($SQLquery); + while ($row = mysql_fetch_array($result)) { + $this_bitrate = getid3_mp3::ClosestStandardMP3Bitrate($row['RoundBitrate'] * 1000); + if (isset($BitrateDistribution[$this_bitrate])) { + $BitrateDistribution[$this_bitrate] += $row['num']; + } else { + $BitrateDistribution[$this_bitrate] = $row['num']; + } + } + + echo ''; + echo ''; + foreach ($BitrateDistribution as $Bitrate => $Count) { + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
BitrateCount
'.round($Bitrate / 1000).' kbps'.number_format($Count).'
'; + + } elseif (!empty($_REQUEST['emptygenres'])) { - $SQLquery = 'SELECT `fileformat`, `filename`, `genre`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`genre` = "")'; - $SQLquery .= ' OR (`genre` = "Unknown")'; - $SQLquery .= ' OR (`genre` = "Other")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - if (!in_array($row['fileformat'], $IgnoreNoTagFormats)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - } - exit; - } else { - echo '.m3u version
'; - $EmptyGenreCounter = 0; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - if (!in_array($row['fileformat'], $IgnoreNoTagFormats)) { - $EmptyGenreCounter++; - echo ''; - echo ''; - echo ''; - echo ''; - } - } - echo '
m3ufilename
m3u'.htmlentities($row['filename']).'
'; - echo ''.number_format($EmptyGenreCounter).' files with empty genres'; - } + $SQLquery = 'SELECT `fileformat`, `filename`, `genre`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`genre` = "")'; + $SQLquery .= ' OR (`genre` = "Unknown")'; + $SQLquery .= ' OR (`genre` = "Other")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + if (!in_array($row['fileformat'], $IgnoreNoTagFormats)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + } + exit; + + } else { + + echo '.m3u version
'; + $EmptyGenreCounter = 0; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + if (!in_array($row['fileformat'], $IgnoreNoTagFormats)) { + $EmptyGenreCounter++; + echo ''; + echo ''; + echo ''; + echo ''; + } + } + echo '
m3ufilename
m3u'.htmlentities($row['filename']).'
'; + echo ''.number_format($EmptyGenreCounter).' files with empty genres'; + + } + } elseif (!empty($_REQUEST['nonemptycomments'])) { - $SQLquery = 'SELECT `filename`, `comment`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`comment` <> "")'; - $SQLquery .= ' ORDER BY `comment` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - $NonEmptyCommentsCounter = 0; - echo '.m3u version
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - $NonEmptyCommentsCounter++; - echo ''; - echo ''; - echo ''; - if (strlen(trim($row['comment'])) > 0) { - echo ''; - } else { - echo ''; - } - echo ''; - } - echo '
m3ufilenamecomments
m3u'.htmlentities($row['filename']).''.htmlentities($row['comment']).'space
'; - echo ''.number_format($NonEmptyCommentsCounter).' files with non-empty comments'; - } + $SQLquery = 'SELECT `filename`, `comment`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`comment` <> "")'; + $SQLquery .= ' ORDER BY `comment` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + $NonEmptyCommentsCounter = 0; + echo '.m3u version
'; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + $NonEmptyCommentsCounter++; + echo ''; + echo ''; + echo ''; + if (strlen(trim($row['comment'])) > 0) { + echo ''; + } else { + echo ''; + } + echo ''; + } + echo '
m3ufilenamecomments
m3u'.htmlentities($row['filename']).''.htmlentities($row['comment']).'space
'; + echo ''.number_format($NonEmptyCommentsCounter).' files with non-empty comments'; + + } + } elseif (!empty($_REQUEST['trackzero'])) { - $SQLquery = 'SELECT `filename`, `track`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`track` <> "")'; - $SQLquery .= ' AND ((`track` < "1")'; - $SQLquery .= ' OR (`track` > "99"))'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - if ((strlen($row['track']) > 0) && ($row['track'] < 1) || ($row['track'] > 99)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - } - exit; - } else { - echo '.m3u version
'; - $TrackZeroCounter = 0; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - if ((strlen($row['track']) > 0) && ($row['track'] < 1) || ($row['track'] > 99)) { - $TrackZeroCounter++; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - } - echo '
m3ufilenametrack
m3u'.htmlentities($row['filename']).''.htmlentities($row['track']).'
'; - echo ''.number_format($TrackZeroCounter).' files with track "zero"'; - } + $SQLquery = 'SELECT `filename`, `track`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`track` <> "")'; + $SQLquery .= ' AND ((`track` < "1")'; + $SQLquery .= ' OR (`track` > "99"))'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + if ((strlen($row['track']) > 0) && ($row['track'] < 1) || ($row['track'] > 99)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + } + exit; + + } else { + + echo '.m3u version
'; + $TrackZeroCounter = 0; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + if ((strlen($row['track']) > 0) && ($row['track'] < 1) || ($row['track'] > 99)) { + $TrackZeroCounter++; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + } + echo '
m3ufilenametrack
m3u'.htmlentities($row['filename']).''.htmlentities($row['track']).'
'; + echo ''.number_format($TrackZeroCounter).' files with track "zero"'; + + } + + } elseif (!empty($_REQUEST['titlefeat'])) { - $SQLquery = 'SELECT `filename`, `title`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`title` LIKE "%feat.%")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - echo ''.number_format(mysql_num_rows($result)).' files with "feat." in the title (instead of the artist)

'; - echo '.m3u version
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
m3ufilenametitle
m3u'.htmlentities($row['filename']).''.preg_replace('#(feat\. .*)#i', '\\1', htmlentities($row['title'])).'
'; - } + $SQLquery = 'SELECT `filename`, `title`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`title` LIKE "%feat.%")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + echo ''.number_format(mysql_num_rows($result)).' files with "feat." in the title (instead of the artist)

'; + echo '.m3u version
'; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
m3ufilenametitle
m3u'.htmlentities($row['filename']).''.preg_replace('#(feat\. .*)#i', '\\1', htmlentities($row['title'])).'
'; + + } + + } elseif (!empty($_REQUEST['tracknoalbum'])) { - $SQLquery = 'SELECT `filename`, `track`, `album`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`track` <> "")'; - $SQLquery .= ' AND (`album` = "")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - echo ''.number_format(mysql_num_rows($result)).' files with a track number, but no album

'; - echo '.m3u version
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
m3ufilenametrackalbum
m3u'.htmlentities($row['filename']).''.htmlentities($row['track']).''.htmlentities($row['album']).'
'; - } + $SQLquery = 'SELECT `filename`, `track`, `album`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`track` <> "")'; + $SQLquery .= ' AND (`album` = "")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + echo ''.number_format(mysql_num_rows($result)).' files with a track number, but no album

'; + echo '.m3u version
'; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
m3ufilenametrackalbum
m3u'.htmlentities($row['filename']).''.htmlentities($row['track']).''.htmlentities($row['album']).'
'; + + } + + } elseif (!empty($_REQUEST['synchronizetagsfrom']) && !empty($_REQUEST['filename'])) { - echo 'Applying new tags from '.$_REQUEST['synchronizetagsfrom'].' in '.htmlentities($_REQUEST['filename']).'
    '; - $errors = []; - if (SynchronizeAllTags($_REQUEST['filename'], $_REQUEST['synchronizetagsfrom'], 'A12', $errors)) { - echo '
  • Sucessfully wrote tags
  • '; - } else { - echo '
  • Tag writing had errors:
    • '.implode('
    • ', $errors).'
  • '; - } - echo '
'; + + echo 'Applying new tags from '.$_REQUEST['synchronizetagsfrom'].' in '.htmlentities($_REQUEST['filename']).'
    '; + $errors = array(); + if (SynchronizeAllTags($_REQUEST['filename'], $_REQUEST['synchronizetagsfrom'], 'A12', $errors)) { + echo '
  • Sucessfully wrote tags
  • '; + } else { + echo '
  • Tag writing had errors:
    • '.implode('
    • ', $errors).'
  • '; + } + echo '
'; + + } elseif (!empty($_REQUEST['unsynchronizedtags'])) { - $NotOKfiles = 0; - $Autofixedfiles = 0; - $FieldsToCompare = ['title', 'artist', 'album', 'year', 'genre', 'comment', 'track']; - $TagsToCompare = ['id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false]; - $ID3v1FieldLengths = ['title'=>30, 'artist'=>30, 'album'=>30, 'year'=>4, 'genre'=>99, 'comment'=>28]; - if (strpos($_REQUEST['unsynchronizedtags'], '2') !== false) { - $TagsToCompare['id3v2'] = true; - } - if (strpos($_REQUEST['unsynchronizedtags'], 'A') !== false) { - $TagsToCompare['ape'] = true; - } - if (strpos($_REQUEST['unsynchronizedtags'], 'L') !== false) { - $TagsToCompare['lyrics3'] = true; - } - if (strpos($_REQUEST['unsynchronizedtags'], '1') !== false) { - $TagsToCompare['id3v1'] = true; - } - echo 'Auto-fix empty tags

'; - echo '
'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - if ($TagsToCompare['id3v2']) { - echo ''; - } - if ($TagsToCompare['ape']) { - echo ''; - } - if ($TagsToCompare['lyrics3']) { - echo ''; - } - if ($TagsToCompare['id3v1']) { - echo ''; - } - echo ''; + $NotOKfiles = 0; + $Autofixedfiles = 0; + $FieldsToCompare = array('title', 'artist', 'album', 'year', 'genre', 'comment', 'track'); + $TagsToCompare = array('id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false); + $ID3v1FieldLengths = array('title'=>30, 'artist'=>30, 'album'=>30, 'year'=>4, 'genre'=>99, 'comment'=>28); + if (strpos($_REQUEST['unsynchronizedtags'], '2') !== false) { + $TagsToCompare['id3v2'] = true; + } + if (strpos($_REQUEST['unsynchronizedtags'], 'A') !== false) { + $TagsToCompare['ape'] = true; + } + if (strpos($_REQUEST['unsynchronizedtags'], 'L') !== false) { + $TagsToCompare['lyrics3'] = true; + } + if (strpos($_REQUEST['unsynchronizedtags'], '1') !== false) { + $TagsToCompare['id3v1'] = true; + } - $SQLquery = 'SELECT `filename`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` = "mp3")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - $lastdir = ''; - $serializedCommentsFields = ['all', 'id3v2', 'ape', 'lyrics3', 'id3v1']; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - if ($lastdir != dirname($row['filename'])) { - echo ''; - flush(); - } + echo 'Auto-fix empty tags

'; + echo '
'; + echo '
ViewFilenameCombinedID3v2APELyrics3ID3v1
'; + echo ''; + echo ''; + echo ''; + echo ''; + if ($TagsToCompare['id3v2']) { + echo ''; + } + if ($TagsToCompare['ape']) { + echo ''; + } + if ($TagsToCompare['lyrics3']) { + echo ''; + } + if ($TagsToCompare['id3v1']) { + echo ''; + } + echo ''; - $FileOK = true; - $Mismatched = ['id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false]; - $SemiMatched = ['id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false]; - $EmptyTags = ['id3v2'=>true, 'ape'=>true, 'lyrics3'=>true, 'id3v1'=>true]; + $SQLquery = 'SELECT `filename`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` = "mp3")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + $lastdir = ''; + $serializedCommentsFields = array('all', 'id3v2', 'ape', 'lyrics3', 'id3v1'); + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + if ($lastdir != dirname($row['filename'])) { + echo ''; + flush(); + } - foreach ($serializedCommentsFields as $field) { - $Comments[$field] = []; - ob_start(); - if ($unserialized = unserialize($row['comments_'.$field])) { - $Comments[$field] = $unserialized; - } - $errormessage = ob_get_contents(); - ob_end_clean(); - } + $FileOK = true; + $Mismatched = array('id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false); + $SemiMatched = array('id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false); + $EmptyTags = array('id3v2'=>true, 'ape'=>true, 'lyrics3'=>true, 'id3v1'=>true); - if (isset($Comments['ape']['tracknumber'])) { - $Comments['ape']['track'] = $Comments['ape']['tracknumber']; - unset($Comments['ape']['tracknumber']); - } - if (isset($Comments['ape']['track_number'])) { - $Comments['ape']['track'] = $Comments['ape']['track_number']; - unset($Comments['ape']['track_number']); - } - if (isset($Comments['id3v2']['track_number'])) { - $Comments['id3v2']['track'] = $Comments['id3v2']['track_number']; - unset($Comments['id3v2']['track_number']); - } - if (!empty($Comments['all']['track'])) { - $besttrack = ''; - foreach ($Comments['all']['track'] as $key => $value) { - if (strlen($value) > strlen($besttrack)) { - $besttrack = $value; - } - } - $Comments['all']['track'] = [0=>$besttrack]; - } + foreach ($serializedCommentsFields as $field) { + $Comments[$field] = array(); + ob_start(); + if ($unserialized = unserialize($row['comments_'.$field])) { + $Comments[$field] = $unserialized; + } + $errormessage = ob_get_contents(); + ob_end_clean(); + } - $ThisLine = ''; - $ThisLine .= ''; - $ThisLine .= ''; - $tagvalues = ''; - foreach ($FieldsToCompare as $fieldname) { - $tagvalues .= $fieldname.' = '.(!empty($Comments['all'][$fieldname]) ? implode(" \n", $Comments['all'][$fieldname]) : '')." \n"; - } - $ThisLine .= ''; - foreach ($TagsToCompare as $tagtype => $CompareThisTagType) { - if ($CompareThisTagType) { - $tagvalues = ''; - foreach ($FieldsToCompare as $fieldname) { - if ($tagtype == 'id3v1') { - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); - if (($fieldname == 'genre') && !empty($Comments['all'][$fieldname][0]) && !getid3_id3v1::LookupGenreID($Comments['all'][$fieldname][0])) { - // non-standard genres can never match, so just ignore - $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - } elseif ($fieldname == 'comment') { - if (isset($Comments[$tagtype][$fieldname][0]) && isset($Comments['all'][$fieldname][0]) && (rtrim(substr($Comments[$tagtype][$fieldname][0], 0, 28)) != rtrim(substr($Comments['all'][$fieldname][0], 0, 28)))) { - $tagvalues .= $fieldname.' = [['.$Comments[$tagtype][$fieldname][0].']]'."\n"; - if (trim(strtolower(RemoveAccents(substr($Comments[$tagtype][$fieldname][0], 0, 28)))) == trim(strtolower(RemoveAccents(substr($Comments['all'][$fieldname][0], 0, 28))))) { - $SemiMatched[$tagtype] = true; - } else { - $Mismatched[$tagtype] = true; - } - $FileOK = false; - } else { - $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - } - } elseif ($fieldname == 'track') { - // intval('01/20') == intval('1') - $trackA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''); - $trackB = (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''); - if (intval($trackA) != intval($trackB)) { - $tagvalues .= $fieldname.' = [['.$trackA.']]'."\n"; - $Mismatched[$tagtype] = true; - $FileOK = false; - } else { - $tagvalues .= $fieldname.' = '.$trackA."\n"; - } - } elseif ((isset($Comments[$tagtype][$fieldname][0]) ? rtrim(substr($Comments[$tagtype][$fieldname][0], 0, 30)) : '') != (isset($Comments['all'][$fieldname][0]) ? rtrim(substr($Comments['all'][$fieldname][0], 0, 30)) : '')) { - $tagvalues .= $fieldname.' = [['.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '').']]'."\n"; - if (strtolower(RemoveAccents(trim(substr((isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''), 0, 30)))) == strtolower(RemoveAccents(trim(substr((isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''), 0, 30))))) { - $SemiMatched[$tagtype] = true; - } else { - $Mismatched[$tagtype] = true; - } - $FileOK = false; - if (!empty($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } else { - $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } - } elseif (($tagtype == 'ape') && ($fieldname == 'year')) { - if (((isset($Comments['ape']['date'][0]) ? $Comments['ape']['date'][0] : '') != (isset($Comments['all']['year'][0]) ? $Comments['all']['year'][0] : '')) && ((isset($Comments['ape']['year'][0]) ? $Comments['ape']['year'][0] : '') != (isset($Comments['all']['year'][0]) ? $Comments['all']['year'][0] : ''))) { - $tagvalues .= $fieldname.' = [['.(isset($Comments['ape']['date'][0]) ? $Comments['ape']['date'][0] : '').']]'."\n"; - $Mismatched[$tagtype] = true; - $FileOK = false; - if (isset($Comments['ape']['date'][0]) && (strlen(trim($Comments['ape']['date'][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } else { - $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } - } elseif (($fieldname == 'genre') && !empty($Comments['all'][$fieldname]) && !empty($Comments[$tagtype][$fieldname]) && in_array($Comments[$tagtype][$fieldname][0], $Comments['all'][$fieldname])) { - $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } elseif ((isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '') != (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : '')) { - $skiptracknumberfield = false; - switch ($fieldname) { - case 'track': - case 'tracknumber': - case 'track_number': - $trackA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''); - $trackB = (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''); - if (intval($trackA) == intval($trackB)) { - $skiptracknumberfield = true; - } - break; - } - if (!$skiptracknumberfield) { - $tagvalues .= $fieldname.' = [['.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '').']]'."\n"; - $tagA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''); - $tagB = (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''); - if (trim(strtolower(RemoveAccents($tagA))) == trim(strtolower(RemoveAccents($tagB)))) { - $SemiMatched[$tagtype] = true; - } else { - $Mismatched[$tagtype] = true; - } - $FileOK = false; - if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } - } else { - $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { - $EmptyTags[$tagtype] = false; - } - } - } + if (isset($Comments['ape']['tracknumber'])) { + $Comments['ape']['track'] = $Comments['ape']['tracknumber']; + unset($Comments['ape']['tracknumber']); + } + if (isset($Comments['ape']['track_number'])) { + $Comments['ape']['track'] = $Comments['ape']['track_number']; + unset($Comments['ape']['track_number']); + } + if (isset($Comments['id3v2']['track_number'])) { + $Comments['id3v2']['track'] = $Comments['id3v2']['track_number']; + unset($Comments['id3v2']['track_number']); + } + if (!empty($Comments['all']['track'])) { + $besttrack = ''; + foreach ($Comments['all']['track'] as $key => $value) { + if (strlen($value) > strlen($besttrack)) { + $besttrack = $value; + } + } + $Comments['all']['track'] = array(0=>$besttrack); + } - if ($EmptyTags[$tagtype]) { - $FileOK = false; - $ThisLine .= ''; - } - } - $ThisLine .= ''; + $ThisLine = ''; + $ThisLine .= ''; + $ThisLine .= ''; + $tagvalues = ''; + foreach ($FieldsToCompare as $fieldname) { + $tagvalues .= $fieldname.' = '.(!empty($Comments['all'][$fieldname]) ? implode(" \n", $Comments['all'][$fieldname]) : '')." \n"; + } + $ThisLine .= ''; + foreach ($TagsToCompare as $tagtype => $CompareThisTagType) { + if ($CompareThisTagType) { + $tagvalues = ''; + foreach ($FieldsToCompare as $fieldname) { - if (!$FileOK) { - $NotOKfiles++; + if ($tagtype == 'id3v1') { - echo ''; - flush(); + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); + if (($fieldname == 'genre') && !empty($Comments['all'][$fieldname][0]) && !getid3_id3v1::LookupGenreID($Comments['all'][$fieldname][0])) { - if (!empty($_REQUEST['autofix'])) { - $AnyMismatched = false; - foreach ($Mismatched as $key => $value) { - if ($value && ($EmptyTags["$key"] === false)) { - $AnyMismatched = true; - } - } - if ($AnyMismatched && empty($_REQUEST['autofixforcesource'])) { - echo $ThisLine; - } else { - $TagsToSynch = ''; - foreach ($EmptyTags as $key => $value) { - if ($value) { - switch ($key) { - case 'id3v1': - $TagsToSynch .= '1'; - break; - case 'id3v2': - $TagsToSynch .= '2'; - break; - case 'ape': - $TagsToSynch .= 'A'; - break; - } - } - } + // non-standard genres can never match, so just ignore + $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; - $autofixforcesource = (!empty($_REQUEST['autofixforcesource']) ? $_REQUEST['autofixforcesource'] : 'all'); - $TagsToSynch = (!empty($_REQUEST['autofixforcedest']) ? $_REQUEST['autofixforcedest'] : $TagsToSynch); + } elseif ($fieldname == 'comment') { - $errors = []; - if (SynchronizeAllTags($row['filename'], $autofixforcesource, $TagsToSynch, $errors)) { - $Autofixedfiles++; - echo ''; - } else { - echo ''; - } - echo ''; - echo ''; - } - } else { - echo $ThisLine; - } - } - } + if (isset($Comments[$tagtype][$fieldname][0]) && isset($Comments['all'][$fieldname][0]) && (rtrim(substr($Comments[$tagtype][$fieldname][0], 0, 28)) != rtrim(substr($Comments['all'][$fieldname][0], 0, 28)))) { + $tagvalues .= $fieldname.' = [['.$Comments[$tagtype][$fieldname][0].']]'."\n"; + if (trim(strtolower(RemoveAccents(substr($Comments[$tagtype][$fieldname][0], 0, 28)))) == trim(strtolower(RemoveAccents(substr($Comments['all'][$fieldname][0], 0, 28))))) { + $SemiMatched[$tagtype] = true; + } else { + $Mismatched[$tagtype] = true; + } + $FileOK = false; + } else { + $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; + } + + } elseif ($fieldname == 'track') { + + // intval('01/20') == intval('1') + $trackA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''); + $trackB = (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''); + if (intval($trackA) != intval($trackB)) { + $tagvalues .= $fieldname.' = [['.$trackA.']]'."\n"; + $Mismatched[$tagtype] = true; + $FileOK = false; + } else { + $tagvalues .= $fieldname.' = '.$trackA."\n"; + } + + } elseif ((isset($Comments[$tagtype][$fieldname][0]) ? rtrim(substr($Comments[$tagtype][$fieldname][0], 0, 30)) : '') != (isset($Comments['all'][$fieldname][0]) ? rtrim(substr($Comments['all'][$fieldname][0], 0, 30)) : '')) { + + $tagvalues .= $fieldname.' = [['.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '').']]'."\n"; + if (strtolower(RemoveAccents(trim(substr((isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''), 0, 30)))) == strtolower(RemoveAccents(trim(substr((isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''), 0, 30))))) { + $SemiMatched[$tagtype] = true; + } else { + $Mismatched[$tagtype] = true; + } + $FileOK = false; + if (!empty($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + + } else { + + $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; + if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + + } + + } elseif (($tagtype == 'ape') && ($fieldname == 'year')) { + + if (((isset($Comments['ape']['date'][0]) ? $Comments['ape']['date'][0] : '') != (isset($Comments['all']['year'][0]) ? $Comments['all']['year'][0] : '')) && ((isset($Comments['ape']['year'][0]) ? $Comments['ape']['year'][0] : '') != (isset($Comments['all']['year'][0]) ? $Comments['all']['year'][0] : ''))) { + + $tagvalues .= $fieldname.' = [['.(isset($Comments['ape']['date'][0]) ? $Comments['ape']['date'][0] : '').']]'."\n"; + $Mismatched[$tagtype] = true; + $FileOK = false; + if (isset($Comments['ape']['date'][0]) && (strlen(trim($Comments['ape']['date'][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + + } else { + + $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; + if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + + } + + } elseif (($fieldname == 'genre') && !empty($Comments['all'][$fieldname]) && !empty($Comments[$tagtype][$fieldname]) && in_array($Comments[$tagtype][$fieldname][0], $Comments['all'][$fieldname])) { + + $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; + if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + + } elseif ((isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '') != (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : '')) { + + $skiptracknumberfield = false; + switch ($fieldname) { + case 'track': + case 'tracknumber': + case 'track_number': + $trackA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''); + $trackB = (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''); + if (intval($trackA) == intval($trackB)) { + $skiptracknumberfield = true; + } + break; + } + if (!$skiptracknumberfield) { + $tagvalues .= $fieldname.' = [['.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '').']]'."\n"; + $tagA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''); + $tagB = (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''); + if (trim(strtolower(RemoveAccents($tagA))) == trim(strtolower(RemoveAccents($tagB)))) { + $SemiMatched[$tagtype] = true; + } else { + $Mismatched[$tagtype] = true; + } + $FileOK = false; + if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + } + + } else { + + $tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n"; + if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) { + $EmptyTags[$tagtype] = false; + } + + } + } + + if ($EmptyTags[$tagtype]) { + $FileOK = false; + $ThisLine .= ''; + } + } + $ThisLine .= ''; + + if (!$FileOK) { + $NotOKfiles++; + + echo ''; + flush(); + + if (!empty($_REQUEST['autofix'])) { + + $AnyMismatched = false; + foreach ($Mismatched as $key => $value) { + if ($value && ($EmptyTags["$key"] === false)) { + $AnyMismatched = true; + } + } + if ($AnyMismatched && empty($_REQUEST['autofixforcesource'])) { + + echo $ThisLine; + + } else { + + $TagsToSynch = ''; + foreach ($EmptyTags as $key => $value) { + if ($value) { + switch ($key) { + case 'id3v1': + $TagsToSynch .= '1'; + break; + case 'id3v2': + $TagsToSynch .= '2'; + break; + case 'ape': + $TagsToSynch .= 'A'; + break; + } + } + } + + $autofixforcesource = (!empty($_REQUEST['autofixforcesource']) ? $_REQUEST['autofixforcesource'] : 'all'); + $TagsToSynch = (!empty($_REQUEST['autofixforcedest']) ? $_REQUEST['autofixforcedest'] : $TagsToSynch); + + $errors = array(); + if (SynchronizeAllTags($row['filename'], $autofixforcesource, $TagsToSynch, $errors)) { + $Autofixedfiles++; + echo ''; + } else { + echo ''; + } + echo ''; + echo ''; + } + + } else { + + echo $ThisLine; + + } + } + } + + echo '
ViewFilenameCombinedID3v2APELyrics3ID3v1
view'.htmlentities($row['filename']).'all'; - } elseif ($SemiMatched[$tagtype]) { - $ThisLine .= ''; - } elseif ($Mismatched[$tagtype]) { - $ThisLine .= ''; - } else { - $ThisLine .= ''; - } - $ThisLine .= ''.$tagtype.''; - $ThisLine .= '
view'.htmlentities($row['filename']).'all
 '; - echo ''.htmlentities($row['filename']).''; - echo ''; - echo '
'.$TagsToSynch.'
'; + } elseif ($SemiMatched[$tagtype]) { + $ThisLine .= ''; + } elseif ($Mismatched[$tagtype]) { + $ThisLine .= ''; + } else { + $ThisLine .= ''; + } + $ThisLine .= ''.$tagtype.''; + $ThisLine .= '
 '; + echo ''.htmlentities($row['filename']).''; + echo ''; + echo '
'.$TagsToSynch.'

'; + echo ''; + echo 'Found '.number_format($NotOKfiles).' files with unsynchronized tags, and auto-fixed '.number_format($Autofixedfiles).' of them.'; - echo '
'; - echo ''; - echo 'Found '.number_format($NotOKfiles).' files with unsynchronized tags, and auto-fixed '.number_format($Autofixedfiles).' of them.'; } elseif (!empty($_REQUEST['filenamepattern'])) { - $patterns['A'] = 'artist'; - $patterns['T'] = 'title'; - $patterns['M'] = 'album'; - $patterns['N'] = 'track'; - $patterns['G'] = 'genre'; - $patterns['R'] = 'remix'; - $FieldsToUse = explode(' ', wordwrap(preg_replace('#[^A-Z]#i', '', $_REQUEST['filenamepattern']), 1, ' ', 1)); - //$FieldsToUse = explode(' ', wordwrap($_REQUEST['filenamepattern'], 1, ' ', 1)); - foreach ($FieldsToUse as $FieldID) { - $FieldNames[] = $patterns["$FieldID"]; - } + $patterns['A'] = 'artist'; + $patterns['T'] = 'title'; + $patterns['M'] = 'album'; + $patterns['N'] = 'track'; + $patterns['G'] = 'genre'; + $patterns['R'] = 'remix'; - $SQLquery = 'SELECT `filename`, `fileformat`, '.implode(', ', $FieldNames); - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - echo 'Files that do not match naming pattern: (auto-fix)
'; - echo ''; - echo ''; - $nonmatchingfilenames = 0; - $Pattern = $_REQUEST['filenamepattern']; - $PatternLength = strlen($Pattern); - while ($row = mysql_fetch_array($result)) { - set_time_limit(10); - $PatternFilename = ''; - for ($i = 0; $i < $PatternLength; $i++) { - if (isset($patterns[$Pattern{$i}])) { - $PatternFilename .= trim(strtr($row[$patterns[$Pattern{$i}]], ':\\*<>|', ';-¤«»¦'), ' '); - } else { - $PatternFilename .= $Pattern{$i}; - } - } + $FieldsToUse = explode(' ', wordwrap(preg_replace('#[^A-Z]#i', '', $_REQUEST['filenamepattern']), 1, ' ', 1)); + //$FieldsToUse = explode(' ', wordwrap($_REQUEST['filenamepattern'], 1, ' ', 1)); + foreach ($FieldsToUse as $FieldID) { + $FieldNames[] = $patterns["$FieldID"]; + } - // Replace "~" with "-" if characters immediately before and after are both numbers, - // "/" has been replaced with "~" above which is good for multi-song medley dividers, - // but for things like 24/7, 7/8ths, etc it looks better if it's 24-7, 7-8ths, etc. - $PatternFilename = preg_replace('#([ a-z]+)/([ a-z]+)#i', '\\1~\\2', $PatternFilename); - $PatternFilename = str_replace('/', '×', $PatternFilename); + $SQLquery = 'SELECT `filename`, `fileformat`, '.implode(', ', $FieldNames); + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + echo 'Files that do not match naming pattern: (auto-fix)
'; + echo '
viewWhyActual filename
(click to play/edit file)
Correct filename (based on tags)'.(empty($_REQUEST['autofix']) ? '
(click to rename file to this)' : '').'
'; + echo ''; + $nonmatchingfilenames = 0; + $Pattern = $_REQUEST['filenamepattern']; + $PatternLength = strlen($Pattern); + while ($row = mysql_fetch_array($result)) { + set_time_limit(10); + $PatternFilename = ''; + for ($i = 0; $i < $PatternLength; $i++) { + if (isset($patterns[$Pattern{$i}])) { + $PatternFilename .= trim(strtr($row[$patterns[$Pattern{$i}]], ':\\*<>|', ';-¤«»¦'), ' '); + } else { + $PatternFilename .= $Pattern{$i}; + } + } - $PatternFilename = str_replace('?', '¿', $PatternFilename); - $PatternFilename = str_replace(' "', ' “', $PatternFilename); - $PatternFilename = str_replace('("', '(“', $PatternFilename); - $PatternFilename = str_replace('-"', '-“', $PatternFilename); - $PatternFilename = str_replace('" ', '” ', $PatternFilename.' '); - $PatternFilename = str_replace('"', '”', $PatternFilename); - $PatternFilename = str_replace(' ', ' ', $PatternFilename); + // Replace "~" with "-" if characters immediately before and after are both numbers, + // "/" has been replaced with "~" above which is good for multi-song medley dividers, + // but for things like 24/7, 7/8ths, etc it looks better if it's 24-7, 7-8ths, etc. + $PatternFilename = preg_replace('#([ a-z]+)/([ a-z]+)#i', '\\1~\\2', $PatternFilename); + $PatternFilename = str_replace('/', '×', $PatternFilename); + + $PatternFilename = str_replace('?', '¿', $PatternFilename); + $PatternFilename = str_replace(' "', ' “', $PatternFilename); + $PatternFilename = str_replace('("', '(“', $PatternFilename); + $PatternFilename = str_replace('-"', '-“', $PatternFilename); + $PatternFilename = str_replace('" ', '” ', $PatternFilename.' '); + $PatternFilename = str_replace('"', '”', $PatternFilename); + $PatternFilename = str_replace(' ', ' ', $PatternFilename); - $ParenthesesPairs = ['()', '[]', '{}']; - foreach ($ParenthesesPairs as $pair) { - // multiple remixes are stored tab-seperated in the database. - // change "{2000 Version\tSomebody Remix}" into "{2000 Version} {Somebody Remix}" - while (preg_match('#^(.*)'.preg_quote($pair{0}).'([^'.preg_quote($pair{1}).']*)('."\t".')([^'.preg_quote($pair{0}).']*)'.preg_quote($pair{1}).'#', $PatternFilename, $matches)) { - $PatternFilename = $matches[1].$pair{0}.$matches[2].$pair{1}.' '.$pair{0}.$matches[4].$pair{1}; - } + $ParenthesesPairs = array('()', '[]', '{}'); + foreach ($ParenthesesPairs as $pair) { - // remove empty parenthesized pairs (probably where no track numbers, remix version, etc) - $PatternFilename = preg_replace('#'.preg_quote($pair).'#', '', $PatternFilename); + // multiple remixes are stored tab-seperated in the database. + // change "{2000 Version\tSomebody Remix}" into "{2000 Version} {Somebody Remix}" + while (preg_match('#^(.*)'.preg_quote($pair{0}).'([^'.preg_quote($pair{1}).']*)('."\t".')([^'.preg_quote($pair{0}).']*)'.preg_quote($pair{1}).'#', $PatternFilename, $matches)) { + $PatternFilename = $matches[1].$pair{0}.$matches[2].$pair{1}.' '.$pair{0}.$matches[4].$pair{1}; + } - // "[01] - Title With No Artist.mp3" ==> "[01] Title With No Artist.mp3" - $PatternFilename = preg_replace('#'.preg_quote($pair{1}).' +\- #', $pair{1}.' ', $PatternFilename); - } + // remove empty parenthesized pairs (probably where no track numbers, remix version, etc) + $PatternFilename = preg_replace('#'.preg_quote($pair).'#', '', $PatternFilename); - // get rid of leading & trailing spaces if end items (artist or title for example) are missing - $PatternFilename = trim($PatternFilename, ' -'); + // "[01] - Title With No Artist.mp3" ==> "[01] Title With No Artist.mp3" + $PatternFilename = preg_replace('#'.preg_quote($pair{1}).' +\- #', $pair{1}.' ', $PatternFilename); - if (!$PatternFilename) { - // no tags to create a filename from -- skip this file - continue; - } - $PatternFilename .= '.'.$row['fileformat']; + } - $ActualFilename = basename($row['filename']); - if ($ActualFilename != $PatternFilename) { - $NotMatchedReasons = ''; - if (strtolower($ActualFilename) === strtolower($PatternFilename)) { - $NotMatchedReasons .= 'Aa '; - } elseif (RemoveAccents($ActualFilename) === RemoveAccents($PatternFilename)) { - $NotMatchedReasons .= 'ée '; - } + // get rid of leading & trailing spaces if end items (artist or title for example) are missing + $PatternFilename = trim($PatternFilename, ' -'); + + if (!$PatternFilename) { + // no tags to create a filename from -- skip this file + continue; + } + $PatternFilename .= '.'.$row['fileformat']; + + $ActualFilename = basename($row['filename']); + if ($ActualFilename != $PatternFilename) { + + $NotMatchedReasons = ''; + if (strtolower($ActualFilename) === strtolower($PatternFilename)) { + $NotMatchedReasons .= 'Aa '; + } elseif (RemoveAccents($ActualFilename) === RemoveAccents($PatternFilename)) { + $NotMatchedReasons .= 'ée '; + } - $actualExt = '.'.fileextension($ActualFilename); - $patternExt = '.'.fileextension($PatternFilename); - $ActualFilenameNoExt = (($actualExt != '.') ? substr($ActualFilename, 0, 0 - strlen($actualExt)) : $ActualFilename); - $PatternFilenameNoExt = (($patternExt != '.') ? substr($PatternFilename, 0, 0 - strlen($patternExt)) : $PatternFilename); + $actualExt = '.'.fileextension($ActualFilename); + $patternExt = '.'.fileextension($PatternFilename); + $ActualFilenameNoExt = (($actualExt != '.') ? substr($ActualFilename, 0, 0 - strlen($actualExt)) : $ActualFilename); + $PatternFilenameNoExt = (($patternExt != '.') ? substr($PatternFilename, 0, 0 - strlen($patternExt)) : $PatternFilename); - if (strpos($PatternFilenameNoExt, $ActualFilenameNoExt) !== false) { - $DifferenceBoldedName = str_replace($ActualFilenameNoExt, ''.$ActualFilenameNoExt.'', $PatternFilenameNoExt); - } else { - $ShortestNameLength = min(strlen($ActualFilenameNoExt), strlen($PatternFilenameNoExt)); - for ($DifferenceOffset = 0; $DifferenceOffset < $ShortestNameLength; $DifferenceOffset++) { - if ($ActualFilenameNoExt{$DifferenceOffset} !== $PatternFilenameNoExt{$DifferenceOffset}) { - break; - } - } - $DifferenceBoldedName = ''.substr($PatternFilenameNoExt, 0, $DifferenceOffset).''.substr($PatternFilenameNoExt, $DifferenceOffset); - } - $DifferenceBoldedName .= (($actualExt == $patternExt) ? ''.$patternExt.'' : $patternExt); + if (strpos($PatternFilenameNoExt, $ActualFilenameNoExt) !== false) { + $DifferenceBoldedName = str_replace($ActualFilenameNoExt, ''.$ActualFilenameNoExt.'', $PatternFilenameNoExt); + } else { + $ShortestNameLength = min(strlen($ActualFilenameNoExt), strlen($PatternFilenameNoExt)); + for ($DifferenceOffset = 0; $DifferenceOffset < $ShortestNameLength; $DifferenceOffset++) { + if ($ActualFilenameNoExt{$DifferenceOffset} !== $PatternFilenameNoExt{$DifferenceOffset}) { + break; + } + } + $DifferenceBoldedName = ''.substr($PatternFilenameNoExt, 0, $DifferenceOffset).''.substr($PatternFilenameNoExt, $DifferenceOffset); + } + $DifferenceBoldedName .= (($actualExt == $patternExt) ? ''.$patternExt.'' : $patternExt); - echo ''; - echo ''; - echo ''; - echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + if (!empty($_REQUEST['autofix'])) { + + $results = ''; + if (RenameFileFromTo($row['filename'], dirname($row['filename']).'/'.$PatternFilename, $results)) { + echo ''; + + + } else { + + echo ''; + + } + echo ''; + + $nonmatchingfilenames++; + } + } + echo '
viewWhyActual filename
(click to play/edit file)
Correct filename (based on tags)'.(empty($_REQUEST['autofix']) ? '
(click to rename file to this)' : '').'
view '.$NotMatchedReasons.''.htmlentities($ActualFilename).'
view '.$NotMatchedReasons.''.htmlentities($ActualFilename).''; + } else { + echo ''; + } + echo ''.$DifferenceBoldedName.''; + echo ''.$DifferenceBoldedName.'

'; + echo 'Found '.number_format($nonmatchingfilenames).' files that do not match naming pattern
'; - if (!empty($_REQUEST['autofix'])) { - $results = ''; - if (RenameFileFromTo($row['filename'], dirname($row['filename']).'/'.$PatternFilename, $results)) { - echo ''; - } else { - echo ''; - } - echo ''.$DifferenceBoldedName.''; - } else { - echo ''; - echo ''.$DifferenceBoldedName.''; - } - echo ''; - $nonmatchingfilenames++; - } - } - echo '
'; - echo 'Found '.number_format($nonmatchingfilenames).' files that do not match naming pattern
'; } elseif (!empty($_REQUEST['encoderoptionsdistribution'])) { - if (isset($_REQUEST['showtagfiles'])) { - $SQLquery = 'SELECT `filename`, `encoder_options` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`encoder_options` LIKE "'.mysql_real_escape_string($_REQUEST['showtagfiles']).'")'; - $SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - echo 'Show all Encoder Options
'; - echo 'Files with Encoder Options '.$_REQUEST['showtagfiles'].':
'; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
'.htmlentities($row['filename']).''.$row['encoder_options'].'
'; - } - } elseif (!isset($_REQUEST['m3u'])) { - $SQLquery = 'SELECT `encoder_options`, COUNT(*) AS `num` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' GROUP BY `encoder_options`'; - $SQLquery .= ' ORDER BY (`encoder_options` LIKE "LAME%") DESC, (`encoder_options` LIKE "CBR%") DESC, `num` DESC, `encoder_options` ASC'; - $result = mysql_query_safe($SQLquery); - echo 'Files with Encoder Options:
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
Encoder OptionsCountM3U
'.$row['encoder_options'].''.number_format($row['num']).'m3u

'; - } + if (isset($_REQUEST['showtagfiles'])) { + $SQLquery = 'SELECT `filename`, `encoder_options` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`encoder_options` LIKE "'.mysql_real_escape_string($_REQUEST['showtagfiles']).'")'; + $SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + echo 'Show all Encoder Options
'; + echo 'Files with Encoder Options '.$_REQUEST['showtagfiles'].':
'; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
'.htmlentities($row['filename']).''.$row['encoder_options'].'
'; + + } + + } elseif (!isset($_REQUEST['m3u'])) { + + $SQLquery = 'SELECT `encoder_options`, COUNT(*) AS `num` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' GROUP BY `encoder_options`'; + $SQLquery .= ' ORDER BY (`encoder_options` LIKE "LAME%") DESC, (`encoder_options` LIKE "CBR%") DESC, `num` DESC, `encoder_options` ASC'; + $result = mysql_query_safe($SQLquery); + echo 'Files with Encoder Options:
'; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
Encoder OptionsCountM3U
'.$row['encoder_options'].''.number_format($row['num']).'m3u

'; + + } + } elseif (!empty($_REQUEST['tagtypes'])) { - if (!isset($_REQUEST['m3u'])) { - $SQLquery = 'SELECT `tags`, COUNT(*) AS `num` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' GROUP BY `tags`'; - $SQLquery .= ' ORDER BY `num` DESC'; - $result = mysql_query_safe($SQLquery); - echo 'Files with tags:
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
TagsCountM3U
'.$row['tags'].''.number_format($row['num']).'m3u

'; - } - if (isset($_REQUEST['showtagfiles'])) { - $SQLquery = 'SELECT `filename`, `tags` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`tags` LIKE "'.mysql_real_escape_string($_REQUEST['showtagfiles']).'")'; - $SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); + if (!isset($_REQUEST['m3u'])) { + $SQLquery = 'SELECT `tags`, COUNT(*) AS `num` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' GROUP BY `tags`'; + $SQLquery .= ' ORDER BY `num` DESC'; + $result = mysql_query_safe($SQLquery); + echo 'Files with tags:
'; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
TagsCountM3U
'.$row['tags'].''.number_format($row['num']).'m3u

'; + } + + if (isset($_REQUEST['showtagfiles'])) { + $SQLquery = 'SELECT `filename`, `tags` FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`tags` LIKE "'.mysql_real_escape_string($_REQUEST['showtagfiles']).'")'; + $SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
'.htmlentities($row['filename']).''.$row['tags'].'
'; + + } + } + - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
'.htmlentities($row['filename']).''.$row['tags'].'
'; - } - } } elseif (!empty($_REQUEST['md5datadupes'])) { - $OtherFormats = ''; - $AVFormats = ''; - $SQLquery = 'SELECT `md5_data`, `filename`, COUNT(*) AS `num`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`md5_data` <> "")'; - $SQLquery .= ' GROUP BY `md5_data`'; - $SQLquery .= ' ORDER BY `num` DESC'; - $result = mysql_query_safe($SQLquery); - while (($row = mysql_fetch_array($result)) && ($row['num'] > 1)) { - set_time_limit(30); + $OtherFormats = ''; + $AVFormats = ''; - $filenames = []; - $tags = []; - $md5_data = []; - $SQLquery = 'SELECT `fileformat`, `filename`, `tags`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`md5_data` = "'.mysql_real_escape_string($row['md5_data']).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result2 = mysql_query_safe($SQLquery); - while ($row2 = mysql_fetch_array($result2)) { - $thisfileformat = $row2['fileformat']; - $filenames[] = $row2['filename']; - $tags[] = $row2['tags']; - $md5_data[] = $row['md5_data']; - } + $SQLquery = 'SELECT `md5_data`, `filename`, COUNT(*) AS `num`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`md5_data` <> "")'; + $SQLquery .= ' GROUP BY `md5_data`'; + $SQLquery .= ' ORDER BY `num` DESC'; + $result = mysql_query_safe($SQLquery); + while (($row = mysql_fetch_array($result)) && ($row['num'] > 1)) { + set_time_limit(30); + + $filenames = array(); + $tags = array(); + $md5_data = array(); + $SQLquery = 'SELECT `fileformat`, `filename`, `tags`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`md5_data` = "'.mysql_real_escape_string($row['md5_data']).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result2 = mysql_query_safe($SQLquery); + while ($row2 = mysql_fetch_array($result2)) { + $thisfileformat = $row2['fileformat']; + $filenames[] = $row2['filename']; + $tags[] = $row2['tags']; + $md5_data[] = $row['md5_data']; + } + + $thisline = ''; + $thisline .= ''.implode('
', $md5_data).''; + $thisline .= ''.implode('
', $tags).''; + $thisline .= ''.implode('
', $filenames).''; + $thisline .= ''; + + if (in_array($thisfileformat, $IgnoreNoTagFormats)) { + $OtherFormats .= $thisline; + } else { + $AVFormats .= $thisline; + } + } + echo 'Duplicated MD5_DATA (Audio/Video files):'; + echo $AVFormats.'

'; + echo 'Duplicated MD5_DATA (Other files):'; + echo $OtherFormats.'

'; - $thisline = ''; - $thisline .= ''.implode('
', $md5_data).''; - $thisline .= ''.implode('
', $tags).''; - $thisline .= ''.implode('
', $filenames).''; - $thisline .= ''; - if (in_array($thisfileformat, $IgnoreNoTagFormats)) { - $OtherFormats .= $thisline; - } else { - $AVFormats .= $thisline; - } - } - echo 'Duplicated MD5_DATA (Audio/Video files):'; - echo $AVFormats.'

'; - echo 'Duplicated MD5_DATA (Other files):'; - echo $OtherFormats.'

'; } elseif (!empty($_REQUEST['artisttitledupes'])) { - if (isset($_REQUEST['m3uartist']) && isset($_REQUEST['m3utitle'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`artist` = "'.mysql_real_escape_string($_REQUEST['m3uartist']).'")'; - $SQLquery .= ' AND (`title` = "'.mysql_real_escape_string($_REQUEST['m3utitle']).'")'; - $SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC'; - $result = mysql_query_safe($SQLquery); - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } - $SQLquery = 'SELECT `artist`, `title`, `filename`, COUNT(*) AS `num`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`artist` <> "")'; - $SQLquery .= ' AND (`title` <> "")'; - $SQLquery .= ' GROUP BY `artist`, `title`'.(!empty($_REQUEST['samemix']) ? ', `remix`' : ''); - $SQLquery .= ' ORDER BY `num` DESC, `artist` ASC, `title` ASC, `playtime_seconds` ASC, `remix` ASC'; - $result = mysql_query_safe($SQLquery); - $uniquetitles = 0; - $uniquefiles = 0; + if (isset($_REQUEST['m3uartist']) && isset($_REQUEST['m3utitle'])) { - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while (($row = mysql_fetch_array($result)) && ($row['num'] > 1)) { - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`artist` = "'.mysql_real_escape_string($row['artist']).'")'; - $SQLquery .= ' AND (`title` = "'.mysql_real_escape_string($row['title']).'")'; - if (!empty($_REQUEST['samemix'])) { - $SQLquery .= ' AND (`remix` = "'.mysql_real_escape_string($row['remix']).'")'; - } - $SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC'; - $result2 = mysql_query_safe($SQLquery); - while ($row2 = mysql_fetch_array($result2)) { - echo WindowsShareSlashTranslate($row2['filename'])."\n"; - } - } - exit; - } else { - echo 'Duplicated aritst + title: (Identical Mix/Version only)
'; - echo '(.m3u version)
'; - echo ''; - echo ''; + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`artist` = "'.mysql_real_escape_string($_REQUEST['m3uartist']).'")'; + $SQLquery .= ' AND (`title` = "'.mysql_real_escape_string($_REQUEST['m3utitle']).'")'; + $SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC'; + $result = mysql_query_safe($SQLquery); + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; - while (($row = mysql_fetch_array($result)) && ($row['num'] > 1)) { - $uniquetitles++; - set_time_limit(30); + } - $filenames = []; - $artists = []; - $titles = []; - $remixes = []; - $bitrates = []; - $playtimes = []; - $SQLquery = 'SELECT `filename`, `artist`, `title`, `remix`, `audio_bitrate`, `vbr_method`, `playtime_seconds`, `encoder_options`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`artist` = "'.mysql_real_escape_string($row['artist']).'")'; - $SQLquery .= ' AND (`title` = "'.mysql_real_escape_string($row['title']).'")'; - $SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC'; - $result2 = mysql_query_safe($SQLquery); - while ($row2 = mysql_fetch_array($result2)) { - $uniquefiles++; - $filenames[] = $row2['filename']; - $artists[] = $row2['artist']; - $titles[] = $row2['title']; - $remixes[] = $row2['remix']; - if ($row2['vbr_method']) { - $bitrates[] = ''.BitrateText($row2['audio_bitrate'] / 1000).''; - } else { - $bitrates[] = BitrateText($row2['audio_bitrate'] / 1000); - } - $playtimes[] = getid3_lib::PlaytimeString($row2['playtime_seconds']); - } + $SQLquery = 'SELECT `artist`, `title`, `filename`, COUNT(*) AS `num`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`artist` <> "")'; + $SQLquery .= ' AND (`title` <> "")'; + $SQLquery .= ' GROUP BY `artist`, `title`'.(!empty($_REQUEST['samemix']) ? ', `remix`' : ''); + $SQLquery .= ' ORDER BY `num` DESC, `artist` ASC, `title` ASC, `playtime_seconds` ASC, `remix` ASC'; + $result = mysql_query_safe($SQLquery); + $uniquetitles = 0; + $uniquefiles = 0; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; + if (!empty($_REQUEST['m3u'])) { - echo ''; + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while (($row = mysql_fetch_array($result)) && ($row['num'] > 1)) { + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`artist` = "'.mysql_real_escape_string($row['artist']).'")'; + $SQLquery .= ' AND (`title` = "'.mysql_real_escape_string($row['title']).'")'; + if (!empty($_REQUEST['samemix'])) { + $SQLquery .= ' AND (`remix` = "'.mysql_real_escape_string($row['remix']).'")'; + } + $SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC'; + $result2 = mysql_query_safe($SQLquery); + while ($row2 = mysql_fetch_array($result2)) { + echo WindowsShareSlashTranslate($row2['filename'])."\n"; + } + } + exit; + + } else { + + echo 'Duplicated aritst + title: (Identical Mix/Version only)
'; + echo '(.m3u version)
'; + echo '
 ArtistTitleVersion  Filename
'; - foreach ($filenames as $file) { - echo 'delete
'; - } - echo '
'; - foreach ($filenames as $file) { - echo 'play
'; - } - echo '
play all'.implode('
', $artists).'
'.implode('
', $titles).'
'.implode('
', $remixes).'
'.implode('
', $bitrates).'
'.implode('
', $playtimes).'
'; - foreach ($filenames as $file) { - echo ''; - } - echo '
'.dirname($file).'/'.basename($file).'
'; + echo ''; + + while (($row = mysql_fetch_array($result)) && ($row['num'] > 1)) { + $uniquetitles++; + set_time_limit(30); + + $filenames = array(); + $artists = array(); + $titles = array(); + $remixes = array(); + $bitrates = array(); + $playtimes = array(); + $SQLquery = 'SELECT `filename`, `artist`, `title`, `remix`, `audio_bitrate`, `vbr_method`, `playtime_seconds`, `encoder_options`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`artist` = "'.mysql_real_escape_string($row['artist']).'")'; + $SQLquery .= ' AND (`title` = "'.mysql_real_escape_string($row['title']).'")'; + $SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC'; + $result2 = mysql_query_safe($SQLquery); + while ($row2 = mysql_fetch_array($result2)) { + $uniquefiles++; + $filenames[] = $row2['filename']; + $artists[] = $row2['artist']; + $titles[] = $row2['title']; + $remixes[] = $row2['remix']; + if ($row2['vbr_method']) { + $bitrates[] = ''.BitrateText($row2['audio_bitrate'] / 1000).''; + } else { + $bitrates[] = BitrateText($row2['audio_bitrate'] / 1000); + } + $playtimes[] = getid3_lib::PlaytimeString($row2['playtime_seconds']); + } + + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + + echo ''; + + echo ''; + } + + } + echo '
 ArtistTitleVersion  Filename
'; + foreach ($filenames as $file) { + echo 'delete
'; + } + echo '
'; + foreach ($filenames as $file) { + echo 'play
'; + } + echo '
play all'.implode('
', $artists).'
'.implode('
', $titles).'
'.implode('
', $remixes).'
'.implode('
', $bitrates).'
'.implode('
', $playtimes).'
'; + foreach ($filenames as $file) { + echo ''; + } + echo '
'.dirname($file).'/'.basename($file).'
'; + echo number_format($uniquefiles).' files with '.number_format($uniquetitles).' unique aritst + title
'; + echo '
'; - echo ''; - } - } - echo ''; - echo number_format($uniquefiles).' files with '.number_format($uniquetitles).' unique aritst + title
'; - echo '
'; } elseif (!empty($_REQUEST['filetypelist'])) { - list($fileformat, $audioformat) = explode('|', $_REQUEST['filetypelist']); - $SQLquery = 'SELECT `filename`, `fileformat`, `audio_dataformat`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` = "'.mysql_real_escape_string($fileformat).'")'; - $SQLquery .= ' AND (`audio_dataformat` = "'.mysql_real_escape_string($audioformat).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - echo 'Files of format '.$fileformat.'.'.$audioformat.':'; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
fileaudiofilename
'.$row['fileformat'].''.$row['audio_dataformat'].''.htmlentities($row['filename']).'

'; + + list($fileformat, $audioformat) = explode('|', $_REQUEST['filetypelist']); + $SQLquery = 'SELECT `filename`, `fileformat`, `audio_dataformat`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` = "'.mysql_real_escape_string($fileformat).'")'; + $SQLquery .= ' AND (`audio_dataformat` = "'.mysql_real_escape_string($audioformat).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + echo 'Files of format '.$fileformat.'.'.$audioformat.':'; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
fileaudiofilename
'.$row['fileformat'].''.$row['audio_dataformat'].''.htmlentities($row['filename']).'

'; + } elseif (!empty($_REQUEST['trackinalbum'])) { - $SQLquery = 'SELECT `filename`, `album`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`album` LIKE "% [%")'; - $SQLquery .= ' ORDER BY `album` ASC, `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } elseif (!empty($_REQUEST['autofix'])) { - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - $ThisFileInfo = $getID3->analyze($filename); - getid3_lib::CopyTagsToComments($ThisFileInfo); + $SQLquery = 'SELECT `filename`, `album`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`album` LIKE "% [%")'; + $SQLquery .= ' ORDER BY `album` ASC, `filename` ASC'; + $result = mysql_query_safe($SQLquery); + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } elseif (!empty($_REQUEST['autofix'])) { + + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); + + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + $ThisFileInfo = $getID3->analyze($filename); + getid3_lib::CopyTagsToComments($ThisFileInfo); + + if (!empty($ThisFileInfo['tags'])) { + + $Album = trim(str_replace(strstr($ThisFileInfo['comments']['album'][0], ' ['), '', $ThisFileInfo['comments']['album'][0])); + $Track = (string) intval(str_replace(' [', '', str_replace(']', '', strstr($ThisFileInfo['comments']['album'][0], ' [')))); + if ($Track == '0') { + $Track = ''; + } + if ($Album && $Track) { + echo '
'.htmlentities($row['filename']).'
'; + echo ''.htmlentities($Album).' (track #'.$Track.')
'; + echo 'ID3v2: '.(RemoveID3v2($row['filename'], false) ? 'removed' : 'REMOVAL FAILED!').', '; + $WriteID3v1_title = (isset($ThisFileInfo['comments']['title'][0]) ? $ThisFileInfo['comments']['title'][0] : ''); + $WriteID3v1_artist = (isset($ThisFileInfo['comments']['artist'][0]) ? $ThisFileInfo['comments']['artist'][0] : ''); + $WriteID3v1_year = (isset($ThisFileInfo['comments']['year'][0]) ? $ThisFileInfo['comments']['year'][0] : ''); + $WriteID3v1_comment = (isset($ThisFileInfo['comments']['comment'][0]) ? $ThisFileInfo['comments']['comment'][0] : ''); + $WriteID3v1_genreid = (isset($ThisFileInfo['comments']['genreid'][0]) ? $ThisFileInfo['comments']['genreid'][0] : ''); + echo 'ID3v1: '.(WriteID3v1($row['filename'], $WriteID3v1_title, $WriteID3v1_artist, $Album, $WriteID3v1_year, $WriteID3v1_comment, $WriteID3v1_genreid, $Track, false) ? 'updated' : 'UPDATE FAILED').'
'; + } else { + echo ' . '; + } + + } else { + + echo '
FAILED
'.htmlentities($row['filename']).'
'; + + } + flush(); + } + + } else { + + echo ''.number_format(mysql_num_rows($result)).' files with [??]-format track numbers in album field:
'; + if (mysql_num_rows($result) > 0) { + echo '(.m3u version)
'; + echo 'Try to auto-fix
'; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
'.$row['album'].''.htmlentities($row['filename']).'
'; + } + echo '
'; + + } - if (!empty($ThisFileInfo['tags'])) { - $Album = trim(str_replace(strstr($ThisFileInfo['comments']['album'][0], ' ['), '', $ThisFileInfo['comments']['album'][0])); - $Track = (string) intval(str_replace(' [', '', str_replace(']', '', strstr($ThisFileInfo['comments']['album'][0], ' [')))); - if ($Track == '0') { - $Track = ''; - } - if ($Album && $Track) { - echo '
'.htmlentities($row['filename']).'
'; - echo ''.htmlentities($Album).' (track #'.$Track.')
'; - echo 'ID3v2: '.(RemoveID3v2($row['filename'], false) ? 'removed' : 'REMOVAL FAILED!').', '; - $WriteID3v1_title = (isset($ThisFileInfo['comments']['title'][0]) ? $ThisFileInfo['comments']['title'][0] : ''); - $WriteID3v1_artist = (isset($ThisFileInfo['comments']['artist'][0]) ? $ThisFileInfo['comments']['artist'][0] : ''); - $WriteID3v1_year = (isset($ThisFileInfo['comments']['year'][0]) ? $ThisFileInfo['comments']['year'][0] : ''); - $WriteID3v1_comment = (isset($ThisFileInfo['comments']['comment'][0]) ? $ThisFileInfo['comments']['comment'][0] : ''); - $WriteID3v1_genreid = (isset($ThisFileInfo['comments']['genreid'][0]) ? $ThisFileInfo['comments']['genreid'][0] : ''); - echo 'ID3v1: '.(WriteID3v1($row['filename'], $WriteID3v1_title, $WriteID3v1_artist, $Album, $WriteID3v1_year, $WriteID3v1_comment, $WriteID3v1_genreid, $Track, false) ? 'updated' : 'UPDATE FAILED').'
'; - } else { - echo ' . '; - } - } else { - echo '
FAILED
'.htmlentities($row['filename']).'
'; - } - flush(); - } - } else { - echo ''.number_format(mysql_num_rows($result)).' files with [??]-format track numbers in album field:
'; - if (mysql_num_rows($result) > 0) { - echo '(.m3u version)
'; - echo 'Try to auto-fix
'; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
'.$row['album'].''.htmlentities($row['filename']).'
'; - } - echo '
'; - } } elseif (!empty($_REQUEST['fileextensions'])) { - $SQLquery = 'SELECT `filename`, `fileformat`, `audio_dataformat`, `video_dataformat`, `tags`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - $invalidextensionfiles = 0; - $invalidextensionline = ''; - $invalidextensionline .= ''; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - $acceptableextensions = AcceptableExtensions($row['fileformat'], $row['audio_dataformat'], $row['video_dataformat']); - $actualextension = strtolower(fileextension($row['filename'])); - if ($acceptableextensions && !in_array($actualextension, $acceptableextensions)) { - $invalidextensionfiles++; + $SQLquery = 'SELECT `filename`, `fileformat`, `audio_dataformat`, `video_dataformat`, `tags`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + $invalidextensionfiles = 0; + $invalidextensionline = '
fileaudiovideotagsactualcorrectfilename
'; + $invalidextensionline .= ''; + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + + $acceptableextensions = AcceptableExtensions($row['fileformat'], $row['audio_dataformat'], $row['video_dataformat']); + $actualextension = strtolower(fileextension($row['filename'])); + if ($acceptableextensions && !in_array($actualextension, $acceptableextensions)) { + $invalidextensionfiles++; + + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + $invalidextensionline .= ''; + } + } + $invalidextensionline .= '
fileaudiovideotagsactualcorrectfilename
'.$row['fileformat'].''.$row['audio_dataformat'].''.$row['video_dataformat'].''.$row['tags'].''.$actualextension.''.implode('; ', $acceptableextensions).''.htmlentities($row['filename']).'

'; + echo number_format($invalidextensionfiles).' files with incorrect filename extension:
'; + echo $invalidextensionline; - $invalidextensionline .= ''; - $invalidextensionline .= ''.$row['fileformat'].''; - $invalidextensionline .= ''.$row['audio_dataformat'].''; - $invalidextensionline .= ''.$row['video_dataformat'].''; - $invalidextensionline .= ''.$row['tags'].''; - $invalidextensionline .= ''.$actualextension.''; - $invalidextensionline .= ''.implode('; ', $acceptableextensions).''; - $invalidextensionline .= ''.htmlentities($row['filename']).''; - $invalidextensionline .= ''; - } - } - $invalidextensionline .= '
'; - echo number_format($invalidextensionfiles).' files with incorrect filename extension:
'; - echo $invalidextensionline; } elseif (isset($_REQUEST['genredistribution'])) { - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (BINARY `genre` = "'.$_REQUEST['genredistribution'].'")'; - $SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - if ($_REQUEST['genredistribution'] == '%') { - $SQLquery = 'SELECT COUNT(*) AS `num`, `genre`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; - $SQLquery .= ' GROUP BY `genre`'; - $SQLquery .= ' ORDER BY `num` DESC'; - $result = mysql_query_safe($SQLquery); - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - $GenreID = getid3_id3v1::LookupGenreID($row['genre']); - if (is_numeric($GenreID)) { - echo ''; - } else { - echo ''; - } - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
CountGenrem3u
'.number_format($row['num']).''.str_replace("\t", '
', $row['genre']).'
.m3u

'; - } else { - $SQLquery = 'SELECT `filename`, `genre`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`genre` LIKE "'.mysql_real_escape_string($_REQUEST['genredistribution']).'")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - echo 'All Genres
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
Genrem3uFilename
'.str_replace("\t", '
', $row['genre']).'
m3u'.htmlentities($row['filename']).'

'; - } - } + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (BINARY `genre` = "'.$_REQUEST['genredistribution'].'")'; + $SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + if ($_REQUEST['genredistribution'] == '%') { + + $SQLquery = 'SELECT COUNT(*) AS `num`, `genre`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")'; + $SQLquery .= ' GROUP BY `genre`'; + $SQLquery .= ' ORDER BY `num` DESC'; + $result = mysql_query_safe($SQLquery); + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true); + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + $GenreID = getid3_id3v1::LookupGenreID($row['genre']); + if (is_numeric($GenreID)) { + echo ''; + } else { + echo ''; + } + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
CountGenrem3u
'.number_format($row['num']).''.str_replace("\t", '
', $row['genre']).'
.m3u

'; + + } else { + + $SQLquery = 'SELECT `filename`, `genre`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`genre` LIKE "'.mysql_real_escape_string($_REQUEST['genredistribution']).'")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + echo 'All Genres
'; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
Genrem3uFilename
'.str_replace("\t", '
', $row['genre']).'
m3u'.htmlentities($row['filename']).'

'; + + } + + + } + } elseif (!empty($_REQUEST['formatdistribution'])) { - $SQLquery = 'SELECT `fileformat`, `audio_dataformat`, COUNT(*) AS `num`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' GROUP BY `fileformat`, `audio_dataformat`'; - $SQLquery .= ' ORDER BY `num` DESC'; - $result = mysql_query_safe($SQLquery); - echo 'File format distribution:'; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - } - echo '
NumberFormat
'.number_format($row['num']).''.($row['fileformat'] ? $row['fileformat'] : 'unknown').(($row['audio_dataformat'] && ($row['audio_dataformat'] != $row['fileformat'])) ? '.'.$row['audio_dataformat'] : '').'

'; + + $SQLquery = 'SELECT `fileformat`, `audio_dataformat`, COUNT(*) AS `num`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' GROUP BY `fileformat`, `audio_dataformat`'; + $SQLquery .= ' ORDER BY `num` DESC'; + $result = mysql_query_safe($SQLquery); + echo 'File format distribution:'; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
NumberFormat
'.number_format($row['num']).''.($row['fileformat'] ? $row['fileformat'] : 'unknown').(($row['audio_dataformat'] && ($row['audio_dataformat'] != $row['fileformat'])) ? '.'.$row['audio_dataformat'] : '').'

'; + } elseif (!empty($_REQUEST['errorswarnings'])) { - $SQLquery = 'SELECT `filename`, `error`, `warning`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`error` <> "")'; - $SQLquery .= ' OR (`warning` <> "")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - if (!empty($_REQUEST['m3u'])) { - header('Content-type: audio/x-mpegurl'); - echo '#EXTM3U'."\n"; - while ($row = mysql_fetch_array($result)) { - echo WindowsShareSlashTranslate($row['filename'])."\n"; - } - exit; - } else { - echo number_format(mysql_num_rows($result)).' files with errors or warnings:
'; - echo '(.m3u version)
'; - echo ''; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - } - echo '
FilenameErrorWarning
'.htmlentities($row['filename']).''.(!empty($row['error']) ? '
  • '.str_replace("\t", '
  • ', htmlentities($row['error'])).'
  • ' : ' ').'
    '.(!empty($row['warning']) ? '
  • '.str_replace("\t", '
  • ', htmlentities($row['warning'])).'
  • ' : ' ').'

    '; + $SQLquery = 'SELECT `filename`, `error`, `warning`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`error` <> "")'; + $SQLquery .= ' OR (`warning` <> "")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + + if (!empty($_REQUEST['m3u'])) { + + header('Content-type: audio/x-mpegurl'); + echo '#EXTM3U'."\n"; + while ($row = mysql_fetch_array($result)) { + echo WindowsShareSlashTranslate($row['filename'])."\n"; + } + exit; + + } else { + + echo number_format(mysql_num_rows($result)).' files with errors or warnings:
    '; + echo '(.m3u version)
    '; + echo ''; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + } + echo '
    FilenameErrorWarning
    '.htmlentities($row['filename']).''.(!empty($row['error']) ? '
  • '.str_replace("\t", '
  • ', htmlentities($row['error'])).'
  • ' : ' ').'
    '.(!empty($row['warning']) ? '
  • '.str_replace("\t", '
  • ', htmlentities($row['warning'])).'
  • ' : ' ').'

    '; + } elseif (!empty($_REQUEST['fixid3v1padding'])) { - getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.id3v1.php', __FILE__, true); - $id3v1_writer = new getid3_write_id3v1; - $SQLquery = 'SELECT `filename`, `error`, `warning`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` = "mp3")'; - $SQLquery .= ' AND (`warning` <> "")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - $totaltofix = mysql_num_rows($result); - $rowcounter = 0; - while ($row = mysql_fetch_array($result)) { - set_time_limit(30); - if (strpos($row['warning'], 'Some ID3v1 fields do not use NULL characters for padding') !== false) { - set_time_limit(30); - $id3v1_writer->filename = $row['filename']; - echo ($id3v1_writer->FixID3v1Padding() ? 'fixed - ' : 'error - '); - } else { - echo 'No error? - '; - } - echo '['.++$rowcounter.' / '.$totaltofix.'] '; - echo htmlentities($row['filename']).'
    '; - flush(); - } + getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.id3v1.php', __FILE__, true); + $id3v1_writer = new getid3_write_id3v1; + + $SQLquery = 'SELECT `filename`, `error`, `warning`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` = "mp3")'; + $SQLquery .= ' AND (`warning` <> "")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + $totaltofix = mysql_num_rows($result); + $rowcounter = 0; + while ($row = mysql_fetch_array($result)) { + set_time_limit(30); + if (strpos($row['warning'], 'Some ID3v1 fields do not use NULL characters for padding') !== false) { + set_time_limit(30); + $id3v1_writer->filename = $row['filename']; + echo ($id3v1_writer->FixID3v1Padding() ? 'fixed - ' : 'error - '); + } else { + echo 'No error? - '; + } + echo '['.++$rowcounter.' / '.$totaltofix.'] '; + echo htmlentities($row['filename']).'
    '; + flush(); + } + } elseif (!empty($_REQUEST['vbrmethod'])) { - if ($_REQUEST['vbrmethod'] == '1') { - $SQLquery = 'SELECT COUNT(*) AS `num`, `vbr_method`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' GROUP BY `vbr_method`'; - $SQLquery .= ' ORDER BY `vbr_method`'; - $result = mysql_query_safe($SQLquery); - echo 'VBR methods:'; - echo ''; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - if ($row['vbr_method']) { - echo ''; - } else { - echo ''; - } - echo ''; - } - echo '
    CountVBR Method
    '.htmlentities(number_format($row['num'])).''.htmlentities($row['vbr_method']).'CBR
    '; - } else { - $SQLquery = 'SELECT `filename`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`vbr_method` = "'.mysql_real_escape_string($_REQUEST['vbrmethod']).'")'; - $result = mysql_query_safe($SQLquery); - echo number_format(mysql_num_rows($result)).' files with VBR_method of "'.$_REQUEST['vbrmethod'].'":'; - while ($row = mysql_fetch_array($result)) { - echo ''; - echo ''; - } - echo '
    m3u'.htmlentities($row['filename']).'
    '; - } - echo '
    '; + + if ($_REQUEST['vbrmethod'] == '1') { + + $SQLquery = 'SELECT COUNT(*) AS `num`, `vbr_method`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' GROUP BY `vbr_method`'; + $SQLquery .= ' ORDER BY `vbr_method`'; + $result = mysql_query_safe($SQLquery); + echo 'VBR methods:'; + echo ''; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + if ($row['vbr_method']) { + echo ''; + } else { + echo ''; + } + echo ''; + } + echo '
    CountVBR Method
    '.htmlentities(number_format($row['num'])).''.htmlentities($row['vbr_method']).'CBR
    '; + + } else { + + $SQLquery = 'SELECT `filename`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`vbr_method` = "'.mysql_real_escape_string($_REQUEST['vbrmethod']).'")'; + $result = mysql_query_safe($SQLquery); + echo number_format(mysql_num_rows($result)).' files with VBR_method of "'.$_REQUEST['vbrmethod'].'":'; + while ($row = mysql_fetch_array($result)) { + echo ''; + echo ''; + } + echo '
    m3u'.htmlentities($row['filename']).'
    '; + + } + echo '
    '; + } elseif (!empty($_REQUEST['correctcase'])) { - $SQLquery = 'SELECT `filename`, `fileformat`'; - $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; - $SQLquery .= ' WHERE (`fileformat` <> "")'; - $SQLquery .= ' ORDER BY `filename` ASC'; - $result = mysql_query_safe($SQLquery); - echo 'Copy and paste the following into a DOS batch file. You may have to run this script more than once to catch all the changes (remember to scan for deleted/changed files and rescan directory between scans)
    '; - echo '
    ';
    -    $lastdir = '';
    -    while ($row = mysql_fetch_array($result)) {
    -        set_time_limit(30);
    -        $CleanedFilename = CleanUpFileName($row['filename']);
    -        if ($row['filename'] != $CleanedFilename) {
    -            if (strtolower($lastdir) != strtolower(str_replace('/', '\\', dirname($row['filename'])))) {
    -                $lastdir = str_replace('/', '\\', dirname($row['filename']));
    -                echo 'cd "'.$lastdir.'"'."\n";
    -            }
    -            echo 'ren "'.basename($row['filename']).'" "'.basename(CleanUpFileName($row['filename'])).'"'."\n";
    -        }
    -    }
    -    echo '
    '; - echo '
    '; + + $SQLquery = 'SELECT `filename`, `fileformat`'; + $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; + $SQLquery .= ' WHERE (`fileformat` <> "")'; + $SQLquery .= ' ORDER BY `filename` ASC'; + $result = mysql_query_safe($SQLquery); + echo 'Copy and paste the following into a DOS batch file. You may have to run this script more than once to catch all the changes (remember to scan for deleted/changed files and rescan directory between scans)
    '; + echo '
    ';
    +	$lastdir = '';
    +	while ($row = mysql_fetch_array($result)) {
    +		set_time_limit(30);
    +		$CleanedFilename = CleanUpFileName($row['filename']);
    +		if ($row['filename'] != $CleanedFilename) {
    +			if (strtolower($lastdir) != strtolower(str_replace('/', '\\', dirname($row['filename'])))) {
    +				$lastdir = str_replace('/', '\\', dirname($row['filename']));
    +				echo 'cd "'.$lastdir.'"'."\n";
    +			}
    +			echo 'ren "'.basename($row['filename']).'" "'.basename(CleanUpFileName($row['filename'])).'"'."\n";
    +		}
    +	}
    +	echo '
    '; + echo '
    '; + } -function CleanUpFileName($filename) -{ - $DirectoryName = dirname($filename); - $FileExtension = fileextension(basename($filename)); - $BaseFilename = basename($filename, '.'.$FileExtension); +function CleanUpFileName($filename) { + $DirectoryName = dirname($filename); + $FileExtension = fileextension(basename($filename)); + $BaseFilename = basename($filename, '.'.$FileExtension); - $BaseFilename = strtolower($BaseFilename); - $BaseFilename = str_replace('_', ' ', $BaseFilename); - //$BaseFilename = str_replace('-', ' - ', $BaseFilename); - $BaseFilename = str_replace('(', ' (', $BaseFilename); - $BaseFilename = str_replace('( ', '(', $BaseFilename); - $BaseFilename = str_replace(')', ') ', $BaseFilename); - $BaseFilename = str_replace(' )', ')', $BaseFilename); - $BaseFilename = str_replace(' \'\'', ' “', $BaseFilename); - $BaseFilename = str_replace('\'\' ', '” ', $BaseFilename); - $BaseFilename = str_replace(' vs ', ' vs. ', $BaseFilename); - while (strstr($BaseFilename, ' ') !== false) { - $BaseFilename = str_replace(' ', ' ', $BaseFilename); - } - $BaseFilename = trim($BaseFilename); + $BaseFilename = strtolower($BaseFilename); + $BaseFilename = str_replace('_', ' ', $BaseFilename); + //$BaseFilename = str_replace('-', ' - ', $BaseFilename); + $BaseFilename = str_replace('(', ' (', $BaseFilename); + $BaseFilename = str_replace('( ', '(', $BaseFilename); + $BaseFilename = str_replace(')', ') ', $BaseFilename); + $BaseFilename = str_replace(' )', ')', $BaseFilename); + $BaseFilename = str_replace(' \'\'', ' “', $BaseFilename); + $BaseFilename = str_replace('\'\' ', '” ', $BaseFilename); + $BaseFilename = str_replace(' vs ', ' vs. ', $BaseFilename); + while (strstr($BaseFilename, ' ') !== false) { + $BaseFilename = str_replace(' ', ' ', $BaseFilename); + } + $BaseFilename = trim($BaseFilename); - return $DirectoryName.'/'.BetterUCwords($BaseFilename).'.'.strtolower($FileExtension); + return $DirectoryName.'/'.BetterUCwords($BaseFilename).'.'.strtolower($FileExtension); } -function BetterUCwords($string) -{ - $stringlength = strlen($string); +function BetterUCwords($string) { + $stringlength = strlen($string); - $string{0} = strtoupper($string{0}); - for ($i = 1; $i < $stringlength; $i++) { - if (($string{$i - 1} == '\'') && ($i > 1) && (($string{$i - 2} == 'O') || ($string{$i - 2} == ' '))) { - // O'Clock, 'Em - $string{$i} = strtoupper($string{$i}); - } elseif (preg_match('#^[\'A-Za-z0-9À-ÿ]$#', $string{$i - 1})) { - $string{$i} = strtolower($string{$i}); - } else { - $string{$i} = strtoupper($string{$i}); - } - } + $string{0} = strtoupper($string{0}); + for ($i = 1; $i < $stringlength; $i++) { + if (($string{$i - 1} == '\'') && ($i > 1) && (($string{$i - 2} == 'O') || ($string{$i - 2} == ' '))) { + // O'Clock, 'Em + $string{$i} = strtoupper($string{$i}); + } elseif (preg_match('#^[\'A-Za-z0-9À-ÿ]$#', $string{$i - 1})) { + $string{$i} = strtolower($string{$i}); + } else { + $string{$i} = strtoupper($string{$i}); + } + } - static $LowerCaseWords = ['vs.', 'feat.']; - static $UpperCaseWords = ['DJ', 'USA', 'II', 'MC', 'CD', 'TV', '\'N\'']; + static $LowerCaseWords = array('vs.', 'feat.'); + static $UpperCaseWords = array('DJ', 'USA', 'II', 'MC', 'CD', 'TV', '\'N\''); - $OutputListOfWords = []; - $ListOfWords = explode(' ', $string); - foreach ($ListOfWords as $ThisWord) { - if (in_array(strtolower(str_replace('(', '', $ThisWord)), $LowerCaseWords)) { - $ThisWord = strtolower($ThisWord); - } elseif (in_array(strtoupper(str_replace('(', '', $ThisWord)), $UpperCaseWords)) { - $ThisWord = strtoupper($ThisWord); - } elseif ((substr($ThisWord, 0, 2) == 'Mc') && (strlen($ThisWord) > 2)) { - $ThisWord{2} = strtoupper($ThisWord{2}); - } elseif ((substr($ThisWord, 0, 3) == 'Mac') && (strlen($ThisWord) > 3)) { - $ThisWord{3} = strtoupper($ThisWord{3}); - } - $OutputListOfWords[] = $ThisWord; - } - $UCstring = implode(' ', $OutputListOfWords); - $UCstring = str_replace(' From “', ' from “', $UCstring); - $UCstring = str_replace(' \'n\' ', ' \'N\' ', $UCstring); + $OutputListOfWords = array(); + $ListOfWords = explode(' ', $string); + foreach ($ListOfWords as $ThisWord) { + if (in_array(strtolower(str_replace('(', '', $ThisWord)), $LowerCaseWords)) { + $ThisWord = strtolower($ThisWord); + } elseif (in_array(strtoupper(str_replace('(', '', $ThisWord)), $UpperCaseWords)) { + $ThisWord = strtoupper($ThisWord); + } elseif ((substr($ThisWord, 0, 2) == 'Mc') && (strlen($ThisWord) > 2)) { + $ThisWord{2} = strtoupper($ThisWord{2}); + } elseif ((substr($ThisWord, 0, 3) == 'Mac') && (strlen($ThisWord) > 3)) { + $ThisWord{3} = strtoupper($ThisWord{3}); + } + $OutputListOfWords[] = $ThisWord; + } + $UCstring = implode(' ', $OutputListOfWords); + $UCstring = str_replace(' From “', ' from “', $UCstring); + $UCstring = str_replace(' \'n\' ', ' \'N\' ', $UCstring); - return $UCstring; + return $UCstring; } @@ -1994,19 +2178,19 @@ $SQLquery = 'SELECT COUNT(*) AS `TotalFiles`, SUM(`playtime_seconds`) AS `Total $SQLquery .= ' FROM `'.mysql_real_escape_string(GETID3_DB_TABLE).'`'; $result = mysql_query_safe($SQLquery); if ($row = mysql_fetch_array($result)) { - echo '
    '; - echo '
    '; - echo 'Spent '.number_format(mysql_query_safe(null), 3).' seconds querying the database
    '; - echo '
    '; - echo 'Currently in the database:'; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo '
    Total Files'.number_format($row['TotalFiles']).'
    Total Filesize'.number_format($row['TotalFilesize'] / 1048576).' MB
    Total Playtime'.number_format($row['TotalPlaytime'] / 3600, 1).' hours
    Average Filesize'.number_format($row['AvgFilesize'] / 1048576, 1).' MB
    Average Playtime'.getid3_lib::PlaytimeString($row['AvgPlaytime']).'
    Average Bitrate'.BitrateText($row['AvgBitrate'] / 1000, 1).'
    '; - echo '
    '; + echo '
    '; + echo '
    '; + echo 'Spent '.number_format(mysql_query_safe(null), 3).' seconds querying the database
    '; + echo '
    '; + echo 'Currently in the database:'; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo '
    Total Files'.number_format($row['TotalFiles']).'
    Total Filesize'.number_format($row['TotalFilesize'] / 1048576).' MB
    Total Playtime'.number_format($row['TotalPlaytime'] / 3600, 1).' hours
    Average Filesize'.number_format($row['AvgFilesize'] / 1048576, 1).' MB
    Average Playtime'.getid3_lib::PlaytimeString($row['AvgPlaytime']).'
    Average Bitrate'.BitrateText($row['AvgBitrate'] / 1000, 1).'
    '; + echo '
    '; } -echo ''; +echo ''; \ No newline at end of file diff --git a/app/Library/getid3/demos/demo.simple.php b/app/Library/getid3/demos/demo.simple.php index 39b69944..dbaf7bb6 100644 --- a/app/Library/getid3/demos/demo.simple.php +++ b/app/Library/getid3/demos/demo.simple.php @@ -32,24 +32,24 @@ $dir = opendir($DirectoryToScan); echo ''; echo ''; while (($file = readdir($dir)) !== false) { - $FullFileName = realpath($DirectoryToScan.'/'.$file); - if ((substr($file, 0, 1) != '.') && is_file($FullFileName)) { - set_time_limit(30); + $FullFileName = realpath($DirectoryToScan.'/'.$file); + if ((substr($file, 0, 1) != '.') && is_file($FullFileName)) { + set_time_limit(30); - $ThisFileInfo = $getID3->analyze($FullFileName); + $ThisFileInfo = $getID3->analyze($FullFileName); - getid3_lib::CopyTagsToComments($ThisFileInfo); + getid3_lib::CopyTagsToComments($ThisFileInfo); - // output desired information in whatever format you want - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } + // output desired information in whatever format you want + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } } echo '
    FilenameArtistTitleBitratePlaytime
    '.htmlentities($ThisFileInfo['filenamepath']).'' .htmlentities(!empty($ThisFileInfo['comments_html']['artist']) ? implode('
    ', $ThisFileInfo['comments_html']['artist']) : chr(160)).'
    ' .htmlentities(!empty($ThisFileInfo['comments_html']['title']) ? implode('
    ', $ThisFileInfo['comments_html']['title']) : chr(160)).'
    '.htmlentities(!empty($ThisFileInfo['audio']['bitrate']) ? round($ThisFileInfo['audio']['bitrate'] / 1000).' kbps' : chr(160)).''.htmlentities(!empty($ThisFileInfo['playtime_string']) ? $ThisFileInfo['playtime_string'] : chr(160)).'
    '.htmlentities($ThisFileInfo['filenamepath']).'' .htmlentities(!empty($ThisFileInfo['comments_html']['artist']) ? implode('
    ', $ThisFileInfo['comments_html']['artist']) : chr(160)).'
    ' .htmlentities(!empty($ThisFileInfo['comments_html']['title']) ? implode('
    ', $ThisFileInfo['comments_html']['title']) : chr(160)).'
    '.htmlentities(!empty($ThisFileInfo['audio']['bitrate']) ? round($ThisFileInfo['audio']['bitrate'] / 1000).' kbps' : chr(160)).''.htmlentities(!empty($ThisFileInfo['playtime_string']) ? $ThisFileInfo['playtime_string'] : chr(160)).'
    '; -echo ''; +echo ''; \ No newline at end of file diff --git a/app/Library/getid3/demos/demo.simple.write.php b/app/Library/getid3/demos/demo.simple.write.php index 5cfd7975..8e8b4261 100644 --- a/app/Library/getid3/demos/demo.simple.write.php +++ b/app/Library/getid3/demos/demo.simple.write.php @@ -12,14 +12,14 @@ // /// ///////////////////////////////////////////////////////////////// -//die('Due to a security issue, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in '.$_SERVER['PHP_SELF']); +die('Due to a security issue, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in '.$_SERVER['PHP_SELF']); $TextEncoding = 'UTF-8'; require_once('../getid3/getid3.php'); // Initialize getID3 engine $getID3 = new getID3; -$getID3->setOption(['encoding'=>$TextEncoding]); +$getID3->setOption(array('encoding'=>$TextEncoding)); require_once('../getid3/write.php'); // Initialize getID3 tag-writing module @@ -28,7 +28,7 @@ $tagwriter = new getid3_writetags; $tagwriter->filename = 'c:/file.mp3'; //$tagwriter->tagformats = array('id3v1', 'id3v2.3'); -$tagwriter->tagformats = ['id3v2.3']; +$tagwriter->tagformats = array('id3v2.3'); // set various options (optional) $tagwriter->overwrite_tags = true; // if true will erase existing tag data and write only passed data; if false will merge passed data with existing tag data (experimental) @@ -37,24 +37,25 @@ $tagwriter->tag_encoding = $TextEncoding; $tagwriter->remove_other_tags = true; // populate data array -$TagData = [ - 'title' => ['My Song'], - 'artist' => ['The Artist'], - 'album' => ['Greatest Hits'], - 'year' => ['2004'], - 'genre' => ['Rock'], - 'comment' => ['excellent!'], - 'track' => ['04/16'], - 'popularimeter' => ['email'=>'user@example.net', 'rating'=>128, 'data'=>0], -]; +$TagData = array( + 'title' => array('My Song'), + 'artist' => array('The Artist'), + 'album' => array('Greatest Hits'), + 'year' => array('2004'), + 'genre' => array('Rock'), + 'comment' => array('excellent!'), + 'track' => array('04/16'), + 'popularimeter' => array('email'=>'user@example.net', 'rating'=>128, 'data'=>0), + 'unique_file_identifier' => array('ownerid'=>'user@example.net', 'data'=>md5(time())), +); $tagwriter->tag_data = $TagData; // write tags if ($tagwriter->WriteTags()) { - echo 'Successfully wrote tags
    '; - if (!empty($tagwriter->warnings)) { - echo 'There were some warnings:
    '.implode('

    ', $tagwriter->warnings); - } + echo 'Successfully wrote tags
    '; + if (!empty($tagwriter->warnings)) { + echo 'There were some warnings:
    '.implode('

    ', $tagwriter->warnings); + } } else { - echo 'Failed to write tags!
    '.implode('

    ', $tagwriter->errors); + echo 'Failed to write tags!
    '.implode('

    ', $tagwriter->errors); } diff --git a/app/Library/getid3/demos/demo.write.php b/app/Library/getid3/demos/demo.write.php index 32671e84..c15394b3 100644 --- a/app/Library/getid3/demos/demo.write.php +++ b/app/Library/getid3/demos/demo.write.php @@ -25,7 +25,7 @@ echo 'getID3() - Sample tag writer