Exemplo n.º 1
0
 function tagFlacFile($file, $tagData, $allowBlank = FALSE, $coverFile = NULL)
 {
     if (!file_exists($file)) {
         $error = 'The input file appears not to exist';
         return array('result' => FALSE, 'error' => $error);
     }
     //Instantiate the getID3 object.
     $gid3 = new getID3();
     if (!is_object($gid3)) {
         $error = 'The getID3 object could not be instantiated';
         return array('result' => FALSE, 'error' => $error);
     }
     //Attempt to acquire the audio file's properties.
     $fileDetails = $gid3->analyze($file);
     if (!is_array($fileDetails)) {
         $error = 'getID3\'s analyze() method did not return a usable array';
         return array('result' => FALSE, 'error' => $error);
     }
     //Ensure that the file on which we're attempting to operate is indeed
     //a FLAC file.
     //
     //Note: we could use the self::validateAudioFile() method, but there's
     //no reason to waste the time/memory required to call that function
     //when we have to call getID3's analyze() method again.
     if (!isset($fileDetails['fileformat']) || $fileDetails['fileformat'] != 'flac') {
         $error = 'The audio file does not validate as a FLAC file';
         return array('result' => FALSE, 'error' => $error);
     }
     //A counter to store the number of tags that we attempted to write.
     $numWritesAttempted = 0;
     //Attempt to remove any existing tags before writing new tags.
     //IMPORTANT: The --remove-vc-all option is deprecated in favor of the
     //--remove-all-tags option; using the deprecated option will cause the
     //command to fail on systems on which the option is not supported.
     //Changed to --remove-all because cover art was not being removed. -CBJ 2011.01.18
     $cmd = 'metaflac --remove-all "' . $file . '"';
     //XXX This call should be updated to use GlobalMethods::openProcess().
     $output = shell_exec($cmd);
     //Attempt to acquire the audio file's properties, again, now that
     //we've attempted to remove any existing tags.
     $fileDetails = $gid3->analyze($file);
     if (!is_array($fileDetails)) {
         $error = 'getID3\'s analyze() method did not return a usable array';
         return array('result' => FALSE, 'error' => $error);
     }
     //We attempted to remove all tags from the FLAC file; we can
     //determine whether or not we were successful in that effort by
     //checking to see if the vorbiscomment block is present in the file.
     if (isset($fileDetails['tags']['vorbiscomment'])) {
         $error = 'The vorbiscomment block was not removed for some reason';
         return array('result' => FALSE, 'error' => $error);
     }
     if (empty($tagData['date'][0]) || $tagData['date'][0] === 'Unknown') {
         unset($tagData['date']);
     }
     if (!empty($coverFile)) {
         $res = $this->embedFlacArt($coverFile, $file);
         if ($res['result'] !== FALSE) {
         } else {
             $error = 'Embedding cover art in FLAC file "' . $file . '" failed; ' . $res['error'];
             \GlobalMethods::logCriticalError($error);
         }
     }
     //Attempt to add each tag to the FLAC file, and keep track of the number
     //of write attempts. Given that the shell_exec() exit status is not a
     //reliable means by which to determine the success/failure of the
     //operation, we must compare the number of write attempts to the number
     //of tags that exist once we're done attempting to write.
     foreach ($tagData as $fieldName => $fieldDataArray) {
         foreach ($fieldDataArray as $numericIndex => $fieldValue) {
             //IMPORTANT: The --set-vc-field option is deprecated in favor of the
             //--set-tag option; using the deprecated option will cause the command to
             //fail on systems on which the option is not supported.
             $cmd = 'metaflac --set-tag=' . ucfirst($fieldName) . '="' . $fieldValue . '" "' . $file . '"';
             //XXX This call should be updated to use GlobalMethods::openProcess().
             $output = shell_exec($cmd);
             $numWritesAttempted++;
         }
     }
     //Attempt to acquire the audio file's properties, again, now that we've
     //attempted to write new tags.
     $fileDetails = $gid3->analyze($file);
     $prefix = 'getID3\'s analyze() method';
     if (!is_array($fileDetails)) {
         $error = $prefix . ' did not return a usable array';
         return array('result' => FALSE, 'error' => $error);
     }
     if ($allowBlank !== TRUE) {
         if (!isset($fileDetails['tags']['vorbiscomment'])) {
             $error = $prefix . ' determined that the tags were not written for some reason';
             if (!empty($fileDetails['error'])) {
                 for ($i = 0; $i < count($fileDetails['error']); $i++) {
                     if ($i == 0) {
                         $error .= ": ";
                     } else {
                         $error .= '; ';
                     }
                     $error .= $fileDetails['error'][$i];
                 }
             }
             return array('result' => FALSE, 'error' => $error);
         } else {
             //If at least one tag was written, we'll end-up here.
             $vorbiscomment = $fileDetails['tags']['vorbiscomment'];
             $numWritesSucceeded = 0;
             //Now, we'll compare each tag on the file with the tag data that
             //we attempted to apply earlier, in order to determine whether
             //or not each tag was written successfully.
             foreach ($tagData as $fieldName => $fieldDataArray) {
                 foreach ($fieldDataArray as $numericIndex => $fieldValue) {
                     if ($vorbiscomment[$fieldName][0] == $fieldValue) {
                         $numWritesSucceeded++;
                     }
                 }
             }
             //We're able to compare how many tags were written versus how
             //many write attempts were made in order to determine our
             //success rate.
             if ($numWritesAttempted == $numWritesSucceeded) {
                 return array('result' => TRUE, 'error' => NULL);
             } else {
                 $error = 'The number of tag writes that succeeded (' . $numWritesSucceeded . ') is less than the number attempted (' . $numWritesAttempted . ')';
                 return array('result' => FALSE, 'error' => $error);
             }
         }
     } else {
         return array('result' => TRUE, 'error' => NULL);
     }
 }
Exemplo n.º 2
0
 /**
  * Important: NEVER call this function on a "master" file, as it removes the
  * artwork from THAT file (and not a copy)!
  * @param string $file
  * @param array $tagData
  * @param boolean $allowBlank
  * @param string $coverFile
  * @return multitype:boolean string |multitype:boolean NULL
  */
 function transcodeFlacToAlac($file, $tagData = array(), $allowBlank = FALSE, $coverFile = NULL)
 {
     //In avconv version 9.16 (and possibly earlier), embedded artwork with a
     //width or height that is not divisible by 2 will cause a failure, e.g.:
     //"width not divisible by 2 (1419x1419)". So, we must strip any "odd" artwork.
     //It's entirely possible that artwork was not copied in earlier versions, so
     //this error did not occur.
     $r = $this->tagger->removeArtwork($file);
     $cmd1 = 'avconv -i';
     //Tag data is copied automatically. Nice!!!
     $pathParts = pathinfo($file);
     $outfile = $pathParts['dirname'] . DIRECTORY_SEPARATOR . $pathParts['filename'] . '.m4a';
     $cmd1 .= ' "' . $file . '" -acodec alac "' . $outfile . '"';
     $r1 = \GlobalMethods::openProcess($cmd1);
     if ($r1['exitCode'] == 0) {
         //Write the cover artwork into the file, and fail gracefully.
         //Note the unconventional letter-case of the executable name and its options
         //(which are indeed case-sensitive).
         if (is_string($coverFile) && strlen($coverFile) > 0) {
             $cmd2 = 'AtomicParsley "' . $outfile . '" --artwork "' . $coverFile . '" --overWrite';
             $r2 = \GlobalMethods::openProcess($cmd2);
             if ($r2['exitCode'] != 0) {
                 $e = 'The FLAC file was transcoded to an ALAC file successfully, but the album artwork could not be embedded; the command was: "' . $cmd2 . '"';
                 \GlobalMethods::logCriticalError($e);
             }
         }
     } else {
         $error = 'The FLAC file could not be transcoded to an ALAC file; the command was: "' . $cmd1 . '"';
         return array('result' => FALSE, 'error' => $error);
     }
     return array('result' => TRUE, 'error' => NULL);
 }