PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/zina/extras/getid3/write.php

https://bitbucket.org/helmespc/zina2
PHP | 606 lines | 469 code | 74 blank | 63 comment | 83 complexity | 9acbd0d8a60d03a3efc327e2eb1272b7 MD5 | raw file
  1. <?php
  2. /////////////////////////////////////////////////////////////////
  3. /// getID3() by James Heinrich <info@getid3.org> //
  4. // available at http://getid3.sourceforge.net //
  5. // or http://www.getid3.org //
  6. /////////////////////////////////////////////////////////////////
  7. // See readme.txt for more details //
  8. /////////////////////////////////////////////////////////////////
  9. /// //
  10. // write.php //
  11. // module for writing tags (APEv2, ID3v1, ID3v2) //
  12. // dependencies: getid3.lib.php //
  13. // write.apetag.php (optional) //
  14. // write.id3v1.php (optional) //
  15. // write.id3v2.php (optional) //
  16. // write.vorbiscomment.php (optional) //
  17. // write.metaflac.php (optional) //
  18. // write.lyrics3.php (optional) //
  19. // ///
  20. /////////////////////////////////////////////////////////////////
  21. if (!defined('GETID3_INCLUDEPATH')) {
  22. die('getid3.php MUST be included before calling getid3_writetags');
  23. }
  24. if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) {
  25. die('write.php depends on getid3.lib.php, which is missing.');
  26. }
  27. // NOTES:
  28. //
  29. // You should pass data here with standard field names as follows:
  30. // * TITLE
  31. // * ARTIST
  32. // * ALBUM
  33. // * TRACKNUMBER
  34. // * COMMENT
  35. // * GENRE
  36. // * YEAR
  37. // * ATTACHED_PICTURE (ID3v2 only)
  38. //
  39. // http://www.personal.uni-jena.de/~pfk/mpp/sv8/apekey.html
  40. // The APEv2 Tag Items Keys definition says "TRACK" is correct but foobar2000 uses "TRACKNUMBER" instead
  41. // Pass data here as "TRACKNUMBER" for compatability with all formats
  42. class getid3_writetags
  43. {
  44. // public
  45. var $filename; // absolute filename of file to write tags to
  46. var $tagformats = array(); // array of tag formats to write ('id3v1', 'id3v2.2', 'id2v2.3', 'id3v2.4', 'ape', 'vorbiscomment', 'metaflac', 'real')
  47. var $tag_data = array(array()); // 2-dimensional array of tag data (ex: $data['ARTIST'][0] = 'Elvis')
  48. var $tag_encoding = 'ISO-8859-1'; // text encoding used for tag data ('ISO-8859-1', 'UTF-8', 'UTF-16', 'UTF-16LE', 'UTF-16BE', )
  49. var $overwrite_tags = false; // if true will erase existing tag data and write only passed data; if false will merge passed data with existing tag data
  50. var $remove_other_tags = false; // if true will erase remove all existing tags and only write those passed in $tagformats; if false will ignore any tags not mentioned in $tagformats
  51. var $id3v2_tag_language = 'eng'; // ISO-639-2 3-character language code needed for some ID3v2 frames (http://www.id3.org/iso639-2.html)
  52. var $id3v2_paddedlength = 4096; // minimum length of ID3v2 tags (will be padded to this length if tag data is shorter)
  53. var $warnings = array(); // any non-critical errors will be stored here
  54. var $errors = array(); // any critical errors will be stored here
  55. var $skip_errors = false; // if frame error, skip frame and write tag anyway (id3v2 only)
  56. // private
  57. var $ThisFileInfo; // analysis of file before writing
  58. function getid3_writetags() {
  59. return true;
  60. }
  61. function WriteTags() {
  62. if (empty($this->filename)) {
  63. $this->errors[] = 'filename is undefined in getid3_writetags';
  64. return false;
  65. } elseif (!file_exists($this->filename)) {
  66. $this->errors[] = 'filename set to non-existant file "'.$this->filename.'" in getid3_writetags';
  67. return false;
  68. }
  69. if (!is_array($this->tagformats)) {
  70. $this->errors[] = 'tagformats must be an array in getid3_writetags';
  71. return false;
  72. }
  73. $TagFormatsToRemove = array();
  74. if (filesize($this->filename) == 0) {
  75. // empty file special case - allow any tag format, don't check existing format
  76. // could be useful if you want to generate tag data for a non-existant file
  77. $this->ThisFileInfo = array('fileformat'=>'');
  78. $AllowedTagFormats = array('id3v1', 'id3v2.2', 'id3v2.3', 'id3v2.4', 'ape', 'lyrics3');
  79. } else {
  80. $getID3 = new getID3;
  81. $getID3->encoding = $this->tag_encoding;
  82. $this->ThisFileInfo = $getID3->analyze($this->filename);
  83. // check for what file types are allowed on this fileformat
  84. switch (@$this->ThisFileInfo['fileformat']) {
  85. case 'mp3':
  86. case 'mp2':
  87. case 'mp1':
  88. case 'riff': // maybe not officially, but people do it anyway
  89. $AllowedTagFormats = array('id3v1', 'id3v2.2', 'id3v2.3', 'id3v2.4', 'ape', 'lyrics3');
  90. break;
  91. case 'mpc':
  92. $AllowedTagFormats = array('ape');
  93. break;
  94. case 'flac':
  95. $AllowedTagFormats = array('metaflac');
  96. break;
  97. case 'real':
  98. $AllowedTagFormats = array('real');
  99. break;
  100. case 'ogg':
  101. switch (@$this->ThisFileInfo['audio']['dataformat']) {
  102. case 'flac':
  103. //$AllowedTagFormats = array('metaflac');
  104. $this->errors[] = 'metaflac is not (yet) compatible with OggFLAC files';
  105. return false;
  106. break;
  107. case 'vorbis':
  108. $AllowedTagFormats = array('vorbiscomment');
  109. break;
  110. default:
  111. $this->errors[] = 'metaflac is not (yet) compatible with Ogg files other than OggVorbis';
  112. return false;
  113. break;
  114. }
  115. break;
  116. default:
  117. $AllowedTagFormats = array();
  118. break;
  119. }
  120. foreach ($this->tagformats as $requested_tag_format) {
  121. if (!in_array($requested_tag_format, $AllowedTagFormats)) {
  122. $errormessage = 'Tag format "'.$requested_tag_format.'" is not allowed on "'.@$this->ThisFileInfo['fileformat'];
  123. if (@$this->ThisFileInfo['fileformat'] != @$this->ThisFileInfo['audio']['dataformat']) {
  124. $errormessage .= '.'.@$this->ThisFileInfo['audio']['dataformat'];
  125. }
  126. $errormessage .= '" files';
  127. $this->errors[] = $errormessage;
  128. return false;
  129. }
  130. }
  131. // List of other tag formats, removed if requested
  132. if ($this->remove_other_tags) {
  133. foreach ($AllowedTagFormats as $AllowedTagFormat) {
  134. switch ($AllowedTagFormat) {
  135. case 'id3v2.2':
  136. case 'id3v2.3':
  137. case 'id3v2.4':
  138. if (!in_array('id3v2', $TagFormatsToRemove) && !in_array('id3v2.2', $this->tagformats) && !in_array('id3v2.3', $this->tagformats) && !in_array('id3v2.4', $this->tagformats)) {
  139. $TagFormatsToRemove[] = 'id3v2';
  140. }
  141. break;
  142. default:
  143. if (!in_array($AllowedTagFormat, $this->tagformats)) {
  144. $TagFormatsToRemove[] = $AllowedTagFormat;
  145. }
  146. break;
  147. }
  148. }
  149. }
  150. }
  151. $WritingFilesToInclude = array_merge($this->tagformats, $TagFormatsToRemove);
  152. // Check for required include files and include them
  153. foreach ($WritingFilesToInclude as $tagformat) {
  154. switch ($tagformat) {
  155. case 'ape':
  156. $GETID3_ERRORARRAY = &$this->errors;
  157. if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.apetag.php', __FILE__, false)) {
  158. $this->errors[] = "No $tagformat Library in WriteTags()";
  159. return false;
  160. }
  161. break;
  162. case 'id3v1':
  163. case 'lyrics3':
  164. case 'vorbiscomment':
  165. case 'metaflac':
  166. case 'real':
  167. $GETID3_ERRORARRAY = &$this->errors;
  168. if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.'.$tagformat.'.php', __FILE__, false)) {
  169. $this->errors[] = "No $tagformat Library in WriteTags()";
  170. return false;
  171. }
  172. break;
  173. case 'id3v2.2':
  174. case 'id3v2.3':
  175. case 'id3v2.4':
  176. case 'id3v2':
  177. $GETID3_ERRORARRAY = &$this->errors;
  178. if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.id3v2.php', __FILE__, false)) {
  179. $this->errors[] = "No $tagformat Library in WriteTags()";
  180. return false;
  181. }
  182. break;
  183. default:
  184. $this->errors[] = 'unknown tag format "'.$tagformat.'" in $tagformats in WriteTags()';
  185. return false;
  186. break;
  187. }
  188. }
  189. // Validation of supplied data
  190. if (!is_array($this->tag_data)) {
  191. $this->errors[] = '$tag_data is not an array in WriteTags()';
  192. return false;
  193. }
  194. // convert supplied data array keys to upper case, if they're not already
  195. foreach ($this->tag_data as $tag_key => $tag_array) {
  196. if (strtoupper($tag_key) !== $tag_key) {
  197. $this->tag_data[strtoupper($tag_key)] = $this->tag_data[$tag_key];
  198. unset($this->tag_data[$tag_key]);
  199. }
  200. }
  201. // convert source data array keys to upper case, if they're not already
  202. if (!empty($this->ThisFileInfo['tags'])) {
  203. foreach ($this->ThisFileInfo['tags'] as $tag_format => $tag_data_array) {
  204. foreach ($tag_data_array as $tag_key => $tag_array) {
  205. if (strtoupper($tag_key) !== $tag_key) {
  206. $this->ThisFileInfo['tags'][$tag_format][strtoupper($tag_key)] = $this->ThisFileInfo['tags'][$tag_format][$tag_key];
  207. unset($this->ThisFileInfo['tags'][$tag_format][$tag_key]);
  208. }
  209. }
  210. }
  211. }
  212. // Convert "TRACK" to "TRACKNUMBER" (if needed) for compatability with all formats
  213. if (isset($this->tag_data['TRACK']) && !isset($this->tag_data['TRACKNUMBER'])) {
  214. $this->tag_data['TRACKNUMBER'] = $this->tag_data['TRACK'];
  215. unset($this->tag_data['TRACK']);
  216. }
  217. // Remove all other tag formats, if requested
  218. if ($this->remove_other_tags) {
  219. $this->DeleteTags($TagFormatsToRemove);
  220. }
  221. // Write data for each tag format
  222. foreach ($this->tagformats as $tagformat) {
  223. $success = false; // overridden if tag writing is successful
  224. switch ($tagformat) {
  225. case 'ape':
  226. $ape_writer = new getid3_write_apetag;
  227. if (($ape_writer->tag_data = $this->FormatDataForAPE()) !== false) {
  228. $ape_writer->filename = $this->filename;
  229. if (($success = $ape_writer->WriteAPEtag()) === false) {
  230. $this->errors[] = 'WriteAPEtag() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $ape_writer->errors)).'</LI></UL></PRE>';
  231. }
  232. } else {
  233. $this->errors[] = 'FormatDataForAPE() failed';
  234. }
  235. break;
  236. case 'id3v1':
  237. $id3v1_writer = new getid3_write_id3v1;
  238. if (($id3v1_writer->tag_data = $this->FormatDataForID3v1()) !== false) {
  239. $id3v1_writer->filename = $this->filename;
  240. if (($success = $id3v1_writer->WriteID3v1()) === false) {
  241. $this->errors[] = 'WriteID3v1() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $id3v1_writer->errors)).'</LI></UL></PRE>';
  242. }
  243. } else {
  244. $this->errors[] = 'FormatDataForID3v1() failed';
  245. }
  246. break;
  247. case 'id3v2.2':
  248. case 'id3v2.3':
  249. case 'id3v2.4':
  250. $id3v2_writer = new getid3_write_id3v2;
  251. $id3v2_writer->majorversion = intval(substr($tagformat, -1));
  252. $id3v2_writer->paddedlength = $this->id3v2_paddedlength;
  253. $id3v2_writer->merge_existing_data = !$this->overwrite_tags;
  254. $id3v2_writer->skip_errors = $this->skip_errors;
  255. if (($id3v2_writer->tag_data = $this->FormatDataForID3v2($id3v2_writer->majorversion)) !== false) {
  256. $id3v2_writer->filename = $this->filename;
  257. if (($success = $id3v2_writer->WriteID3v2()) === false) {
  258. $this->errors[] = 'WriteID3v2() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $id3v2_writer->errors)).'</LI></UL></PRE>';
  259. }
  260. } else {
  261. $this->errors[] = 'FormatDataForID3v2() failed';
  262. }
  263. if (!empty($id3v2_writer->warnings)) $this->warnings = array_merge($this->warnings, $id3v2_writer->warnings);
  264. break;
  265. case 'vorbiscomment':
  266. $vorbiscomment_writer = new getid3_write_vorbiscomment;
  267. if (($vorbiscomment_writer->tag_data = $this->FormatDataForVorbisComment()) !== false) {
  268. $vorbiscomment_writer->filename = $this->filename;
  269. if (($success = $vorbiscomment_writer->WriteVorbisComment()) === false) {
  270. $this->errors[] = 'WriteVorbisComment() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $vorbiscomment_writer->errors)).'</LI></UL></PRE>';
  271. }
  272. } else {
  273. $this->errors[] = 'FormatDataForVorbisComment() failed';
  274. }
  275. break;
  276. case 'metaflac':
  277. $metaflac_writer = new getid3_write_metaflac;
  278. if (($metaflac_writer->tag_data = $this->FormatDataForMetaFLAC()) !== false) {
  279. $metaflac_writer->filename = $this->filename;
  280. if (($success = $metaflac_writer->WriteMetaFLAC()) === false) {
  281. $this->errors[] = 'WriteMetaFLAC() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $metaflac_writer->errors)).'</LI></UL></PRE>';
  282. }
  283. } else {
  284. $this->errors[] = 'FormatDataForMetaFLAC() failed';
  285. }
  286. break;
  287. case 'real':
  288. $real_writer = new getid3_write_real;
  289. if (($real_writer->tag_data = $this->FormatDataForReal()) !== false) {
  290. $real_writer->filename = $this->filename;
  291. if (($success = $real_writer->WriteReal()) === false) {
  292. $this->errors[] = 'WriteReal() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $real_writer->errors)).'</LI></UL></PRE>';
  293. }
  294. } else {
  295. $this->errors[] = 'FormatDataForReal() failed';
  296. }
  297. break;
  298. default:
  299. $this->errors[] = 'Invalid tag format to write: "'.$tagformat.'"';
  300. return false;
  301. break;
  302. }
  303. if (!$success) {
  304. if (empty($this->errors)) {
  305. $this->errors[] = 'unknown error in WriteTags()';
  306. }
  307. return false;
  308. }
  309. }
  310. return true;
  311. }
  312. function DeleteTags($TagFormatsToDelete) {
  313. foreach ($TagFormatsToDelete as $DeleteTagFormat) {
  314. $success = false; // overridden if tag deletion is successful
  315. switch ($DeleteTagFormat) {
  316. case 'id3v1':
  317. $id3v1_writer = new getid3_write_id3v1;
  318. $id3v1_writer->filename = $this->filename;
  319. if (($success = $id3v1_writer->RemoveID3v1()) === false) {
  320. $this->errors[] = 'RemoveID3v1() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $id3v1_writer->errors)).'</LI></UL></PRE>';
  321. }
  322. break;
  323. case 'id3v2':
  324. $id3v2_writer = new getid3_write_id3v2;
  325. $id3v2_writer->filename = $this->filename;
  326. if (($success = $id3v2_writer->RemoveID3v2()) === false) {
  327. $this->errors[] = 'RemoveID3v2() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $id3v2_writer->errors)).'</LI></UL></PRE>';
  328. }
  329. break;
  330. case 'ape':
  331. $ape_writer = new getid3_write_apetag;
  332. $ape_writer->filename = $this->filename;
  333. if (($success = $ape_writer->DeleteAPEtag()) === false) {
  334. $this->errors[] = 'DeleteAPEtag() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $ape_writer->errors)).'</LI></UL></PRE>';
  335. }
  336. break;
  337. case 'vorbiscomment':
  338. $vorbiscomment_writer = new getid3_write_vorbiscomment;
  339. $vorbiscomment_writer->filename = $this->filename;
  340. if (($success = $vorbiscomment_writer->DeleteVorbisComment()) === false) {
  341. $this->errors[] = 'DeleteVorbisComment() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $vorbiscomment_writer->errors)).'</LI></UL></PRE>';
  342. }
  343. break;
  344. case 'metaflac':
  345. $metaflac_writer = new getid3_write_metaflac;
  346. $metaflac_writer->filename = $this->filename;
  347. if (($success = $metaflac_writer->DeleteMetaFLAC()) === false) {
  348. $this->errors[] = 'DeleteMetaFLAC() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $metaflac_writer->errors)).'</LI></UL></PRE>';
  349. }
  350. break;
  351. case 'lyrics3':
  352. $lyrics3_writer = new getid3_write_lyrics3;
  353. $lyrics3_writer->filename = $this->filename;
  354. if (($success = $lyrics3_writer->DeleteLyrics3()) === false) {
  355. $this->errors[] = 'DeleteLyrics3() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $lyrics3_writer->errors)).'</LI></UL></PRE>';
  356. }
  357. break;
  358. case 'real':
  359. $real_writer = new getid3_write_real;
  360. $real_writer->filename = $this->filename;
  361. if (($success = $real_writer->RemoveReal()) === false) {
  362. $this->errors[] = 'RemoveReal() failed with message(s):<PRE><UL><LI>'.trim(implode('</LI><LI>', $real_writer->errors)).'</LI></UL></PRE>';
  363. }
  364. break;
  365. default:
  366. $this->errors[] = 'Invalid tag format to delete: "'.$tagformat.'"';
  367. return false;
  368. break;
  369. }
  370. if (!$success) {
  371. return false;
  372. }
  373. }
  374. return true;
  375. }
  376. function MergeExistingTagData($TagFormat, &$tag_data) {
  377. // Merge supplied data with existing data, if requested
  378. if ($this->overwrite_tags) {
  379. // do nothing - ignore previous data
  380. } else {
  381. if (!isset($this->ThisFileInfo['tags'][$TagFormat])) {
  382. return false;
  383. }
  384. $tag_data = array_merge_recursive($tag_data, $this->ThisFileInfo['tags'][$TagFormat]);
  385. }
  386. return true;
  387. }
  388. function FormatDataForAPE() {
  389. $ape_tag_data = array();
  390. foreach ($this->tag_data as $tag_key => $valuearray) {
  391. switch ($tag_key) {
  392. case 'ATTACHED_PICTURE':
  393. // ATTACHED_PICTURE is ID3v2 only - ignore
  394. $this->warnings[] = '$data['.$tag_key.'] is assumed to be ID3v2 APIC data - NOT written to APE tag';
  395. break;
  396. default:
  397. foreach ($valuearray as $key => $value) {
  398. if (is_string($value) || is_numeric($value)) {
  399. $ape_tag_data[$tag_key][$key] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-8', $value);
  400. } else {
  401. $this->warnings[] = '$data['.$tag_key.']['.$key.'] is not a string value - all of $data['.$tag_key.'] NOT written to APE tag';
  402. unset($ape_tag_data[$tag_key]);
  403. break;
  404. }
  405. }
  406. break;
  407. }
  408. }
  409. $this->MergeExistingTagData('ape', $ape_tag_data);
  410. return $ape_tag_data;
  411. }
  412. function FormatDataForID3v1() {
  413. $tag_data_id3v1['genreid'] = 255;
  414. if (!empty($this->tag_data['GENRE'])) {
  415. foreach ($this->tag_data['GENRE'] as $key => $value) {
  416. if (getid3_id3v1::LookupGenreID($value) !== false) {
  417. $tag_data_id3v1['genreid'] = getid3_id3v1::LookupGenreID($value);
  418. break;
  419. }
  420. }
  421. }
  422. $tag_data_id3v1['title'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['TITLE']));
  423. $tag_data_id3v1['artist'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['ARTIST']));
  424. $tag_data_id3v1['album'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['ALBUM']));
  425. $tag_data_id3v1['year'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['YEAR']));
  426. $tag_data_id3v1['comment'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['COMMENT']));
  427. $tag_data_id3v1['track'] = intval(getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['TRACKNUMBER'])));
  428. if ($tag_data_id3v1['track'] <= 0) {
  429. $tag_data_id3v1['track'] = '';
  430. }
  431. $this->MergeExistingTagData('id3v1', $tag_data_id3v1);
  432. return $tag_data_id3v1;
  433. }
  434. function FormatDataForID3v2($id3v2_majorversion) {
  435. $tag_data_id3v2 = array();
  436. $ID3v2_text_encoding_lookup[2] = array('ISO-8859-1'=>0, 'UTF-16'=>1);
  437. $ID3v2_text_encoding_lookup[3] = array('ISO-8859-1'=>0, 'UTF-16'=>1);
  438. $ID3v2_text_encoding_lookup[4] = array('ISO-8859-1'=>0, 'UTF-16'=>1, 'UTF-16BE'=>2, 'UTF-8'=>3);
  439. foreach ($this->tag_data as $tag_key => $valuearray) {
  440. $ID3v2_framename = getid3_write_id3v2::ID3v2ShortFrameNameLookup($id3v2_majorversion, $tag_key);
  441. switch ($ID3v2_framename) {
  442. case 'APIC':
  443. foreach ($valuearray as $key => $apic_data_array) {
  444. if (isset($apic_data_array['data']) &&
  445. isset($apic_data_array['picturetypeid']) &&
  446. isset($apic_data_array['description']) &&
  447. isset($apic_data_array['mime'])) {
  448. $tag_data_id3v2['APIC'][] = $apic_data_array;
  449. } else {
  450. $this->errors[] = 'ID3v2 APIC data is not properly structured';
  451. return false;
  452. }
  453. }
  454. break;
  455. case '':
  456. $this->errors[] = 'ID3v2: Skipping "'.$tag_key.'" because cannot match it to a known ID3v2 frame type';
  457. // some other data type, don't know how to handle it, ignore it
  458. break;
  459. default:
  460. // most other (text) frames can be copied over as-is
  461. foreach ($valuearray as $key => $value) {
  462. if (isset($ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding])) {
  463. // source encoding is valid in ID3v2 - use it with no conversion
  464. $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = $ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding];
  465. $tag_data_id3v2[$ID3v2_framename][$key]['data'] = $value;
  466. } else {
  467. // source encoding is NOT valid in ID3v2 - convert it to an ID3v2-valid encoding first
  468. if ($id3v2_majorversion < 4) {
  469. // convert data from other encoding to UTF-16
  470. $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 1;
  471. #$tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-16', $value);
  472. $tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-16LE', $value);
  473. $data = &$tag_data_id3v2[$ID3v2_framename][$key]['data'];
  474. if (!empty($data)) { $data = chr(255).chr(254).$data; }
  475. } else {
  476. // convert data from other encoding to UTF-8
  477. $tag_data_id3v2[$ID3v2_framename][$key]['encodingid'] = 3;
  478. $tag_data_id3v2[$ID3v2_framename][$key]['data'] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-8', $value);
  479. }
  480. }
  481. // These values are not needed for all frame types, but if they're not used no matter
  482. $tag_data_id3v2[$ID3v2_framename][$key]['description'] = '';
  483. $tag_data_id3v2[$ID3v2_framename][$key]['language'] = $this->id3v2_tag_language;
  484. }
  485. break;
  486. }
  487. }
  488. $this->MergeExistingTagData('id3v2', $tag_data_id3v2);
  489. return $tag_data_id3v2;
  490. }
  491. function FormatDataForVorbisComment() {
  492. $tag_data_vorbiscomment = $this->tag_data;
  493. // check for multi-line comment values - split out to multiple comments if neccesary
  494. // and convert data to UTF-8 strings
  495. foreach ($tag_data_vorbiscomment as $tag_key => $valuearray) {
  496. foreach ($valuearray as $key => $value) {
  497. str_replace("\r", "\n", $value);
  498. if (strstr($value, "\n")) {
  499. unset($tag_data_vorbiscomment[$tag_key][$key]);
  500. $multilineexploded = explode("\n", $value);
  501. foreach ($multilineexploded as $newcomment) {
  502. if (strlen(trim($newcomment)) > 0) {
  503. $tag_data_vorbiscomment[$tag_key][] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-8', $newcomment);
  504. }
  505. }
  506. } elseif (is_string($value) || is_numeric($value)) {
  507. $tag_data_vorbiscomment[$tag_key][$key] = getid3_lib::iconv_fallback($this->tag_encoding, 'UTF-8', $value);
  508. } else {
  509. $this->warnings[] = '$data['.$tag_key.']['.$key.'] is not a string value - all of $data['.$tag_key.'] NOT written to VorbisComment tag';
  510. unset($tag_data_vorbiscomment[$tag_key]);
  511. break;
  512. }
  513. }
  514. }
  515. $this->MergeExistingTagData('vorbiscomment', $tag_data_vorbiscomment);
  516. return $tag_data_vorbiscomment;
  517. }
  518. function FormatDataForMetaFLAC() {
  519. // FLAC & OggFLAC use VorbisComments same as OggVorbis
  520. // but require metaflac to do the writing rather than vorbiscomment
  521. return $this->FormatDataForVorbisComment();
  522. }
  523. function FormatDataForReal() {
  524. $tag_data_real['title'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['TITLE']));
  525. $tag_data_real['artist'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['ARTIST']));
  526. $tag_data_real['copyright'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['COPYRIGHT']));
  527. $tag_data_real['comment'] = getid3_lib::iconv_fallback($this->tag_encoding, 'ISO-8859-1', @implode(' ', @$this->tag_data['COMMENT']));
  528. $this->MergeExistingTagData('real', $tag_data_real);
  529. return $tag_data_real;
  530. }
  531. }
  532. ?>