function FormatDataForID3v2($id3v2_majorversion) { $tag_data_id3v2 = array(); $ID3v2_text_encoding_lookup[2] = array('ISO-8859-1' => 0, 'UTF-16' => 1); $ID3v2_text_encoding_lookup[3] = array('ISO-8859-1' => 0, 'UTF-16' => 1); $ID3v2_text_encoding_lookup[4] = array('ISO-8859-1' => 0, 'UTF-16' => 1, 'UTF-16BE' => 2, 'UTF-8' => 3); foreach ($this->tag_data as $tag_key => $valuearray) { $ID3v2_framename = getid3_write_id3v2::ID3v2ShortFrameNameLookup($id3v2_majorversion, $tag_key); switch ($ID3v2_framename) { case 'APIC': foreach ($valuearray as $key => $apic_data_array) { if (isset($apic_data_array['data']) && isset($apic_data_array['picturetypeid']) && isset($apic_data_array['description']) && isset($apic_data_array['mime'])) { $tag_data_id3v2['APIC'][] = $apic_data_array; } else { $this->errors[] = 'ID3v2 APIC data is not properly structured'; return false; } } break; case '': $this->errors[] = 'ID3v2: Skipping "' . $tag_key . '" because cannot match it to a known ID3v2 frame type'; // some other data type, don't know how to handle it, ignore it break; default: // most other (text) frames can be copied over as-is foreach ($valuearray as $key => $value) { if (isset($ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding])) { // source encoding is valid in ID3v2 - use it with no conversion $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = $ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding]; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = $value; } else { // source encoding is NOT valid in ID3v2 - convert it to an ID3v2-valid encoding first if ($id3v2_majorversion < 4) { // convert data from other encoding to UTF-16 $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 1; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-16', $value); } else { // convert data from other encoding to UTF-8 $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 3; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-8', $value); } } // These values are not needed for all frame types, but if they're not used no matter $tag_data_id3v2[$ID3v2_framename][$key]['description'] = ''; $tag_data_id3v2[$ID3v2_framename][$key]['language'] = $this->id3v2_tag_language; } break; } } $this->MergeExistingTagData('id3v2', $tag_data_id3v2); return $tag_data_id3v2; }
function FormatDataForID3v2($id3v2_majorversion) { $tag_data_id3v2 = array(); $ID3v2_text_encoding_lookup[2] = array('ISO-8859-1' => 0, 'UTF-16' => 1); $ID3v2_text_encoding_lookup[3] = array('ISO-8859-1' => 0, 'UTF-16' => 1); $ID3v2_text_encoding_lookup[4] = array('ISO-8859-1' => 0, 'UTF-16' => 1, 'UTF-16BE' => 2, 'UTF-8' => 3); foreach ($this->tag_data as $tag_key => $valuearray) { $ID3v2_framename = getid3_write_id3v2::ID3v2ShortFrameNameLookup($id3v2_majorversion, $tag_key); switch ($ID3v2_framename) { case 'APIC': foreach ($valuearray as $key => $apic_data_array) { if (isset($apic_data_array['data']) && isset($apic_data_array['picturetypeid']) && isset($apic_data_array['description']) && isset($apic_data_array['mime'])) { $tag_data_id3v2['APIC'][] = $apic_data_array; } else { $this->errors[] = 'ID3v2 APIC data is not properly structured'; return false; } } break; case '': $this->errors[] = 'ID3v2: Skipping "' . $tag_key . '" because cannot match it to a known ID3v2 frame type'; // some other data type, don't know how to handle it, ignore it break; default: // most other (text) frames can be copied over as-is foreach ($valuearray as $key => $value) { if (isset($ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding])) { // source encoding is valid in ID3v2 - use it with no conversion $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = $ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding]; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = $value; } else { // source encoding is NOT valid in ID3v2 - convert it to an ID3v2-valid encoding first if ($id3v2_majorversion < 4) { // convert data from other encoding to UTF-16 (with BOM) // note: some software, notably Windows Media Player and iTunes are broken and treat files tagged with UTF-16BE (with BOM) as corrupt // therefore we force data to UTF-16LE and manually prepend the BOM $ID3v2_tag_data_converted = false; if (!$ID3v2_tag_data_converted && $this->tag_encoding == 'ISO-8859-1') { // great, leave data as-is for minimum compatability problems $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 0; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = $value; $ID3v2_tag_data_converted = true; } if (!$ID3v2_tag_data_converted && $this->tag_encoding == 'UTF-8') { do { // if UTF-8 string does not include any characters above chr(127) then it is identical to ISO-8859-1 for ($i = 0; $i < strlen($value); $i++) { if (ord($value[$i]) > 127) { break 2; } } $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 0; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = $value; $ID3v2_tag_data_converted = true; } while (false); } if (!$ID3v2_tag_data_converted) { $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 1; //$tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-16', $value); // output is UTF-16LE+BOM or UTF-16BE+BOM depending on system architecture $tag_data_id3v2[$ID3v2_framename][$key]['data'] = "ÿþ" . getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-16LE', $value); // force LittleEndian order version of UTF-16 $ID3v2_tag_data_converted = true; } } else { // convert data from other encoding to UTF-8 $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 3; $tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-8', $value); } } // These values are not needed for all frame types, but if they're not used no matter $tag_data_id3v2[$ID3v2_framename][$key]['description'] = ''; $tag_data_id3v2[$ID3v2_framename][$key]['language'] = $this->id3v2_tag_language; } break; } } $this->MergeExistingTagData('id3v2', $tag_data_id3v2); return $tag_data_id3v2; }