Make WordPress Core


Ignore:
Timestamp:
09/14/2019 07:06:09 PM (6 years ago)
Author:
jorbin
Message:

Update getID3 library to fix issues with PHP7.4

Updates to trunk version that includes fixes for PHP7.4

Changelog:
https://github.com/JamesHeinrich/getID3/compare/v1.9.14...00f3fbfd77e583099ca70a3cf0bc092e113d2b20

See: #47751,#47783.
Fixes: #48040.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ID3/module.audio.mp3.php

    r41196 r46112  
    11<?php
     2
    23/////////////////////////////////////////////////////////////////
    34/// getID3() by James Heinrich <info@getid3.org>               //
    4 //  available at http://getid3.sourceforge.net                 //
    5 //            or http://www.getid3.org                         //
    6 //          also https://github.com/JamesHeinrich/getID3       //
    7 /////////////////////////////////////////////////////////////////
    8 // See readme.txt for more details                             //
     5//  available at https://github.com/JamesHeinrich/getID3       //
     6//            or https://www.getid3.org                        //
     7//            or http://getid3.sourceforge.net                 //
     8//  see readme.txt for more details                            //
    99/////////////////////////////////////////////////////////////////
    1010//                                                             //
     
    2525class getid3_mp3 extends getid3_handler
    2626{
    27 
    28     public $allow_bruteforce = false; // forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow, unrecommended, but may provide data from otherwise-unusuable files
    29 
     27    /**
     28     * Forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow,
     29     * unrecommended, but may provide data from otherwise-unusable files.
     30     *
     31     * @var bool
     32     */
     33    public $allow_bruteforce = false;
     34
     35    /**
     36     * @return bool
     37     */
    3038    public function Analyze() {
    3139        $info = &$this->getid3->info;
     
    3644            if ($this->allow_bruteforce) {
    3745                $this->error('Rescanning file in BruteForce mode');
    38                 $this->getOnlyMPEGaudioInfoBruteForce($this->getid3->fp, $info);
     46                $this->getOnlyMPEGaudioInfoBruteForce();
    3947            }
    4048        }
     
    153161        // Calculate playtime
    154162        if (!isset($info['playtime_seconds']) && isset($info['audio']['bitrate']) && ($info['audio']['bitrate'] > 0)) {
    155             $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['audio']['bitrate'];
     163            // https://github.com/JamesHeinrich/getID3/issues/161
     164            // VBR header frame contains ~0.026s of silent audio data, but is not actually part of the original encoding and should be ignored
     165            $xingVBRheaderFrameLength = ((isset($info['mpeg']['audio']['VBR_frames']) && isset($info['mpeg']['audio']['framelength'])) ? $info['mpeg']['audio']['framelength'] : 0);
     166
     167            $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset'] - $xingVBRheaderFrameLength) * 8 / $info['audio']['bitrate'];
    156168        }
    157169
     
    161173    }
    162174
    163 
     175    /**
     176     * @return string
     177     */
    164178    public function GuessEncoderOptions() {
    165179        // shortcuts
    166180        $info = &$this->getid3->info;
     181        $thisfile_mpeg_audio = array();
     182        $thisfile_mpeg_audio_lame = array();
    167183        if (!empty($info['mpeg']['audio'])) {
    168184            $thisfile_mpeg_audio = &$info['mpeg']['audio'];
     
    179195            $encoder_options = 'VBR q'.$thisfile_mpeg_audio['VBR_quality'];
    180196
    181         } elseif (!empty($thisfile_mpeg_audio_lame['preset_used']) && (!in_array($thisfile_mpeg_audio_lame['preset_used_id'], $NamedPresetBitrates))) {
     197        } elseif (!empty($thisfile_mpeg_audio_lame['preset_used']) && isset($thisfile_mpeg_audio_lame['preset_used_id']) && (!in_array($thisfile_mpeg_audio_lame['preset_used_id'], $NamedPresetBitrates))) {
    182198
    183199            $encoder_options = $thisfile_mpeg_audio_lame['preset_used'];
     
    405421    }
    406422
    407 
     423    /**
     424     * @param int   $offset
     425     * @param array $info
     426     * @param bool  $recursivesearch
     427     * @param bool  $ScanAsCBR
     428     * @param bool  $FastMPEGheaderScan
     429     *
     430     * @return bool
     431     */
    408432    public function decodeMPEGaudioHeader($offset, &$info, $recursivesearch=true, $ScanAsCBR=false, $FastMPEGheaderScan=false) {
    409433        static $MPEGaudioVersionLookup;
     
    459483        $thisfile_mpeg_audio = &$info['mpeg']['audio'];
    460484
    461 
    462485        if ($MPEGaudioHeaderValidCache[$head4_key]) {
    463486            $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
     
    563586            $thisfile_mpeg_audio['bitrate_mode'] = 'vbr';
    564587            $thisfile_mpeg_audio['VBR_method']   = 'Fraunhofer';
    565             $info['audio']['codec']                = 'Fraunhofer';
     588            $info['audio']['codec']              = 'Fraunhofer';
    566589
    567590            $SideInfoData = substr($headerstring, 4 + 2, 32);
     
    656679                    } elseif (!empty($info['filesize'])) {
    657680                        $used_filesize  = $info['filesize'];
    658                         $used_filesize -= intval(@$info['id3v2']['headerlength']);
     681                        $used_filesize -= (isset($info['id3v2']['headerlength']) ? intval($info['id3v2']['headerlength']) : 0);
    659682                        $used_filesize -= (isset($info['id3v1']) ? 128 : 0);
    660683                        $used_filesize -= (isset($info['tag_offset_end']) ? $info['tag_offset_end'] - $info['tag_offset_start'] : 0);
     
    679702                    $LAMEtocData = substr($headerstring, $VBRidOffset + 16, 100);
    680703                    for ($i = 0; $i < 100; $i++) {
    681                         $thisfile_mpeg_audio['toc'][$i] = ord($LAMEtocData{$i});
     704                        $thisfile_mpeg_audio['toc'][$i] = ord($LAMEtocData[$i]);
    682705                    }
    683706                }
     
    10841107    }
    10851108
     1109    /**
     1110     * @param int $offset
     1111     * @param int $nextframetestoffset
     1112     * @param bool $ScanAsCBR
     1113     *
     1114     * @return bool
     1115     */
    10861116    public function RecursiveFrameScanning(&$offset, &$nextframetestoffset, $ScanAsCBR) {
    10871117        $info = &$this->getid3->info;
     
    11301160    }
    11311161
     1162    /**
     1163     * @param int  $offset
     1164     * @param bool $deepscan
     1165     *
     1166     * @return int|false
     1167     */
    11321168    public function FreeFormatFrameLength($offset, $deepscan=false) {
    11331169        $info = &$this->getid3->info;
     
    11381174        $SyncPattern1 = substr($MPEGaudioData, 0, 4);
    11391175        // may be different pattern due to padding
    1140         $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) | 0x02).$SyncPattern1{3};
     1176        $SyncPattern2 = $SyncPattern1[0].$SyncPattern1[1].chr(ord($SyncPattern1[2]) | 0x02).$SyncPattern1[3];
    11411177        if ($SyncPattern2 === $SyncPattern1) {
    1142             $SyncPattern2 = $SyncPattern1{0}.$SyncPattern1{1}.chr(ord($SyncPattern1{2}) & 0xFD).$SyncPattern1{3};
     1178            $SyncPattern2 = $SyncPattern1[0].$SyncPattern1[1].chr(ord($SyncPattern1[2]) & 0xFD).$SyncPattern1[3];
    11431179        }
    11441180
     
    12071243    }
    12081244
     1245    /**
     1246     * @return bool
     1247     */
    12091248    public function getOnlyMPEGaudioInfoBruteForce() {
    12101249        $MPEGaudioHeaderDecodeCache   = array();
     
    12421281                break;
    12431282            }
    1244             if ($head4{0} != "\xFF") {
     1283            if ($head4[0] != "\xFF") {
    12451284                for ($i = 1; $i < 4; $i++) {
    1246                     if ($head4{$i} == "\xFF") {
     1285                    if ($head4[$i] == "\xFF") {
    12471286                        $this->fseek($i - 4, SEEK_CUR);
    12481287                        continue 2;
     
    12761315                    $this->fseek($MPEGaudioHeaderLengthCache[$head4] - 4, SEEK_CUR);
    12771316                    $next4 = $this->fread(4);
    1278                     if ($next4{0} == "\xFF") {
     1317                    if ($next4[0] == "\xFF") {
    12791318                        if (!isset($MPEGaudioHeaderDecodeCache[$next4])) {
    12801319                            $MPEGaudioHeaderDecodeCache[$next4] = self::MPEGaudioHeaderDecode($next4);
     
    13541393    }
    13551394
    1356 
     1395    /**
     1396     * @param int  $avdataoffset
     1397     * @param bool $BitrateHistogram
     1398     *
     1399     * @return bool
     1400     */
    13571401    public function getOnlyMPEGaudioInfo($avdataoffset, $BitrateHistogram=false) {
    13581402        // looks for synch, decodes MPEG audio header
     
    13641408        static $MPEGaudioBitrateLookup;
    13651409        if (empty($MPEGaudioVersionLookup)) {
    1366            $MPEGaudioVersionLookup = self::MPEGaudioVersionArray();
    1367            $MPEGaudioLayerLookup   = self::MPEGaudioLayerArray();
    1368            $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray();
    1369 
     1410            $MPEGaudioVersionLookup = self::MPEGaudioVersionArray();
     1411            $MPEGaudioLayerLookup   = self::MPEGaudioLayerArray();
     1412            $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray();
    13701413        }
    13711414
     
    14171460            }
    14181461
    1419             if (($header{$SynchSeekOffset} == "\xFF") && ($header{($SynchSeekOffset + 1)} > "\xE0")) { // synch detected
     1462            if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // synch detected
     1463                $FirstFrameAVDataOffset = null;
    14201464                if (!isset($FirstFrameThisfileInfo) && !isset($info['mpeg']['audio'])) {
    14211465                    $FirstFrameThisfileInfo = $info;
     
    14411485                            break;
    14421486                    }
    1443                     if (isset($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode']) && ($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr')) {
     1487                    if (isset($FirstFrameThisfileInfo) && isset($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode']) && ($FirstFrameThisfileInfo['mpeg']['audio']['bitrate_mode'] == 'vbr')) {
    14441488                        if (!(abs($info['audio']['bitrate'] - $FirstFrameThisfileInfo['audio']['bitrate']) <= 1)) {
    14451489                            // If there is garbage data between a valid VBR header frame and a sequence
     
    15111555                                $buffer_4k = $this->fread(4096);
    15121556                                for ($j = 0; $j < (strlen($buffer_4k) - 4); $j++) {
    1513                                     if (($buffer_4k{$j} == "\xFF") && ($buffer_4k{($j + 1)} > "\xE0")) { // synch detected
     1557                                    if (($buffer_4k[$j] == "\xFF") && ($buffer_4k[($j + 1)] > "\xE0")) { // synch detected
    15141558                                        if ($this->decodeMPEGaudioHeader($scan_start_offset[$current_segment] + $j, $dummy, false, false, $FastMode)) {
    15151559                                            $calculated_next_offset = $scan_start_offset[$current_segment] + $j + $dummy['mpeg']['audio']['framelength'];
     
    15231567                            }
    15241568                            $synchstartoffset = $scan_start_offset[$current_segment];
    1525                             while ($this->decodeMPEGaudioHeader($synchstartoffset, $dummy, false, false, $FastMode)) {
     1569                            while (($synchstartoffset < $info['avdataend']) && $this->decodeMPEGaudioHeader($synchstartoffset, $dummy, false, false, $FastMode)) {
    15261570                                $FastMode = true;
    15271571                                $thisframebitrate = $MPEGaudioBitrateLookup[$MPEGaudioVersionLookup[$dummy['mpeg']['audio']['raw']['version']]][$MPEGaudioLayerLookup[$dummy['mpeg']['audio']['raw']['layer']]][$dummy['mpeg']['audio']['raw']['bitrate']];
     
    16341678    }
    16351679
    1636 
     1680    /**
     1681     * @return array
     1682     */
    16371683    public static function MPEGaudioVersionArray() {
    16381684        static $MPEGaudioVersion = array('2.5', false, '2', '1');
     
    16401686    }
    16411687
     1688    /**
     1689     * @return array
     1690     */
    16421691    public static function MPEGaudioLayerArray() {
    16431692        static $MPEGaudioLayer = array(false, 3, 2, 1);
     
    16451694    }
    16461695
     1696    /**
     1697     * @return array
     1698     */
    16471699    public static function MPEGaudioBitrateArray() {
    16481700        static $MPEGaudioBitrate;
     
    16641716    }
    16651717
     1718    /**
     1719     * @return array
     1720     */
    16661721    public static function MPEGaudioFrequencyArray() {
    16671722        static $MPEGaudioFrequency;
     
    16761731    }
    16771732
     1733    /**
     1734     * @return array
     1735     */
    16781736    public static function MPEGaudioChannelModeArray() {
    16791737        static $MPEGaudioChannelMode = array('stereo', 'joint stereo', 'dual channel', 'mono');
     
    16811739    }
    16821740
     1741    /**
     1742     * @return array
     1743     */
    16831744    public static function MPEGaudioModeExtensionArray() {
    16841745        static $MPEGaudioModeExtension;
     
    16931754    }
    16941755
     1756    /**
     1757     * @return array
     1758     */
    16951759    public static function MPEGaudioEmphasisArray() {
    16961760        static $MPEGaudioEmphasis = array('none', '50/15ms', false, 'CCIT J.17');
     
    16981762    }
    16991763
     1764    /**
     1765     * @param string $head4
     1766     * @param bool   $allowBitrate15
     1767     *
     1768     * @return bool
     1769     */
    17001770    public static function MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false) {
    17011771        return self::MPEGaudioHeaderValid(self::MPEGaudioHeaderDecode($head4), false, $allowBitrate15);
    17021772    }
    17031773
     1774    /**
     1775     * @param array $rawarray
     1776     * @param bool  $echoerrors
     1777     * @param bool  $allowBitrate15
     1778     *
     1779     * @return bool
     1780     */
    17041781    public static function MPEGaudioHeaderValid($rawarray, $echoerrors=false, $allowBitrate15=false) {
    17051782        if (($rawarray['synch'] & 0x0FFE) != 0x0FFE) {
     
    17741851    }
    17751852
     1853    /**
     1854     * @param string $Header4Bytes
     1855     *
     1856     * @return array|false
     1857     */
    17761858    public static function MPEGaudioHeaderDecode($Header4Bytes) {
    17771859        // AAAA AAAA  AAAB BCCD  EEEE FFGH  IIJJ KLMM
     
    17951877
    17961878        $MPEGrawHeader['synch']         = (getid3_lib::BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4;
    1797         $MPEGrawHeader['version']       = (ord($Header4Bytes{1}) & 0x18) >> 3; //    BB
    1798         $MPEGrawHeader['layer']         = (ord($Header4Bytes{1}) & 0x06) >> 1; //      CC
    1799         $MPEGrawHeader['protection']    = (ord($Header4Bytes{1}) & 0x01);      //        D
    1800         $MPEGrawHeader['bitrate']       = (ord($Header4Bytes{2}) & 0xF0) >> 4; // EEEE
    1801         $MPEGrawHeader['sample_rate']   = (ord($Header4Bytes{2}) & 0x0C) >> 2; //     FF
    1802         $MPEGrawHeader['padding']       = (ord($Header4Bytes{2}) & 0x02) >> 1; //       G
    1803         $MPEGrawHeader['private']       = (ord($Header4Bytes{2}) & 0x01);      //        H
    1804         $MPEGrawHeader['channelmode']   = (ord($Header4Bytes{3}) & 0xC0) >> 6; // II
    1805         $MPEGrawHeader['modeextension'] = (ord($Header4Bytes{3}) & 0x30) >> 4; //   JJ
    1806         $MPEGrawHeader['copyright']     = (ord($Header4Bytes{3}) & 0x08) >> 3; //     K
    1807         $MPEGrawHeader['original']      = (ord($Header4Bytes{3}) & 0x04) >> 2; //      L
    1808         $MPEGrawHeader['emphasis']      = (ord($Header4Bytes{3}) & 0x03);      //       MM
     1879        $MPEGrawHeader['version']       = (ord($Header4Bytes[1]) & 0x18) >> 3; //    BB
     1880        $MPEGrawHeader['layer']         = (ord($Header4Bytes[1]) & 0x06) >> 1; //      CC
     1881        $MPEGrawHeader['protection']    = (ord($Header4Bytes[1]) & 0x01);      //        D
     1882        $MPEGrawHeader['bitrate']       = (ord($Header4Bytes[2]) & 0xF0) >> 4; // EEEE
     1883        $MPEGrawHeader['sample_rate']   = (ord($Header4Bytes[2]) & 0x0C) >> 2; //     FF
     1884        $MPEGrawHeader['padding']       = (ord($Header4Bytes[2]) & 0x02) >> 1; //       G
     1885        $MPEGrawHeader['private']       = (ord($Header4Bytes[2]) & 0x01);      //        H
     1886        $MPEGrawHeader['channelmode']   = (ord($Header4Bytes[3]) & 0xC0) >> 6; // II
     1887        $MPEGrawHeader['modeextension'] = (ord($Header4Bytes[3]) & 0x30) >> 4; //   JJ
     1888        $MPEGrawHeader['copyright']     = (ord($Header4Bytes[3]) & 0x08) >> 3; //     K
     1889        $MPEGrawHeader['original']      = (ord($Header4Bytes[3]) & 0x04) >> 2; //      L
     1890        $MPEGrawHeader['emphasis']      = (ord($Header4Bytes[3]) & 0x03);      //       MM
    18091891
    18101892        return $MPEGrawHeader;
    18111893    }
    18121894
     1895    /**
     1896     * @param int|string $bitrate
     1897     * @param string     $version
     1898     * @param string     $layer
     1899     * @param bool       $padding
     1900     * @param int        $samplerate
     1901     *
     1902     * @return int|false
     1903     */
    18131904    public static function MPEGaudioFrameLength(&$bitrate, &$version, &$layer, $padding, &$samplerate) {
    18141905        static $AudioFrameLengthCache = array();
     
    18721963    }
    18731964
     1965    /**
     1966     * @param float|int $bit_rate
     1967     *
     1968     * @return int|float|string
     1969     */
    18741970    public static function ClosestStandardMP3Bitrate($bit_rate) {
    18751971        static $standard_bit_rates = array (320000, 256000, 224000, 192000, 160000, 128000, 112000, 96000, 80000, 64000, 56000, 48000, 40000, 32000, 24000, 16000, 8000);
     
    18921988    }
    18931989
     1990    /**
     1991     * @param string $version
     1992     * @param string $channelmode
     1993     *
     1994     * @return int
     1995     */
    18941996    public static function XingVBRidOffset($version, $channelmode) {
    18951997        static $XingVBRidOffsetCache = array();
    1896         if (empty($XingVBRidOffset)) {
    1897             $XingVBRidOffset = array (
     1998        if (empty($XingVBRidOffsetCache)) {
     1999            $XingVBRidOffsetCache = array (
    18982000                '1'   => array ('mono'          => 0x15, // 4 + 17 = 21
    18992001                                'stereo'        => 0x24, // 4 + 32 = 36
     
    19152017            );
    19162018        }
    1917         return $XingVBRidOffset[$version][$channelmode];
    1918     }
    1919 
     2019        return $XingVBRidOffsetCache[$version][$channelmode];
     2020    }
     2021
     2022    /**
     2023     * @param int $VBRmethodID
     2024     *
     2025     * @return string
     2026     */
    19202027    public static function LAMEvbrMethodLookup($VBRmethodID) {
    19212028        static $LAMEvbrMethodLookup = array(
     
    19342041    }
    19352042
     2043    /**
     2044     * @param int $StereoModeID
     2045     *
     2046     * @return string
     2047     */
    19362048    public static function LAMEmiscStereoModeLookup($StereoModeID) {
    19372049        static $LAMEmiscStereoModeLookup = array(
     
    19482060    }
    19492061
     2062    /**
     2063     * @param int $SourceSampleFrequencyID
     2064     *
     2065     * @return string
     2066     */
    19502067    public static function LAMEmiscSourceSampleFrequencyLookup($SourceSampleFrequencyID) {
    19512068        static $LAMEmiscSourceSampleFrequencyLookup = array(
     
    19582075    }
    19592076
     2077    /**
     2078     * @param int $SurroundInfoID
     2079     *
     2080     * @return string
     2081     */
    19602082    public static function LAMEsurroundInfoLookup($SurroundInfoID) {
    19612083        static $LAMEsurroundInfoLookup = array(
     
    19682090    }
    19692091
     2092    /**
     2093     * @param array $LAMEtag
     2094     *
     2095     * @return string
     2096     */
    19702097    public static function LAMEpresetUsedLookup($LAMEtag) {
    19712098
Note: See TracChangeset for help on using the changeset viewer.