Edit File by line

Deprecated: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in /home/sportsfever/public_html/filemanger/function.php on line 93

Warning: Undefined array key "page_file_edit_line" in /home/sportsfever/public_html/filemanger/edit_text_line.php on line 32
/home/sportsfe.../httpdocs/clone/wp-inclu.../ID3
File: module.audio-video.quicktime.php
while (($mdat_offset < (strlen($atom_data) - 8))
[1500] Fix | Delete
&& ($chapter_string_length = getid3_lib::BigEndian2Int(substr($atom_data, $mdat_offset, 2)))
[1501] Fix | Delete
&& ($chapter_string_length < 1000)
[1502] Fix | Delete
&& ($chapter_string_length <= (strlen($atom_data) - $mdat_offset - 2))
[1503] Fix | Delete
&& preg_match('#^([\x00-\xFF]{2})([\x20-\xFF]+)$#', substr($atom_data, $mdat_offset, $chapter_string_length + 2), $chapter_matches)) {
[1504] Fix | Delete
list($dummy, $chapter_string_length_hex, $chapter_string) = $chapter_matches;
[1505] Fix | Delete
$mdat_offset += (2 + $chapter_string_length);
[1506] Fix | Delete
@$info['quicktime']['comments']['chapters'][] = $chapter_string;
[1507] Fix | Delete
[1508] Fix | Delete
// "encd" atom specifies encoding. In theory could be anything, almost always UTF-8, but may be UTF-16 with BOM (not currently handled)
[1509] Fix | Delete
if (substr($atom_data, $mdat_offset, 12) == "\x00\x00\x00\x0C\x65\x6E\x63\x64\x00\x00\x01\x00") { // UTF-8
[1510] Fix | Delete
$mdat_offset += 12;
[1511] Fix | Delete
}
[1512] Fix | Delete
}
[1513] Fix | Delete
[1514] Fix | Delete
if (($atomsize > 8) && (!isset($info['avdataend_tmp']) || ($info['quicktime'][$atomname]['size'] > ($info['avdataend_tmp'] - $info['avdataoffset'])))) {
[1515] Fix | Delete
[1516] Fix | Delete
$info['avdataoffset'] = $atom_structure['offset'] + 8; // $info['quicktime'][$atomname]['offset'] + 8;
[1517] Fix | Delete
$OldAVDataEnd = $info['avdataend'];
[1518] Fix | Delete
$info['avdataend'] = $atom_structure['offset'] + $atom_structure['size']; // $info['quicktime'][$atomname]['offset'] + $info['quicktime'][$atomname]['size'];
[1519] Fix | Delete
[1520] Fix | Delete
$getid3_temp = new getID3();
[1521] Fix | Delete
$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
[1522] Fix | Delete
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
[1523] Fix | Delete
$getid3_temp->info['avdataend'] = $info['avdataend'];
[1524] Fix | Delete
$getid3_mp3 = new getid3_mp3($getid3_temp);
[1525] Fix | Delete
if ($getid3_mp3->MPEGaudioHeaderValid($getid3_mp3->MPEGaudioHeaderDecode($this->fread(4)))) {
[1526] Fix | Delete
$getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
[1527] Fix | Delete
if (!empty($getid3_temp->info['warning'])) {
[1528] Fix | Delete
foreach ($getid3_temp->info['warning'] as $value) {
[1529] Fix | Delete
$this->warning($value);
[1530] Fix | Delete
}
[1531] Fix | Delete
}
[1532] Fix | Delete
if (!empty($getid3_temp->info['mpeg'])) {
[1533] Fix | Delete
$info['mpeg'] = $getid3_temp->info['mpeg'];
[1534] Fix | Delete
if (isset($info['mpeg']['audio'])) {
[1535] Fix | Delete
$info['audio']['dataformat'] = 'mp3';
[1536] Fix | Delete
$info['audio']['codec'] = (!empty($info['mpeg']['audio']['encoder']) ? $info['mpeg']['audio']['encoder'] : (!empty($info['mpeg']['audio']['codec']) ? $info['mpeg']['audio']['codec'] : (!empty($info['mpeg']['audio']['LAME']) ? 'LAME' :'mp3')));
[1537] Fix | Delete
$info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
[1538] Fix | Delete
$info['audio']['channels'] = $info['mpeg']['audio']['channels'];
[1539] Fix | Delete
$info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate'];
[1540] Fix | Delete
$info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
[1541] Fix | Delete
$info['bitrate'] = $info['audio']['bitrate'];
[1542] Fix | Delete
}
[1543] Fix | Delete
}
[1544] Fix | Delete
}
[1545] Fix | Delete
unset($getid3_mp3, $getid3_temp);
[1546] Fix | Delete
$info['avdataend'] = $OldAVDataEnd;
[1547] Fix | Delete
unset($OldAVDataEnd);
[1548] Fix | Delete
[1549] Fix | Delete
}
[1550] Fix | Delete
[1551] Fix | Delete
unset($mdat_offset, $chapter_string_length, $chapter_matches);
[1552] Fix | Delete
break;
[1553] Fix | Delete
[1554] Fix | Delete
case 'ID32': // ID3v2
[1555] Fix | Delete
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
[1556] Fix | Delete
[1557] Fix | Delete
$getid3_temp = new getID3();
[1558] Fix | Delete
$getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
[1559] Fix | Delete
$getid3_id3v2 = new getid3_id3v2($getid3_temp);
[1560] Fix | Delete
$getid3_id3v2->StartingOffset = $atom_structure['offset'] + 14; // framelength(4)+framename(4)+flags(4)+??(2)
[1561] Fix | Delete
if ($atom_structure['valid'] = $getid3_id3v2->Analyze()) {
[1562] Fix | Delete
$atom_structure['id3v2'] = $getid3_temp->info['id3v2'];
[1563] Fix | Delete
} else {
[1564] Fix | Delete
$this->warning('ID32 frame at offset '.$atom_structure['offset'].' did not parse');
[1565] Fix | Delete
}
[1566] Fix | Delete
unset($getid3_temp, $getid3_id3v2);
[1567] Fix | Delete
break;
[1568] Fix | Delete
[1569] Fix | Delete
case 'free': // FREE space atom
[1570] Fix | Delete
case 'skip': // SKIP atom
[1571] Fix | Delete
case 'wide': // 64-bit expansion placeholder atom
[1572] Fix | Delete
// 'free', 'skip' and 'wide' are just padding, contains no useful data at all
[1573] Fix | Delete
[1574] Fix | Delete
// When writing QuickTime files, it is sometimes necessary to update an atom's size.
[1575] Fix | Delete
// It is impossible to update a 32-bit atom to a 64-bit atom since the 32-bit atom
[1576] Fix | Delete
// is only 8 bytes in size, and the 64-bit atom requires 16 bytes. Therefore, QuickTime
[1577] Fix | Delete
// puts an 8-byte placeholder atom before any atoms it may have to update the size of.
[1578] Fix | Delete
// In this way, if the atom needs to be converted from a 32-bit to a 64-bit atom, the
[1579] Fix | Delete
// placeholder atom can be overwritten to obtain the necessary 8 extra bytes.
[1580] Fix | Delete
// The placeholder atom has a type of kWideAtomPlaceholderType ( 'wide' ).
[1581] Fix | Delete
break;
[1582] Fix | Delete
[1583] Fix | Delete
[1584] Fix | Delete
case 'nsav': // NoSAVe atom
[1585] Fix | Delete
// http://developer.apple.com/technotes/tn/tn2038.html
[1586] Fix | Delete
$atom_structure['data'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4));
[1587] Fix | Delete
break;
[1588] Fix | Delete
[1589] Fix | Delete
case 'ctyp': // Controller TYPe atom (seen on QTVR)
[1590] Fix | Delete
// http://homepages.slingshot.co.nz/~helmboy/quicktime/formats/qtm-layout.txt
[1591] Fix | Delete
// some controller names are:
[1592] Fix | Delete
// 0x00 + 'std' for linear movie
[1593] Fix | Delete
// 'none' for no controls
[1594] Fix | Delete
$atom_structure['ctyp'] = substr($atom_data, 0, 4);
[1595] Fix | Delete
$info['quicktime']['controller'] = $atom_structure['ctyp'];
[1596] Fix | Delete
switch ($atom_structure['ctyp']) {
[1597] Fix | Delete
case 'qtvr':
[1598] Fix | Delete
$info['video']['dataformat'] = 'quicktimevr';
[1599] Fix | Delete
break;
[1600] Fix | Delete
}
[1601] Fix | Delete
break;
[1602] Fix | Delete
[1603] Fix | Delete
case 'pano': // PANOrama track (seen on QTVR)
[1604] Fix | Delete
$atom_structure['pano'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4));
[1605] Fix | Delete
break;
[1606] Fix | Delete
[1607] Fix | Delete
case 'hint': // HINT track
[1608] Fix | Delete
case 'hinf': //
[1609] Fix | Delete
case 'hinv': //
[1610] Fix | Delete
case 'hnti': //
[1611] Fix | Delete
$info['quicktime']['hinting'] = true;
[1612] Fix | Delete
break;
[1613] Fix | Delete
[1614] Fix | Delete
case 'imgt': // IMaGe Track reference (kQTVRImageTrackRefType) (seen on QTVR)
[1615] Fix | Delete
for ($i = 0; $i < ($atom_structure['size'] - 8); $i += 4) {
[1616] Fix | Delete
$atom_structure['imgt'][] = getid3_lib::BigEndian2Int(substr($atom_data, $i, 4));
[1617] Fix | Delete
}
[1618] Fix | Delete
break;
[1619] Fix | Delete
[1620] Fix | Delete
[1621] Fix | Delete
// Observed-but-not-handled atom types are just listed here to prevent warnings being generated
[1622] Fix | Delete
case 'FXTC': // Something to do with Adobe After Effects (?)
[1623] Fix | Delete
case 'PrmA':
[1624] Fix | Delete
case 'code':
[1625] Fix | Delete
case 'FIEL': // this is NOT "fiel" (Field Ordering) as describe here: http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/chapter_4_section_2.html
[1626] Fix | Delete
case 'tapt': // TrackApertureModeDimensionsAID - http://developer.apple.com/documentation/QuickTime/Reference/QT7-1_Update_Reference/Constants/Constants.html
[1627] Fix | Delete
// tapt seems to be used to compute the video size [https://www.getid3.org/phpBB3/viewtopic.php?t=838]
[1628] Fix | Delete
// * http://lists.apple.com/archives/quicktime-api/2006/Aug/msg00014.html
[1629] Fix | Delete
// * http://handbrake.fr/irclogs/handbrake-dev/handbrake-dev20080128_pg2.html
[1630] Fix | Delete
case 'ctts':// STCompositionOffsetAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
[1631] Fix | Delete
case 'cslg':// STCompositionShiftLeastGreatestAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
[1632] Fix | Delete
case 'sdtp':// STSampleDependencyAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
[1633] Fix | Delete
case 'stps':// STPartialSyncSampleAID - http://developer.apple.com/documentation/QuickTime/Reference/QTRef_Constants/Reference/reference.html
[1634] Fix | Delete
//$atom_structure['data'] = $atom_data;
[1635] Fix | Delete
break;
[1636] Fix | Delete
[1637] Fix | Delete
case "\xA9".'xyz': // GPS latitude+longitude+altitude
[1638] Fix | Delete
$atom_structure['data'] = $atom_data;
[1639] Fix | Delete
if (preg_match('#([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)([\\+\\-][0-9\\.]+)?/$#i', $atom_data, $matches)) {
[1640] Fix | Delete
@list($all, $latitude, $longitude, $altitude) = $matches;
[1641] Fix | Delete
$info['quicktime']['comments']['gps_latitude'][] = floatval($latitude);
[1642] Fix | Delete
$info['quicktime']['comments']['gps_longitude'][] = floatval($longitude);
[1643] Fix | Delete
if (!empty($altitude)) {
[1644] Fix | Delete
$info['quicktime']['comments']['gps_altitude'][] = floatval($altitude);
[1645] Fix | Delete
}
[1646] Fix | Delete
} else {
[1647] Fix | Delete
$this->warning('QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.');
[1648] Fix | Delete
}
[1649] Fix | Delete
break;
[1650] Fix | Delete
[1651] Fix | Delete
case 'NCDT':
[1652] Fix | Delete
// https://exiftool.org/TagNames/Nikon.html
[1653] Fix | Delete
// Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
[1654] Fix | Delete
$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms);
[1655] Fix | Delete
break;
[1656] Fix | Delete
case 'NCTH': // Nikon Camera THumbnail image
[1657] Fix | Delete
case 'NCVW': // Nikon Camera preVieW image
[1658] Fix | Delete
case 'NCM1': // Nikon Camera preview iMage 1
[1659] Fix | Delete
case 'NCM2': // Nikon Camera preview iMage 2
[1660] Fix | Delete
// https://exiftool.org/TagNames/Nikon.html
[1661] Fix | Delete
if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) {
[1662] Fix | Delete
$descriptions = array(
[1663] Fix | Delete
'NCTH' => 'Nikon Camera Thumbnail Image',
[1664] Fix | Delete
'NCVW' => 'Nikon Camera Preview Image',
[1665] Fix | Delete
'NCM1' => 'Nikon Camera Preview Image 1',
[1666] Fix | Delete
'NCM2' => 'Nikon Camera Preview Image 2',
[1667] Fix | Delete
);
[1668] Fix | Delete
$atom_structure['data'] = $atom_data;
[1669] Fix | Delete
$atom_structure['image_mime'] = 'image/jpeg';
[1670] Fix | Delete
$atom_structure['description'] = $descriptions[$atomname];
[1671] Fix | Delete
$info['quicktime']['comments']['picture'][] = array(
[1672] Fix | Delete
'image_mime' => $atom_structure['image_mime'],
[1673] Fix | Delete
'data' => $atom_data,
[1674] Fix | Delete
'description' => $atom_structure['description']
[1675] Fix | Delete
);
[1676] Fix | Delete
}
[1677] Fix | Delete
break;
[1678] Fix | Delete
case 'NCTG': // Nikon - https://exiftool.org/TagNames/Nikon.html#NCTG
[1679] Fix | Delete
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.nikon-nctg.php', __FILE__, true);
[1680] Fix | Delete
$nikonNCTG = new getid3_tag_nikon_nctg($this->getid3);
[1681] Fix | Delete
[1682] Fix | Delete
$atom_structure['data'] = $nikonNCTG->parse($atom_data);
[1683] Fix | Delete
break;
[1684] Fix | Delete
case 'NCHD': // Nikon:MakerNoteVersion - https://exiftool.org/TagNames/Nikon.html
[1685] Fix | Delete
$makerNoteVersion = '';
[1686] Fix | Delete
for ($i = 0, $iMax = strlen($atom_data); $i < $iMax; ++$i) {
[1687] Fix | Delete
if (ord($atom_data[$i]) <= 0x1F) {
[1688] Fix | Delete
$makerNoteVersion .= ' '.ord($atom_data[$i]);
[1689] Fix | Delete
} else {
[1690] Fix | Delete
$makerNoteVersion .= $atom_data[$i];
[1691] Fix | Delete
}
[1692] Fix | Delete
}
[1693] Fix | Delete
$makerNoteVersion = rtrim($makerNoteVersion, "\x00");
[1694] Fix | Delete
$atom_structure['data'] = array(
[1695] Fix | Delete
'MakerNoteVersion' => $makerNoteVersion
[1696] Fix | Delete
);
[1697] Fix | Delete
break;
[1698] Fix | Delete
case 'NCDB': // Nikon - https://exiftool.org/TagNames/Nikon.html
[1699] Fix | Delete
case 'CNCV': // Canon:CompressorVersion - https://exiftool.org/TagNames/Canon.html
[1700] Fix | Delete
$atom_structure['data'] = $atom_data;
[1701] Fix | Delete
break;
[1702] Fix | Delete
[1703] Fix | Delete
case "\x00\x00\x00\x00":
[1704] Fix | Delete
// some kind of metacontainer, may contain a big data dump such as:
[1705] Fix | Delete
// mdta keys \005 mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst \01D \001 \015data \001DE\010Apple 0 \002 (data \001DE\0102011-05-11T17:54:04+0200 2 \003 *data \001DE\010+52.4936+013.3897+040.247/ \01D \004 \015data \001DE\0104.3.1 \005 \018data \001DE\010iPhone 4
[1706] Fix | Delete
// https://xhelmboyx.tripod.com/formats/qti-layout.txt
[1707] Fix | Delete
[1708] Fix | Delete
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
[1709] Fix | Delete
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
[1710] Fix | Delete
$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
[1711] Fix | Delete
//$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
[1712] Fix | Delete
break;
[1713] Fix | Delete
[1714] Fix | Delete
case 'meta': // METAdata atom
[1715] Fix | Delete
// https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
[1716] Fix | Delete
[1717] Fix | Delete
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
[1718] Fix | Delete
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
[1719] Fix | Delete
$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
[1720] Fix | Delete
break;
[1721] Fix | Delete
[1722] Fix | Delete
case 'data': // metaDATA atom
[1723] Fix | Delete
static $metaDATAkey = 1; // real ugly, but so is the QuickTime structure that stores keys and values in different multinested locations that are hard to relate to each other
[1724] Fix | Delete
// seems to be 2 bytes language code (ASCII), 2 bytes unknown (set to 0x10B5 in sample I have), remainder is useful data
[1725] Fix | Delete
$atom_structure['language'] = substr($atom_data, 4 + 0, 2);
[1726] Fix | Delete
$atom_structure['unknown'] = getid3_lib::BigEndian2Int(substr($atom_data, 4 + 2, 2));
[1727] Fix | Delete
$atom_structure['data'] = substr($atom_data, 4 + 4);
[1728] Fix | Delete
$atom_structure['key_name'] = (isset($info['quicktime']['temp_meta_key_names'][$metaDATAkey]) ? $info['quicktime']['temp_meta_key_names'][$metaDATAkey] : '');
[1729] Fix | Delete
$metaDATAkey++;
[1730] Fix | Delete
[1731] Fix | Delete
if ($atom_structure['key_name'] && $atom_structure['data']) {
[1732] Fix | Delete
@$info['quicktime']['comments'][str_replace('com.apple.quicktime.', '', $atom_structure['key_name'])][] = $atom_structure['data'];
[1733] Fix | Delete
}
[1734] Fix | Delete
break;
[1735] Fix | Delete
[1736] Fix | Delete
case 'keys': // KEYS that may be present in the metadata atom.
[1737] Fix | Delete
// https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW21
[1738] Fix | Delete
// The metadata item keys atom holds a list of the metadata keys that may be present in the metadata atom.
[1739] Fix | Delete
// This list is indexed starting with 1; 0 is a reserved index value. The metadata item keys atom is a full atom with an atom type of "keys".
[1740] Fix | Delete
$atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
[1741] Fix | Delete
$atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
[1742] Fix | Delete
$atom_structure['entry_count'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4));
[1743] Fix | Delete
$keys_atom_offset = 8;
[1744] Fix | Delete
for ($i = 1; $i <= $atom_structure['entry_count']; $i++) {
[1745] Fix | Delete
$atom_structure['keys'][$i]['key_size'] = getid3_lib::BigEndian2Int(substr($atom_data, $keys_atom_offset + 0, 4));
[1746] Fix | Delete
$atom_structure['keys'][$i]['key_namespace'] = substr($atom_data, $keys_atom_offset + 4, 4);
[1747] Fix | Delete
$atom_structure['keys'][$i]['key_value'] = substr($atom_data, $keys_atom_offset + 8, $atom_structure['keys'][$i]['key_size'] - 8);
[1748] Fix | Delete
$keys_atom_offset += $atom_structure['keys'][$i]['key_size']; // key_size includes the 4+4 bytes for key_size and key_namespace
[1749] Fix | Delete
[1750] Fix | Delete
$info['quicktime']['temp_meta_key_names'][$i] = $atom_structure['keys'][$i]['key_value'];
[1751] Fix | Delete
}
[1752] Fix | Delete
break;
[1753] Fix | Delete
[1754] Fix | Delete
case 'uuid': // user-defined atom often seen containing XML data, also used for potentially many other purposes, only a few specifically handled by getID3 (e.g. 360fly spatial data)
[1755] Fix | Delete
//Get the UUID ID in first 16 bytes
[1756] Fix | Delete
$uuid_bytes_read = unpack('H8time_low/H4time_mid/H4time_hi/H4clock_seq_hi/H12clock_seq_low', substr($atom_data, 0, 16));
[1757] Fix | Delete
$atom_structure['uuid_field_id'] = implode('-', $uuid_bytes_read);
[1758] Fix | Delete
[1759] Fix | Delete
switch ($atom_structure['uuid_field_id']) { // http://fileformats.archiveteam.org/wiki/Boxes/atoms_format#UUID_boxes
[1760] Fix | Delete
[1761] Fix | Delete
case '0537cdab-9d0c-4431-a72a-fa561f2a113e': // Exif - http://fileformats.archiveteam.org/wiki/Exif
[1762] Fix | Delete
case '2c4c0100-8504-40b9-a03e-562148d6dfeb': // Photoshop Image Resources - http://fileformats.archiveteam.org/wiki/Photoshop_Image_Resources
[1763] Fix | Delete
case '33c7a4d2-b81d-4723-a0ba-f1a3e097ad38': // IPTC-IIM - http://fileformats.archiveteam.org/wiki/IPTC-IIM
[1764] Fix | Delete
case '8974dbce-7be7-4c51-84f9-7148f9882554': // PIFF Track Encryption Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format
[1765] Fix | Delete
case '96a9f1f1-dc98-402d-a7ae-d68e34451809': // GeoJP2 World File Box - http://fileformats.archiveteam.org/wiki/GeoJP2
[1766] Fix | Delete
case 'a2394f52-5a9b-4f14-a244-6c427c648df4': // PIFF Sample Encryption Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format
[1767] Fix | Delete
case 'b14bf8bd-083d-4b43-a5ae-8cd7d5a6ce03': // GeoJP2 GeoTIFF Box - http://fileformats.archiveteam.org/wiki/GeoJP2
[1768] Fix | Delete
case 'd08a4f18-10f3-4a82-b6c8-32d8aba183d3': // PIFF Protection System Specific Header Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format
[1769] Fix | Delete
$this->warning('Unhandled (but recognized) "uuid" atom identified by "'.$atom_structure['uuid_field_id'].'" at offset '.$atom_structure['offset'].' ('.strlen($atom_data).' bytes)');
[1770] Fix | Delete
break;
[1771] Fix | Delete
[1772] Fix | Delete
case 'be7acfcb-97a9-42e8-9c71-999491e3afac': // XMP data (in XML format)
[1773] Fix | Delete
$atom_structure['xml'] = substr($atom_data, 16, strlen($atom_data) - 16 - 8); // 16 bytes for UUID, 8 bytes header(?)
[1774] Fix | Delete
break;
[1775] Fix | Delete
[1776] Fix | Delete
case 'efe1589a-bb77-49ef-8095-27759eb1dc6f': // 360fly data
[1777] Fix | Delete
/* 360fly code in this block by Paul Lewis 2019-Oct-31 */
[1778] Fix | Delete
/* Sensor Timestamps need to be calculated using the recordings base time at ['quicktime']['moov']['subatoms'][0]['creation_time_unix']. */
[1779] Fix | Delete
$atom_structure['title'] = '360Fly Sensor Data';
[1780] Fix | Delete
[1781] Fix | Delete
//Get the UUID HEADER data
[1782] Fix | Delete
$uuid_bytes_read = unpack('vheader_size/vheader_version/vtimescale/vhardware_version/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/', substr($atom_data, 16, 32));
[1783] Fix | Delete
$atom_structure['uuid_header'] = $uuid_bytes_read;
[1784] Fix | Delete
[1785] Fix | Delete
$start_byte = 48;
[1786] Fix | Delete
$atom_SENSOR_data = substr($atom_data, $start_byte);
[1787] Fix | Delete
$atom_structure['sensor_data']['data_type'] = array(
[1788] Fix | Delete
'fusion_count' => 0, // ID 250
[1789] Fix | Delete
'fusion_data' => array(),
[1790] Fix | Delete
'accel_count' => 0, // ID 1
[1791] Fix | Delete
'accel_data' => array(),
[1792] Fix | Delete
'gyro_count' => 0, // ID 2
[1793] Fix | Delete
'gyro_data' => array(),
[1794] Fix | Delete
'magno_count' => 0, // ID 3
[1795] Fix | Delete
'magno_data' => array(),
[1796] Fix | Delete
'gps_count' => 0, // ID 5
[1797] Fix | Delete
'gps_data' => array(),
[1798] Fix | Delete
'rotation_count' => 0, // ID 6
[1799] Fix | Delete
'rotation_data' => array(),
[1800] Fix | Delete
'unknown_count' => 0, // ID ??
[1801] Fix | Delete
'unknown_data' => array(),
[1802] Fix | Delete
'debug_list' => '', // Used to debug variables stored as comma delimited strings
[1803] Fix | Delete
);
[1804] Fix | Delete
$debug_structure = array();
[1805] Fix | Delete
$debug_structure['debug_items'] = array();
[1806] Fix | Delete
// Can start loop here to decode all sensor data in 32 Byte chunks:
[1807] Fix | Delete
foreach (str_split($atom_SENSOR_data, 32) as $sensor_key => $sensor_data) {
[1808] Fix | Delete
// This gets me a data_type code to work out what data is in the next 31 bytes.
[1809] Fix | Delete
$sensor_data_type = substr($sensor_data, 0, 1);
[1810] Fix | Delete
$sensor_data_content = substr($sensor_data, 1);
[1811] Fix | Delete
$uuid_bytes_read = unpack('C*', $sensor_data_type);
[1812] Fix | Delete
$sensor_data_array = array();
[1813] Fix | Delete
switch ($uuid_bytes_read[1]) {
[1814] Fix | Delete
case 250:
[1815] Fix | Delete
$atom_structure['sensor_data']['data_type']['fusion_count']++;
[1816] Fix | Delete
$uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
[1817] Fix | Delete
$sensor_data_array['mode'] = $uuid_bytes_read['mode'];
[1818] Fix | Delete
$sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
[1819] Fix | Delete
$sensor_data_array['yaw'] = $uuid_bytes_read['yaw'];
[1820] Fix | Delete
$sensor_data_array['pitch'] = $uuid_bytes_read['pitch'];
[1821] Fix | Delete
$sensor_data_array['roll'] = $uuid_bytes_read['roll'];
[1822] Fix | Delete
array_push($atom_structure['sensor_data']['data_type']['fusion_data'], $sensor_data_array);
[1823] Fix | Delete
break;
[1824] Fix | Delete
case 1:
[1825] Fix | Delete
$atom_structure['sensor_data']['data_type']['accel_count']++;
[1826] Fix | Delete
$uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
[1827] Fix | Delete
$sensor_data_array['mode'] = $uuid_bytes_read['mode'];
[1828] Fix | Delete
$sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
[1829] Fix | Delete
$sensor_data_array['yaw'] = $uuid_bytes_read['yaw'];
[1830] Fix | Delete
$sensor_data_array['pitch'] = $uuid_bytes_read['pitch'];
[1831] Fix | Delete
$sensor_data_array['roll'] = $uuid_bytes_read['roll'];
[1832] Fix | Delete
array_push($atom_structure['sensor_data']['data_type']['accel_data'], $sensor_data_array);
[1833] Fix | Delete
break;
[1834] Fix | Delete
case 2:
[1835] Fix | Delete
$atom_structure['sensor_data']['data_type']['gyro_count']++;
[1836] Fix | Delete
$uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
[1837] Fix | Delete
$sensor_data_array['mode'] = $uuid_bytes_read['mode'];
[1838] Fix | Delete
$sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
[1839] Fix | Delete
$sensor_data_array['yaw'] = $uuid_bytes_read['yaw'];
[1840] Fix | Delete
$sensor_data_array['pitch'] = $uuid_bytes_read['pitch'];
[1841] Fix | Delete
$sensor_data_array['roll'] = $uuid_bytes_read['roll'];
[1842] Fix | Delete
array_push($atom_structure['sensor_data']['data_type']['gyro_data'], $sensor_data_array);
[1843] Fix | Delete
break;
[1844] Fix | Delete
case 3:
[1845] Fix | Delete
$atom_structure['sensor_data']['data_type']['magno_count']++;
[1846] Fix | Delete
$uuid_bytes_read = unpack('cmode/Jtimestamp/Gmagx/Gmagy/Gmagz/x*', $sensor_data_content);
[1847] Fix | Delete
$sensor_data_array['mode'] = $uuid_bytes_read['mode'];
[1848] Fix | Delete
$sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
[1849] Fix | Delete
$sensor_data_array['magx'] = $uuid_bytes_read['magx'];
[1850] Fix | Delete
$sensor_data_array['magy'] = $uuid_bytes_read['magy'];
[1851] Fix | Delete
$sensor_data_array['magz'] = $uuid_bytes_read['magz'];
[1852] Fix | Delete
array_push($atom_structure['sensor_data']['data_type']['magno_data'], $sensor_data_array);
[1853] Fix | Delete
break;
[1854] Fix | Delete
case 5:
[1855] Fix | Delete
$atom_structure['sensor_data']['data_type']['gps_count']++;
[1856] Fix | Delete
$uuid_bytes_read = unpack('cmode/Jtimestamp/Glat/Glon/Galt/Gspeed/nbearing/nacc/x*', $sensor_data_content);
[1857] Fix | Delete
$sensor_data_array['mode'] = $uuid_bytes_read['mode'];
[1858] Fix | Delete
$sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
[1859] Fix | Delete
$sensor_data_array['lat'] = $uuid_bytes_read['lat'];
[1860] Fix | Delete
$sensor_data_array['lon'] = $uuid_bytes_read['lon'];
[1861] Fix | Delete
$sensor_data_array['alt'] = $uuid_bytes_read['alt'];
[1862] Fix | Delete
$sensor_data_array['speed'] = $uuid_bytes_read['speed'];
[1863] Fix | Delete
$sensor_data_array['bearing'] = $uuid_bytes_read['bearing'];
[1864] Fix | Delete
$sensor_data_array['acc'] = $uuid_bytes_read['acc'];
[1865] Fix | Delete
array_push($atom_structure['sensor_data']['data_type']['gps_data'], $sensor_data_array);
[1866] Fix | Delete
//array_push($debug_structure['debug_items'], $uuid_bytes_read['timestamp']);
[1867] Fix | Delete
break;
[1868] Fix | Delete
case 6:
[1869] Fix | Delete
$atom_structure['sensor_data']['data_type']['rotation_count']++;
[1870] Fix | Delete
$uuid_bytes_read = unpack('cmode/Jtimestamp/Grotx/Groty/Grotz/x*', $sensor_data_content);
[1871] Fix | Delete
$sensor_data_array['mode'] = $uuid_bytes_read['mode'];
[1872] Fix | Delete
$sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
[1873] Fix | Delete
$sensor_data_array['rotx'] = $uuid_bytes_read['rotx'];
[1874] Fix | Delete
$sensor_data_array['roty'] = $uuid_bytes_read['roty'];
[1875] Fix | Delete
$sensor_data_array['rotz'] = $uuid_bytes_read['rotz'];
[1876] Fix | Delete
array_push($atom_structure['sensor_data']['data_type']['rotation_data'], $sensor_data_array);
[1877] Fix | Delete
break;
[1878] Fix | Delete
default:
[1879] Fix | Delete
$atom_structure['sensor_data']['data_type']['unknown_count']++;
[1880] Fix | Delete
break;
[1881] Fix | Delete
}
[1882] Fix | Delete
}
[1883] Fix | Delete
//if (isset($debug_structure['debug_items']) && count($debug_structure['debug_items']) > 0) {
[1884] Fix | Delete
// $atom_structure['sensor_data']['data_type']['debug_list'] = implode(',', $debug_structure['debug_items']);
[1885] Fix | Delete
//} else {
[1886] Fix | Delete
$atom_structure['sensor_data']['data_type']['debug_list'] = 'No debug items in list!';
[1887] Fix | Delete
//}
[1888] Fix | Delete
break;
[1889] Fix | Delete
[1890] Fix | Delete
default:
[1891] Fix | Delete
$this->warning('Unhandled "uuid" atom identified by "'.$atom_structure['uuid_field_id'].'" at offset '.$atom_structure['offset'].' ('.strlen($atom_data).' bytes)');
[1892] Fix | Delete
}
[1893] Fix | Delete
break;
[1894] Fix | Delete
[1895] Fix | Delete
case 'gps ':
[1896] Fix | Delete
// https://dashcamtalk.com/forum/threads/script-to-extract-gps-data-from-novatek-mp4.20808/page-2#post-291730
[1897] Fix | Delete
// The 'gps ' contains simple look up table made up of 8byte rows, that point to the 'free' atoms that contains the actual GPS data.
[1898] Fix | Delete
// The first row is version/metadata/notsure, I skip that.
[1899] Fix | Delete
// The following rows consist of 4byte address (absolute) and 4byte size (0x1000), these point to the GPS data in the file.
[1900] Fix | Delete
[1901] Fix | Delete
$GPS_rowsize = 8; // 4 bytes for offset, 4 bytes for size
[1902] Fix | Delete
if (strlen($atom_data) > 0) {
[1903] Fix | Delete
if ((strlen($atom_data) % $GPS_rowsize) == 0) {
[1904] Fix | Delete
$atom_structure['gps_toc'] = array();
[1905] Fix | Delete
foreach (str_split($atom_data, $GPS_rowsize) as $counter => $datapair) {
[1906] Fix | Delete
$atom_structure['gps_toc'][] = unpack('Noffset/Nsize', substr($atom_data, $counter * $GPS_rowsize, $GPS_rowsize));
[1907] Fix | Delete
}
[1908] Fix | Delete
[1909] Fix | Delete
$atom_structure['gps_entries'] = array();
[1910] Fix | Delete
$previous_offset = $this->ftell();
[1911] Fix | Delete
foreach ($atom_structure['gps_toc'] as $key => $gps_pointer) {
[1912] Fix | Delete
if ($key == 0) {
[1913] Fix | Delete
// "The first row is version/metadata/notsure, I skip that."
[1914] Fix | Delete
continue;
[1915] Fix | Delete
}
[1916] Fix | Delete
$this->fseek($gps_pointer['offset']);
[1917] Fix | Delete
$GPS_free_data = $this->fread($gps_pointer['size']);
[1918] Fix | Delete
[1919] Fix | Delete
/*
[1920] Fix | Delete
// 2017-05-10: I see some of the data, notably the Hour-Minute-Second, but cannot reconcile the rest of the data. However, the NMEA "GPRMC" line is there and relatively easy to parse, so I'm using that instead
[1921] Fix | Delete
[1922] Fix | Delete
// https://dashcamtalk.com/forum/threads/script-to-extract-gps-data-from-novatek-mp4.20808/page-2#post-291730
[1923] Fix | Delete
// The structure of the GPS data atom (the 'free' atoms mentioned above) is following:
[1924] Fix | Delete
// hour,minute,second,year,month,day,active,latitude_b,longitude_b,unknown2,latitude,longitude,speed = struct.unpack_from('<IIIIIIssssfff',data, 48)
[1925] Fix | Delete
// For those unfamiliar with python struct:
[1926] Fix | Delete
// I = int
[1927] Fix | Delete
// s = is string (size 1, in this case)
[1928] Fix | Delete
// f = float
[1929] Fix | Delete
[1930] Fix | Delete
//$atom_structure['gps_entries'][$key] = unpack('Vhour/Vminute/Vsecond/Vyear/Vmonth/Vday/Vactive/Vlatitude_b/Vlongitude_b/Vunknown2/flatitude/flongitude/fspeed', substr($GPS_free_data, 48));
[1931] Fix | Delete
*/
[1932] Fix | Delete
[1933] Fix | Delete
// $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
[1934] Fix | Delete
// $GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,080301,015.5,E*67
[1935] Fix | Delete
// $GPRMC,002454,A,3553.5295,N,13938.6570,E,0.0,43.1,180700,7.1,W,A*3F
[1936] Fix | Delete
// $GPRMC,094347.000,A,5342.0061,N,00737.9908,W,0.01,156.75,140217,,,A*7D
[1937] Fix | Delete
if (preg_match('#\\$GPRMC,([0-9\\.]*),([AV]),([0-9\\.]*),([NS]),([0-9\\.]*),([EW]),([0-9\\.]*),([0-9\\.]*),([0-9]*),([0-9\\.]*),([EW]?)(,[A])?(\\*[0-9A-F]{2})#', $GPS_free_data, $matches)) {
[1938] Fix | Delete
$GPS_this_GPRMC = array();
[1939] Fix | Delete
$GPS_this_GPRMC_raw = array();
[1940] Fix | Delete
list(
[1941] Fix | Delete
$GPS_this_GPRMC_raw['gprmc'],
[1942] Fix | Delete
$GPS_this_GPRMC_raw['timestamp'],
[1943] Fix | Delete
$GPS_this_GPRMC_raw['status'],
[1944] Fix | Delete
$GPS_this_GPRMC_raw['latitude'],
[1945] Fix | Delete
$GPS_this_GPRMC_raw['latitude_direction'],
[1946] Fix | Delete
$GPS_this_GPRMC_raw['longitude'],
[1947] Fix | Delete
$GPS_this_GPRMC_raw['longitude_direction'],
[1948] Fix | Delete
$GPS_this_GPRMC_raw['knots'],
[1949] Fix | Delete
$GPS_this_GPRMC_raw['angle'],
[1950] Fix | Delete
$GPS_this_GPRMC_raw['datestamp'],
[1951] Fix | Delete
$GPS_this_GPRMC_raw['variation'],
[1952] Fix | Delete
$GPS_this_GPRMC_raw['variation_direction'],
[1953] Fix | Delete
$dummy,
[1954] Fix | Delete
$GPS_this_GPRMC_raw['checksum'],
[1955] Fix | Delete
) = $matches;
[1956] Fix | Delete
$GPS_this_GPRMC['raw'] = $GPS_this_GPRMC_raw;
[1957] Fix | Delete
[1958] Fix | Delete
$hour = substr($GPS_this_GPRMC['raw']['timestamp'], 0, 2);
[1959] Fix | Delete
$minute = substr($GPS_this_GPRMC['raw']['timestamp'], 2, 2);
[1960] Fix | Delete
$second = substr($GPS_this_GPRMC['raw']['timestamp'], 4, 2);
[1961] Fix | Delete
$ms = substr($GPS_this_GPRMC['raw']['timestamp'], 6); // may contain decimal seconds
[1962] Fix | Delete
$day = substr($GPS_this_GPRMC['raw']['datestamp'], 0, 2);
[1963] Fix | Delete
$month = substr($GPS_this_GPRMC['raw']['datestamp'], 2, 2);
[1964] Fix | Delete
$year = (int) substr($GPS_this_GPRMC['raw']['datestamp'], 4, 2);
[1965] Fix | Delete
$year += (($year > 90) ? 1900 : 2000); // complete lack of foresight: datestamps are stored with 2-digit years, take best guess
[1966] Fix | Delete
$GPS_this_GPRMC['timestamp'] = $year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second.$ms;
[1967] Fix | Delete
[1968] Fix | Delete
$GPS_this_GPRMC['active'] = ($GPS_this_GPRMC['raw']['status'] == 'A'); // A=Active,V=Void
[1969] Fix | Delete
[1970] Fix | Delete
foreach (array('latitude','longitude') as $latlon) {
[1971] Fix | Delete
preg_match('#^([0-9]{1,3})([0-9]{2}\\.[0-9]+)$#', $GPS_this_GPRMC['raw'][$latlon], $matches);
[1972] Fix | Delete
list($dummy, $deg, $min) = $matches;
[1973] Fix | Delete
$GPS_this_GPRMC[$latlon] = $deg + ($min / 60);
[1974] Fix | Delete
}
[1975] Fix | Delete
$GPS_this_GPRMC['latitude'] *= (($GPS_this_GPRMC['raw']['latitude_direction'] == 'S') ? -1 : 1);
[1976] Fix | Delete
$GPS_this_GPRMC['longitude'] *= (($GPS_this_GPRMC['raw']['longitude_direction'] == 'W') ? -1 : 1);
[1977] Fix | Delete
[1978] Fix | Delete
$GPS_this_GPRMC['heading'] = $GPS_this_GPRMC['raw']['angle'];
[1979] Fix | Delete
$GPS_this_GPRMC['speed_knot'] = $GPS_this_GPRMC['raw']['knots'];
[1980] Fix | Delete
$GPS_this_GPRMC['speed_kmh'] = $GPS_this_GPRMC['raw']['knots'] * 1.852;
[1981] Fix | Delete
if ($GPS_this_GPRMC['raw']['variation']) {
[1982] Fix | Delete
$GPS_this_GPRMC['variation'] = $GPS_this_GPRMC['raw']['variation'];
[1983] Fix | Delete
$GPS_this_GPRMC['variation'] *= (($GPS_this_GPRMC['raw']['variation_direction'] == 'W') ? -1 : 1);
[1984] Fix | Delete
}
[1985] Fix | Delete
[1986] Fix | Delete
$atom_structure['gps_entries'][$key] = $GPS_this_GPRMC;
[1987] Fix | Delete
[1988] Fix | Delete
@$info['quicktime']['gps_track'][$GPS_this_GPRMC['timestamp']] = array(
[1989] Fix | Delete
'latitude' => (float) $GPS_this_GPRMC['latitude'],
[1990] Fix | Delete
'longitude' => (float) $GPS_this_GPRMC['longitude'],
[1991] Fix | Delete
'speed_kmh' => (float) $GPS_this_GPRMC['speed_kmh'],
[1992] Fix | Delete
'heading' => (float) $GPS_this_GPRMC['heading'],
[1993] Fix | Delete
);
[1994] Fix | Delete
[1995] Fix | Delete
} else {
[1996] Fix | Delete
$this->warning('Unhandled GPS format in "free" atom at offset '.$gps_pointer['offset']);
[1997] Fix | Delete
}
[1998] Fix | Delete
}
[1999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function