Php ile müzik kütüphanenizi düzenleyin.

Başlatan canosayan, 10 Ekim 2011 - 01:09:33

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

canosayan

Eğer sizde benim gibi çok farklı kaynaklardan derlenmiş bir bir müzik kütüphanesine sahipseniz, dosya isimleri, albüm bilgileri gibi şeyleri düzenlemenin tam bir işkence olduğunu bilirsiniz. Hele bir de internetten indiriyorsanız. Hele bir de bu dosyaları arada windows üzerinde de dinliyorsanız iyiden bozulurlar.

İşte çok uzun zamandır bunun için çeşitli id3tag editörleri denedim. sonunda olaya el atayım dedim. bir php sınıfı yazdım. şu an hayli beta sürecinde. o yüzden denemek isterseniz ya mp3lerinizi yedekleyin yada ufak çaplı deneyin derim. kısaca uygulamadan bahsedelim.

Öncelikle işlemlerini gerçekleştirebilmesi için sisteminizde php olmalı. (zaten farkındasanız php bölümündeyiz. zaten olmasa da kurabilirsiniz.) Sonrasında bazı paketlere daha ihtiyacımız var. bunlar
php5-curl, php5-cli ve id3v2 hepsini synaptic yada apt-get ile kurmanız mümkün.

Tabi şu anki beta sürecinden dolayı uygulamaya bazı şeyleri hazır vermeniz gerekiyor. Bunun başında da dizin yapısı geliyor. Gerçi çok zor değil. Muhtemelen zaten öyle kaydetmiştiniz. Dizin yapsı şöyle olmalı


Dizin yapısı
Müzik klasörünüz
     uygulama
     Sanatçı 1
         sanatçı 1 albüm 1
         sanatçı 1 albüm 2
     Sanatçı 2
         sanatçı 2 albüm 1

Uygulamanın özelliklerini yazarsak

  • Uygulama tüm dizin ve dosyaların adlarındaki gereksiz karakterleri temizler. Örneğin: yaylı yada köşeli parantez için notlarını, windows-1254 nedeniyle uygunsuz karakterleri, alt çizgi, slash, diyez, nokta
  • Bütün dosya ve dizin adlarını başlık yazımına dönüştürür. Örneğin "Bu Bir Başlık Tipi Yazımdır"
  • Şarkıların dosya adlarındaki sanatçı isimlerini kaldırır. Böylece tekrarı önlemeye çalışır.
  • Dosya formatlarını küçük harfe çevirir.
  • Thumb.db, *.txt, *.uri gibi çeşitli gereksiz dosyaları temizler.
  • İşlem yaparken işlem yaptığı sanatçı ile ilgili tüm verileri fizy.com'dan çeker. Böylece çok çeşitli şekillerde yazılmış verileri elde eder.
  • Fizy'den çektiği bilgileri düzenler.
  • Her bir dosyayı fizyden gelen veritabanı ile eşlemeye çalışır. Bu süreçte eşleyemediği dosyalar  için, gelen veri ile benzerlik kontrolü yapar. Bu harf hatası nedeniyle, türkçe karakter hatası nedeniyle bulunamayan şarkıları bulmasını sağlar. Ayrıca bu yolla bozuk yada hatalı olan şarkılarınızın adlarını düzeltmeye çalışır.
  • Eşleyebildiği tüm şarkıları eşleyebildikten sonra, fizyden bu şarkılar için şarkı sözü araması yapar.
  • Eğer hala eşleyemediği şarkılar varsa, bu şarkıların isimlerini fizyde doğrudan arar ve önce tam eşleşme, sonrasında, benzerlik kontrolü yaparak eşleşme bulmaya çalışır. Bulduğu eşleşmelerin yine şarkı sözlerini getirir.
  • En son topladığı tüm bilgileri şarkılara uygulayarak daha temiz bir kütüphaneniz olmasını sağlar
  • Yapmakta olduğu işlemleri gösterir ve ne zaman bitecek fikrinden kurtarır

Uygulamayı verirsek

#!/usr/bin/php
<?php 
/* 
bu uygulama mp3leri tarar düzeltir falan işte
canosayan: http://www.canosayan.com
*/
ini_set("display_errors",0);
class 
id3
{
public $arama;
public $dir;
public $dizin;
public $dizinIndis=0;
public $sanatci;
public $sanatciData;
public $fizyData;
public $log;
 
public function __construct()
{
$this->log('Sistem Oluşturuluyor');
$this->dir=dirname(__FILE__);
$this->log=array();
$this->dizin=scandir($this->dir);
$this->dizinAyikla();
$gecici=$this->dizin;
$this->dizin=array();
foreach($gecici as $tek)
{
if($tek!="." && $tek!='..')
{
$this->dizin[]=$tek;
}
}
$this->dizinAdiTemizle();
$this->dizin=scandir($this->dir);
$this->dizinAyikla();
$gecici=$this->dizin;
$this->dizin=array();
foreach($gecici as $tek)
{
if($tek!="." && $tek!='..')
{
$this->dizin[]=$tek;
}
}
}

public function dizinAyikla()
{
foreach($this->dizin as $key=>$deger)
{
if(is_dir($this->dir.'/'.$deger)===FALSE)
{
unset($this->dizin[$key]);
}
}
}

public function tek()
{
if(!isset($this->dizin[$this->dizinIndis]))
{
die;
}
$klasor=$this->dizin[$this->dizinIndis];
$this->sanatci=$klasor;
$this->log($klasor.' için işleme başlanıyor.');
//sanatci için klasörleri toparla
$this->sanatciData=$this->klasorTara($this->dir.'/'.$klasor);
//print_r($this->sanatciData);

$this->log($klasor.' için dizinler tarandı.');
//sanatci dosyalarını temizle
$this->dosyaAdiTemizle();
//fizyden data topla
$this->fizyData=$this->fizy($this->sanatci);
foreach($this->sanatciData as $key=>$dosya)
{
//her dosya için
foreach($this->fizyData->sonuc as $fkey=>$tek)
{
if($tek->baslik==$dosya["baslik"])
{
$this->sanatciData[$key]["fizy"]=$fkey;
}
}
}
//eşlenememiş olanlar için benzerlik taraması yap
foreach($this->sanatciData as $key=>$dosya)
{
if(!isset($dosya["fizy"]))
{
//eşlenememiş her dosya için
foreach($this->fizyData->sonuc as $fkey=>$tek)
{
//eğer oran %75 den büyükse aynı kabul et.
similar_text($tek->baslik,$dosya["baslik"],$oran);
if($oran>85)
{
$this->sanatciData[$key]["fizy"]=$fkey;
$this->sanatciData[$key]["baslik"]=$tek->baslik;
}
}
}
}
//print_r($this->sanatciData);
//sanatçı datasını fizy bilgisi ile doldur.
$this->fizySarkiBilgi();
//şarkı bilgilerde geldiğine göre şimdi it3tag başlamalı
$this->log('Şarkıları işleniyor.');
foreach($this->sanatciData as $key=>$tek)
{
if(!isset($tek["lyrics"]))
{
$tek["lyrics"]="";
}
if(!isset($tek["album"]))
{
$tek["album"]=$this->sanatci;
}
$format=$tek["format"];

$this->log('>>'.$tek["baslik"].' işleniyor');
$data=array(
"--song"=>mb_convert_case($tek["baslik"], MB_CASE_TITLE"UTF-8"),
"--artist"=>mb_convert_case($this->sanatciMB_CASE_TITLE"UTF-8"),
"--comment"=>trim(str_replace(array('"',"'"),'',strip_tags($tek["lyrics"]))),
"--track"=>0,
"--album"=>mb_convert_case($tek["album"], MB_CASE_TITLE"UTF-8"),
);

$this->sanatciData[$key]["exec"]=array();
exec('id3v2 --convert "'.$tek["klasor"].'/'.$tek["dosya"].'"');
foreach( $data as $a=> $b)
{
$exec='id3v2 '.$a.' "'.$b.'" "'.$tek["klasor"].'/'.$tek["dosya"].'"';
exec($exec);
//echo $b."\n\n";
$this->sanatciData[$key]["exec"][]=$exec;
}
rename($tek["klasor"].'/'.$tek["dosya"],$tek["klasor"].'/xxxisleme');
rename($tek["klasor"].'/xxxisleme',$tek["klasor"].'/'.mb_convert_case($tek["baslik"], MB_CASE_TITLE"UTF-8").'.'.strtolower($format));


}
$this->log($tek["baslik"].' işlendi');
$this->log("-----------------------\n\n");

$this->dizinIndis++;

//print_r($this->sanatciData);

}

public function islem()
{
for($i=0;$i<count($this->dizin);$i++)
{
$this->tek();
}
}

public function klasorTara($klasor)
{
$this->log($klasor.' için klasör taranıyor.');
$data=array();
$icerik=$this->scandir($klasor);
foreach($icerik as $tek)
{
if(is_dir($klasor.'/'.$tek))
{
//echo "\n alt:".$klasor.'/'.$tek;
   $alt=$this->klasorTara($klasor.'/'.$tek);
   foreach($alt as $a=>$b)
   {
   $alt[$a]["album"]=$tek;
   }
   //print_r($alt);
$data=array_merge($data,$alt);
}
else
{
$yeni=array();
$yeni["klasor"]=$klasor;
$yeni["dosya"]=$tek;
$data[]=$yeni;
}
}
return $data;
}
 
public function fizy($ara)
{
$this->log($ara.' için fizyden şarkılar taranıyor.');
$obje=new stdClass();
$obje->arama=$ara;
$obje->sonuc=array();
//ilk data
$data = array('query' => $ara"p"=>0);

//ilk aramayı yap
$ch curl_init("http://fizy.com/search");
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_POSTFIELDS$data);
$sonuc=curl_exec($ch);
curl_close($ch);
$sonuc=json_decode($sonuc);
$obje->toplam=$sonuc->total;
$this->log($ara.' için fizy verileri işleniyor.');
foreach($sonuc->results as $tek)
{
$yeni=new stdClass();
$yeni->artist="";
$yeni->baslik="";
$yeni->isim=$tek->title;
if(strpbrk($tek->title,'-')!==FALSE)
{
$data=explode('-',$tek->title);
$yeni->artist=trim($data[0]);
$baslik=str_replace($data[0],'',$data[1]);
$yeni->baslik=$this->fizyBaslikTemizle($baslik);

}
$obje->sonuc[$tek->ID]=$yeni;
}
//diğer sayfaları tara
for($i=1;$i<$sonuc->totalpages;$i++)
{
$data = array('query' => $ara"p"=>$i);

//ilk aramayı yap
$ch curl_init("http://fizy.com/search");
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_POSTFIELDS$data);
$sayfa=curl_exec($ch);
curl_close($ch);
$sayfa=json_decode($sayfa);
foreach($sayfa->results as $tek)
{
$yeni=new stdClass();
$yeni->artist="";
$yeni->baslik="";
$yeni->isim=$tek->title;
if(strpbrk($tek->title,'-')!==FALSE)
{
$data=explode('-',$tek->title);
$yeni->artist=trim($data[0]);
$baslik=str_replace($data[0],'',$data[1]);
$yeni->baslik=$this->fizyBaslikTemizle($baslik);

}
$obje->sonuc[$tek->ID]=$yeni;
}
}
$this->log($ara.' için fizy bilgileri toplandı.');
//geri dön
return $obje;
}

public function fizyBaslikTemizle($baslik)
{
$baslik=str_replace(array("rock'n coke","'",'"','.','/'),'',$baslik);
$baslik=preg_replace('#\([A-Za-z0-9 ]+\)#','',$baslik);
$baslik=preg_replace('#\[[A-Za-z0-9 ]+\]#','',$baslik);
$baslik=preg_replace('#[0-9]*#','',$baslik);
$baslik=str_replace(array('(',')'),'',$baslik);
$baslik=explode('by',$baslik);
$baslik=$baslik[0];
return trim($baslik);
}

public function fizySarkiBilgi()
{
$this->log('Şarkılar için fizy bilgileri toplanıyor.');
foreach($this->sanatciData as $key => $tek)
{
if(isset($tek["fizy"]))
{
//eğer şarkı bulunduysa şarkıyı getir
foreach($this->fizyData->sonuc as $anahtar=>$data)
{
if($tek["baslik"]==$data->baslik)
{
$bilgi=$this->fizySarkiGetir($anahtar);
if($bilgi->lyrics!==false)
{
$this->sanatciData[$key]["lyrics"]=strip_tags($bilgi->lyrics);
break;
}
}
}
if(!isset($this->sanatciData[$key]["lyrics"]))
{
foreach($this->fizyData->sonuc as $anahtar=>$data)
{

similar_text($data->baslik,$tek["baslik"],$oran);
if($oran>85)
{
$bilgi=$this->fizySarkiGetir($anahtar);
if($bilgi->lyrics!==false)
{
$this->sanatciData[$key]["lyrics"]=strip_tags($bilgi->lyrics);
break;
}
}
}
}

}
else
{
//daha önce eşlenemedi. bu sefer bulduklarımızdan türkçe karakterleri silelim ki karakter tabanlı benzerlikler sorun yaratmasın
$data = array('query' => $tek["baslik"], "p"=>0);
//ilk aramayı yap
$ch curl_init("http://fizy.com/search");
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
curl_setopt($chCURLOPT_POSTFIELDS$data);
$sonuc=curl_exec($ch);
curl_close($ch);
$sonuc=json_decode($sonuc);
if(isset($sonuc->result))
{
//sonuç geldiyse
foreach($sonuc->results as $alt)
{
//diziyi tekrar oluştur
$yeni=new stdClass();
$yeni->artist="";
$yeni->baslik="";
$yeni->isim=$alt->title;
if(strpbrk($alt->title,'-')!==FALSE)
{
$data=explode('-',$alt->title);
$yeni->artist=trim($data[0]);
$baslik=str_replace($data[0],'',$data[1]);
$yeni->baslik=$this->fizyBaslikTemizle($baslik);
}
echo $yeni->baslik;
//similar_text($yeni->baslik,$tek["baslik"],$oran);
if($yeni->baslik==$tek["baslik"])
{
//%85 den yüksek oranda eşitle
$bilgi=$this->fizySarkiGetir($anahtar);
if($bilgi->lyrics!==false)
{
$this->sanatciData[$key]["lyrics"]=strip_tags($bilgi->lyrics);
break;
}
}

}
//hala olmadıysa
if(!isset($this->sanatciData[$key]["lyrics"]))
{
foreach($sonuc->results as $alt)
{
//diziyi tekrar oluştur
$yeni=new stdClass();
$yeni->artist="";
$yeni->baslik="";
$yeni->isim=$alt->title;
if(strpbrk($alt->title,'-')!==FALSE)
{
$data=explode('-',$alt->title);
$yeni->artist=trim($data[0]);
$baslik=str_replace($data[0],'',$data[1]);
$yeni->baslik=$this->fizyBaslikTemizle($baslik);
}
echo $yeni->baslik;
similar_text($yeni->baslik,$tek["baslik"],$oran);
if($oran>85)
{
//%85 den yüksek oranda eşitle
$bilgi=$this->fizySarkiGetir($anahtar);
if($bilgi->lyrics!==false)
{
$this->sanatciData[$key]["lyrics"]=strip_tags($bilgi->lyrics);
break;
}
}

}
}
}


}

}
}

private function fizySarkiGetir($SID)
{
//fizyde karşılığı varsa
$ch curl_init("http://fizy.com/fizy::getSong");
curl_setopt($chCURLOPT_POST1);
curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
$data = array('SID' => $SID"isPlaylist"=>0);
curl_setopt($chCURLOPT_POSTFIELDS$data);
$sayfa=curl_exec($ch);
curl_close($ch);
$sayfa=json_decode($sayfa);
return $sayfa;
}

public function dosyaAdiTemizle()
{
$this->log('İlgili klasör dosya adları temizleniyor');

foreach($this->sanatciData as $key=>$tek)
{
//dosya formatını kes
$dosya=explode('.',$tek["dosya"]);
$format=strtolower($dosya[(count($dosya)-1)]);
$baslik=str_replace('.'.$format,'',$tek["dosya"]);
//küçük harfe çevir
$baslik=mb_convert_case($baslikMB_CASE_LOWER"UTF-8");
//genel temizlik

$baslik=$this->genelTemizlik($baslik,array(mb_convert_case($this->sanatciMB_CASE_LOWER"UTF-8")));
$dosyaAd=$baslik.'.'.$format;
$this->sanatciData[$key]["dosya"]=$dosyaAd;
$this->sanatciData[$key]["baslik"]=$baslik;
$this->sanatciData[$key]["format"]=$format;
rename($tek["klasor"].'/'.$tek["dosya"],$tek["klasor"].'/xxxgecici');
rename($tek["klasor"].'/xxxgecici',$tek["klasor"].'/'.$dosyaAd);
// db txt gibi zırva şeylerse sil
if(in_array($format,array('db','url','txt')))
{
unlink($tek["klasor"].'/'.$dosyaAd);
}
}

}

public function dizinAdiTemizle()
{
$this->log('Klasör adları temizleniyor');
foreach($this->dizin as $key=>$tek)
{
//dosya formatını kes
$baslik=$this->genelTemizlik($tek);
$baslik=mb_convert_case($baslikMB_CASE_TITLE"UTF-8");
$this->dizin[$key]=$baslik;

rename($this->dir.'/'.$tek,$this->dir.'/xxxdizin');
rename($this->dir.'/xxxdizin',$this->dir.'/'.$baslik);
$this->altDizinDuzenle($baslik);
}
}

private function altDizinDuzenle($dizin)
{

$dizinler=$this->scandir($this->dir.'/'.$dizin);
foreach($dizinler as $tek)
{
if(is_dir($this->dir.'/'.$dizin.'/'.$tek))
{
//dizinse onuda düzenle
$baslik=mb_convert_case($tekMB_CASE_LOWER"UTF-8");
$baslik=$this->genelTemizlik($tek,array(mb_convert_case($dizinMB_CASE_LOWER"UTF-8")));
//başlık haline getir
$baslik=mb_convert_case($baslikMB_CASE_TITLE"UTF-8");
rename($this->dir.'/'.$dizin.'/'.$tek,$this->dir.'/'.$dizin.'/'.$baslik);
}
}
}

public function scandir($klasor)
{
$yeni=array();
$icerik=scandir($klasor);
foreach($icerik as $tek)
{
if($tek!="." && $tek!="..")
{
$yeni[]=$tek;
}
}
return $yeni;
}

public function genelTemizlik($baslik,$temizlik=array())
{

$donusum=array(
'þ'=>'ş',
'ý'=>'i',
"Ý"=>'i',
'ð'=>'ğ'

);
//tırnakları kaldır
$baslik=str_replace(array('"',"'",'/','#'),'',$baslik);
//alt tire, tire ve noktaları boşlukla değiştir
$baslik=str_replace(array('_',"-",'.'),' ',$baslik);
//çiğft boşlıkları kaldır
$baslik=str_replace('  ',' ',$baslik);
//notları falan temizle
$baslik=preg_replace('#\([A-Za-z0-9 ]+\)#','',$baslik);
$baslik=preg_replace('#\[[A-Za-z0-9 ]+\]#','',$baslik);
$baslik=str_replace(array('(',')','[',']'),'',$baslik);
$baslik=str_replace(array_keys($donusum),$donusum,$baslik);
$baslik=str_replace($temizlik,'',$baslik);
//numaraları sil
$baslik=preg_replace('#[0-9]+#','',$baslik);
$baslik=trim($baslik);
return $baslik;
}

function log($metin)
{
$this->log[]=$metin;
echo date("H.i.s").': '.$metin;
echo "\n";
}

}
$id3=new id3();

//$id3->tek();
$id3->islem();
?>



Uygylamayı çalıştırmak için
Kodları istediğiniz isimde bir php dosyasını kaydedin. Dosyayı müzik klasörünüze taşıyın.
Uygulamayı çalıştırmak için dosyaya sağ tıklayıp erişim seçeneklerinden bir program gibi çalıştırılmasına izin verin. cattr +x'de aynı şeyi sağlar.
Dosyayı uçbirimde açın. (uçbirime sürüklemeniz yeterli olacaktır.)

Neden yazdım
Çoğu kişinin kullanmayacağı, uğraşmayacağı bir uygulama. Benim ihtiyacım vardı yazdım. Ramazan beğendi. Belki ilginizi çeker dedim.

Lisans falan
Php dilini ben geliştirmedim. fizy benim değil. ne mp3 formatı ne id3 benim. Ben sadece farklı araçları bir araya getirdim. isteyen istediği gibi kullanabilir, dağıtabilir, değiştirebilir, satabilir, sevgilisine hediye edebilir.
Chmod bizim işimiz.

canosayan

İlk problemi de ben bildireyim. Tüm dosya isim ve taglar totemde ve smplayerda normal. Fakat banshee ile terbiyesizlik diz boyu.
Chmod bizim işimiz.

decent

Alıntı yapılan: canosayan - 10 Ekim 2011 - 01:23:58
İlk problemi de ben bildireyim. Tüm dosya isim ve taglar totemde ve smplayerda normal. Fakat banshee ile terbiyesizlik diz boyu.

Banshee belki çok iyidir fakat ben bugüne kadar kullanmadım diyebilirim.
Nadiren -yanlışlıkla- açıldığı olmuştur.
Sistemi yüklediğimde ilk olarak varsayılan müzik oynatıcı yetkilerini geri vermemek üzere elinden alırım.

QMMP ve UMPlayer ile de sınama imkanınız olabilir mi ?

alquirel

Düzenli bir müzik kütüphanem zaten olmadığı için etiketleri sonraki iş ama öğreticiliğinden dolayı çok teşekkür ediyorum. Eline sağlık

canosayan

Gelelim bazı medya oynatıcılarda yaşanan soruna id3v2 dediğimiz stanrdart temel karakter kümesini iso-8859-1 olarak belirlemiş. Bu kümede latin ingliz karakterleri var. Fakat daha sonraki güncellemelerde utf-16 ya kadar geliştirilmiş. Fakat id3v1 standardı halen kullanımda.
Şu an biz utf-8 kümesinde veri kaydı yapabiliyoruz. Bazı mdya oynatıcılar farklı karakter setlerinden verilerü okuyollar. örneğin nautilus, totem. Smplayerda böyle sorunlar yok. Fakat bazı uygulamalar sadece iso-8859-1 ile okuyor ve türkçe karakterler hata veriyor.

Bu sürüme 0.0.1 beta dersem 0.0.2 betada türkçe karakter kullanmayan oynatıcılar için bir ayar koyabilirim. Zaten yabancı bir ariiviniz varsa sorun yaamazsımız.
Chmod bizim işimiz.