lib_scanner.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. /**
  3. * ownCloud - media plugin
  4. *
  5. * @author Robin Appelman
  6. * @copyright 2010 Robin Appelman icewind1991@gmail.com
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. require_once('getid3/getid3.php');
  23. //class for scanning directories for music
  24. class OC_MEDIA_SCANNER{
  25. static private $getID3=false;
  26. //these are used to store which artists and albums we found, it can save a lot of addArtist/addAlbum calls
  27. static private $artists=array();
  28. static private $albums=array();//stored as "$artist/$album" to allow albums with the same name from different artists
  29. /**
  30. * scan a folder for music
  31. * @param OC_EventSource eventSource (optional)
  32. * @return int the number of songs found
  33. */
  34. public static function scanCollection($eventSource=null){
  35. $music=OC_FileCache::searchByMime('audio');
  36. $ogg=OC_FileCache::searchByMime('application','ogg');
  37. $music=array_merge($music,$ogg);
  38. $eventSource->send('count',count($music));
  39. $songs=0;
  40. foreach($music as $file){
  41. self::scanFile($file);
  42. $songs++;
  43. if($eventSource){
  44. $eventSource->send('scanned',array('file'=>$file,'count'=>$songs));
  45. }
  46. }
  47. if($eventSource){
  48. $eventSource->send('done',$songs);
  49. }
  50. return $songs;
  51. }
  52. /**
  53. * scan a file for music
  54. * @param string $path
  55. * @return boolean
  56. */
  57. public static function scanFile($path){
  58. $file=OC_Filesystem::getLocalFile($path);
  59. if(!self::isMusic($path)){
  60. return;
  61. }
  62. if(!self::$getID3){
  63. self::$getID3=@new getID3();
  64. self::$getID3->encoding='UTF-8';
  65. }
  66. $data=@self::$getID3->analyze($file);
  67. getid3_lib::CopyTagsToComments($data);
  68. if(!isset($data['comments'])){
  69. OCP\Util::writeLog('media',"error reading id3 tags in '$file'",OCP\Util::WARN);
  70. return;
  71. }
  72. if(!isset($data['comments']['artist'])){
  73. OCP\Util::writeLog('media',"error reading artist tag in '$file'",OCP\Util::WARN);
  74. $artist='unknown';
  75. }else{
  76. $artist=OCP\Util::sanitizeHTML(stripslashes($data['comments']['artist'][0]));
  77. }
  78. if(!isset($data['comments']['album'])){
  79. OCP\Util::writeLog('media',"error reading album tag in '$file'",OCP\Util::WARN);
  80. $album='unknown';
  81. }else{
  82. $album=OCP\Util::sanitizeHTML(stripslashes($data['comments']['album'][0]));
  83. }
  84. if(!isset($data['comments']['title'])){
  85. OCP\Util::writeLog('media',"error reading title tag in '$file'",OCP\Util::WARN);
  86. $title='unknown';
  87. }else{
  88. $title=OCP\Util::sanitizeHTML(stripslashes($data['comments']['title'][0]));
  89. }
  90. $size=$data['filesize'];
  91. if (isset($data['comments']['track']))
  92. {
  93. $track = $data['comments']['track'][0];
  94. }
  95. else if (isset($data['comments']['track_number']))
  96. {
  97. $track = $data['comments']['track_number'][0];
  98. $track = explode('/',$track);
  99. $track = $track[0];
  100. }
  101. else
  102. {
  103. $track = 0;
  104. }
  105. $length=isset($data['playtime_seconds'])?round($data['playtime_seconds']):0;
  106. if(!isset(self::$artists[$artist])){
  107. $artistId=OC_MEDIA_COLLECTION::addArtist($artist);
  108. self::$artists[$artist]=$artistId;
  109. }else{
  110. $artistId=self::$artists[$artist];
  111. }
  112. if(!isset(self::$albums[$artist.'/'.$album])){
  113. $albumId=OC_MEDIA_COLLECTION::addAlbum($album,$artistId);
  114. self::$albums[$artist.'/'.$album]=$albumId;
  115. }else{
  116. $albumId=self::$albums[$artist.'/'.$album];
  117. }
  118. $songId=OC_MEDIA_COLLECTION::addSong($title,$path,$artistId,$albumId,$length,$track,$size);
  119. return (!($title=='unkown' && $artist=='unkown' && $album=='unkown'))?$songId:0;
  120. }
  121. /**
  122. * quick check if a song is a music file by checking the extension, not as good as a proper mimetype check but way faster
  123. * @param string $filename
  124. * @return bool
  125. */
  126. public static function isMusic($filename){
  127. $ext=strtolower(substr($filename,strrpos($filename,'.')+1));
  128. return $ext=='mp3' || $ext=='flac' || $ext=='m4a' || $ext=='ogg' || $ext=='oga';
  129. }
  130. }