: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$descriptionRecord['name_length'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$descriptionRecord['data_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$descriptionRecord['data_type_text'] = self::metadataLibraryObjectDataTypeLookup($descriptionRecord['data_type']);
$descriptionRecord['data_length'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
$descriptionRecord['name'] = substr($asf_header_extension_object_data, $offset, $descriptionRecord['name_length']);
$offset += $descriptionRecord['name_length'];
$descriptionRecord['data'] = substr($asf_header_extension_object_data, $offset, $descriptionRecord['data_length']);
$offset += $descriptionRecord['data_length'];
if (preg_match('#^WM/Picture$#', str_replace("\x00", '', trim($descriptionRecord['name'])))) {
$WMpicture = $this->ASF_WMpicture($descriptionRecord['data']);
foreach ($WMpicture as $key => $value) {
$descriptionRecord['data'] = $WMpicture;
$thisObject['description_record'][$i] = $descriptionRecord;
case GETID3_ASF_Index_Parameters_Object:
$thisObject['index_entry_time_interval'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
$thisObject['index_specifiers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
for ($i = 0; $i < $thisObject['index_specifiers_count']; $i++) {
$indexSpecifier = array();
$indexSpecifier['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$indexSpecifier['index_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$indexSpecifier['index_type_text'] = isset(static::$ASFIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']])
? static::$ASFIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']]
$thisObject['index_specifiers'][$i] = $indexSpecifier;
case GETID3_ASF_Media_Object_Index_Parameters_Object:
$thisObject['index_entry_count_interval'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
$thisObject['index_specifiers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
for ($i = 0; $i < $thisObject['index_specifiers_count']; $i++) {
$indexSpecifier = array();
$indexSpecifier['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$indexSpecifier['index_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$indexSpecifier['index_type_text'] = isset(static::$ASFMediaObjectIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']])
? static::$ASFMediaObjectIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']]
$thisObject['index_specifiers'][$i] = $indexSpecifier;
case GETID3_ASF_Timecode_Index_Parameters_Object:
// 4.11 Timecode Index Parameters Object (mandatory only if TIMECODE index is present in file, 0 or 1)
// Field name Field type Size (bits)
// Object ID GUID 128 // GUID for the Timecode Index Parameters Object - ASF_Timecode_Index_Parameters_Object
// Object Size QWORD 64 // Specifies the size, in bytes, of the Timecode Index Parameters Object. Valid values are at least 34 bytes.
// Index Entry Count Interval DWORD 32 // This value is ignored for the Timecode Index Parameters Object.
// Index Specifiers Count WORD 16 // Specifies the number of entries in the Index Specifiers list. Valid values are 1 and greater.
// Index Specifiers array of: varies //
// * Stream Number WORD 16 // Specifies the stream number that the Index Specifiers refer to. Valid values are between 1 and 127.
// * Index Type WORD 16 // Specifies the type of index. Values are defined as follows (1 is not a valid value):
// 2 = Nearest Past Media Object - indexes point to the closest data packet containing an entire video frame or the first fragment of a video frame
// 3 = Nearest Past Cleanpoint - indexes point to the closest data packet containing an entire video frame (or first fragment of a video frame) that is a key frame.
// Nearest Past Media Object is the most common value
$thisObject['index_entry_count_interval'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 4));
$thisObject['index_specifiers_count'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
for ($i = 0; $i < $thisObject['index_specifiers_count']; $i++) {
$indexSpecifier = array();
$indexSpecifier['stream_number'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$indexSpecifier['index_type'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 2));
$indexSpecifier['index_type_text'] = isset(static::$ASFTimecodeIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']])
? static::$ASFTimecodeIndexParametersObjectIndexSpecifiersIndexTypes[$indexSpecifier['index_type']]
$thisObject['index_specifiers'][$i] = $indexSpecifier;
case GETID3_ASF_Compatibility_Object:
$thisObject['profile'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 1));
$thisObject['mode'] = getid3_lib::LittleEndian2Int(substr($asf_header_extension_object_data, $offset, 1));
if ($this->GUIDname($thisObject['guid_text'])) {
$this->warning('unhandled Header Extension Object GUID "'.$this->GUIDname($thisObject['guid_text']).'" {'.$thisObject['guid_text'].'} at offset '.($offset - 16 - 8));
$this->warning('unknown Header Extension Object GUID {'.$thisObject['guid_text'].'} in at offset '.($offset - 16 - 8));
$HeaderExtensionObjectParsed[] = $thisObject;
$objectOffset += $thisObject['size'];
return $HeaderExtensionObjectParsed;
public static function metadataLibraryObjectDataTypeLookup($id) {
0x0000 => 'Unicode string', // The data consists of a sequence of Unicode characters
0x0001 => 'BYTE array', // The type of the data is implementation-specific
0x0002 => 'BOOL', // The data is 2 bytes long and should be interpreted as a 16-bit unsigned integer. Only 0x0000 or 0x0001 are permitted values
0x0003 => 'DWORD', // The data is 4 bytes long and should be interpreted as a 32-bit unsigned integer
0x0004 => 'QWORD', // The data is 8 bytes long and should be interpreted as a 64-bit unsigned integer
0x0005 => 'WORD', // The data is 2 bytes long and should be interpreted as a 16-bit unsigned integer
0x0006 => 'GUID', // The data is 16 bytes long and should be interpreted as a 128-bit GUID
return (isset($lookup[$id]) ? $lookup[$id] : 'invalid');
public function ASF_WMpicture(&$data) {
//typedef struct _WMPicture{
// LPWSTR pwszDescription;
$WMpicture['image_type_id'] = getid3_lib::LittleEndian2Int(substr($data, $offset, 1));
$WMpicture['image_type'] = self::WMpictureTypeLookup($WMpicture['image_type_id']);
$WMpicture['image_size'] = getid3_lib::LittleEndian2Int(substr($data, $offset, 4));
$WMpicture['image_mime'] = '';
$next_byte_pair = substr($data, $offset, 2);
$WMpicture['image_mime'] .= $next_byte_pair;
} while ($next_byte_pair !== "\x00\x00");
$WMpicture['image_description'] = '';
$next_byte_pair = substr($data, $offset, 2);
$WMpicture['image_description'] .= $next_byte_pair;
} while ($next_byte_pair !== "\x00\x00");
$WMpicture['dataoffset'] = $offset;
$WMpicture['data'] = substr($data, $offset);
$WMpicture['image_mime'] = '';
$imagechunkcheck = getid3_lib::GetDataImageSize($WMpicture['data'], $imageinfo);
if (!empty($imagechunkcheck)) {
$WMpicture['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
if (!isset($this->getid3->info['asf']['comments']['picture'])) {
$this->getid3->info['asf']['comments']['picture'] = array();
$this->getid3->info['asf']['comments']['picture'][] = array('data'=>$WMpicture['data'], 'image_mime'=>$WMpicture['image_mime']);
* Remove terminator 00 00 and convert UTF-16LE to Latin-1.
public static function TrimConvert($string) {
return trim(getid3_lib::iconv_fallback('UTF-16LE', 'ISO-8859-1', self::TrimTerm($string)), ' ');
* Remove terminator 00 00.
public static function TrimTerm($string) {
// remove terminator, only if present (it should be, but...)
if (substr($string, -2) === "\x00\x00") {
$string = substr($string, 0, -2);