FC2ブログ

ホーム > MP3ファイルフォーマット > ID3タグの書き込み 第3部

ID3タグの書き込み 第3部



「ID3タグの書き込み 第3部」では、MFCを使った用例とサンプルプログラムを紹介します。



ID3タグの内容を表示したリストビューを右クリックした際に、ポップアップメニューを出す関数です。

//リストビュー右クリックイベント処理
void CMp3PropDlg::OnNMRclickListId3tag(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
//現在カーソルがある行を求めて、メンバー変数に保存します。

CPoint point,ptList;
::GetCursorPos(&point);
ptList=point;
m_listID3Tag.ScreenToClient(&ptList);
m_iItemClicked=m_listID3Tag.HitTest(ptList);

//ポップアップメニューをロードします。
CMenu menu;
if (menu.LoadMenu(IDR_MENU_POPUP)){
CMenu* pMenuPopup=menu.GetSubMenu(0);
if (pMenuPopup) pMenuPopup->TrackPopupMenu(TPM_LEFTBUTTON,point.x,point.y,this);
}
//メニューを破棄
menu.DestroyMenu();

*pResult = 0;
}


ID3タグに新規フレームを挿入する関数です。

//新規フレームの挿入
void CMp3PropDlg::OnPopupInsertframe()
{
// TODO: Add your command handler code here
//現在読み込んだID3v1/v2タグのフレーム総数を取得します。

ASSERT((m_pId3v1)&&(m_pId3v2));
int v1frames=m_pId3v1->GetFrameCount();
int v2frames=m_pId3v2->GetFrameCount();
UINT nframes=v1frames+v2frames;
//フレームがなければ、新たにID3v2タグを作成します。
if (!nframes) m_pId3v2->TagNew();

//クリックされた行を、メンバー変数から取り出します。
int iItem=m_iItemClicked;
//初期設定
CID3File* pID3File=m_pId3v2;
CByteArray* pByteID3=&m_pMP3File->m_byteId3v2;
//クリックされた行が範囲外なので、末尾に追加します。
if ((m_iItemClicked<0)||((UINT)m_iItemClicked>=nframes)){
iItem=v2frames;
//id3v1だけでフレーム数が7未満の時
if ((!v2frames)&&(v1frames)&&(v1frames<7)){
iItem=v1frames;
pID3File=m_pId3v1;
pByteID3=&m_pMP3File->m_byteId3v1;
}
}
//ID3v1フレームがある場合。
else if (v1frames){
//クリックされた行がID3v1の場合。
if (m_iItemClicked<v1frames){
pID3File=m_pId3v1;
pByteID3=&m_pMP3File->m_byteId3v1;
}
//それ以外は、クリックされた行からID3v1のフレーム数を差し引きます。
//※ID3v1をすべて書き込んだ後に、ID3v2タグのフレーム内容が書き込まれているため。

else iItem-=v1frames;
}
//フレーム編集ダイヤログを起動します。
CEditFrameDlg dlg(pID3File,iItem,this,TRUE);
//「適用ボタン」が押されて、新たに作成したフレームの書き込みに成功した場合。
if ((dlg.DoModal()==IDOK)&&(pID3File->SetFrame(iItem))){
//タグバージョンに変更がある場合は、タグバージョンを再設定します。
SetTagVersion(pID3File,iItem);
//CMP3FileクラスのID3タグの生データを格納するメンバー変数を、それぞれ書き換えます。
m_pId3v1->Update(&m_pMP3File->m_byteId3v1);
m_pId3v2->Update(&m_pMP3File->m_byteId3v2);
//ID3タグの内容変更フラグを立てます。
m_bID3TagModified=TRUE;
}
//リストビューを更新します。
UpdateListView(m_iItemClicked);
}


ID3タグの指定行フレームを編集する関数です。

//指定行フレームの編集
void CMp3PropDlg::OnPopupEditframe()
{
// TODO: Add your command handler code here
ASSERT((m_pId3v1)&&(m_pId3v2));
//カーソルが、リストビューの有効なアイテム上にある場合。
if (m_iItemClicked>=0){
//現在読み込んだID3v1/v2タグのフレーム総数を取得します。
int v1frames=m_pId3v1->GetFrameCount();
int v2frames=m_pId3v2->GetFrameCount();
//クリックされた行のフレームが有効な場合、編集するID3タグを選択します。
if (m_iItemClicked<(v1frames+v2frames)){
int iItem=m_iItemClicked;
CID3File* pID3File=m_pId3v2;
CByteArray* pByteID3=&m_pMP3File->m_byteId3v2;
//ID3v1タグがある場合。
if (v1frames){
//クリックされた行がID3v1の場合。
if (m_iItemClicked<v1frames){
pID3File=m_pId3v1;
pByteID3=&m_pMP3File->m_byteId3v1;
}
//それ以外は、クリックされた行からID3v1のフレーム数を差し引きます。
//※ID3v1をすべて書き込んだ後に、ID3v2タグのフレーム内容が書き込まれているため。

else iItem-=v1frames;
}
//フレーム編集ダイヤログを起動します。
CEditFrameDlg dlg(pID3File,iItem,this);
//「適用ボタン」が押されて、新たに作成したフレームの書き込みに成功した場合。
if ((dlg.DoModal()==IDOK)&&(pID3File->SetFrame(iItem))){
//タグバージョンに変更がある場合は、タグバージョンを再設定します。
SetTagVersion(pID3File,iItem);
//CMP3FileクラスのID3タグの生データを格納するメンバー変数を、それぞれ書き換えます。
m_pId3v1->Update(&m_pMP3File->m_byteId3v1);
m_pId3v2->Update(&m_pMP3File->m_byteId3v2);
//ID3タグの内容変更フラグを立てます。
m_bID3TagModified=TRUE;
}
//リストビューを更新します。
UpdateListView(m_iItemClicked);
}
}
}


ID3タグの指定行フレームを削除する関数です。

//指定行フレームの削除
void CMp3PropDlg::OnPopupDeleteframe()
{
// TODO: Add your command handler code here
ASSERT((m_pId3v1)&&(m_pId3v2));
//カーソルが、リストビューの有効なアイテム上にある場合。
if (m_iItemClicked>=0){
//現在読み込んだID3v1/v2タグのフレーム総数を取得します。
int v1frames=m_pId3v1->GetFrameCount();
int v2frames=m_pId3v2->GetFrameCount();
//クリックされた行のフレームが有効な場合、編集するID3タグを選択します。
if (m_iItemClicked<(v1frames+v2frames)){
int iItem=m_iItemClicked;
CID3File* pID3File=m_pId3v2;
CByteArray* pByteID3=&m_pMP3File->m_byteId3v2;
//ID3v1タグがある場合。
if (v1frames){
//クリックされた行がID3v1の場合。
if (m_iItemClicked<v1frames){
pID3File=m_pId3v1;
pByteID3=&m_pMP3File->m_byteId3v1;
}
//それ以外は、クリックされた行からID3v1のフレーム数を差し引きます。
//※ID3v1をすべて書き込んだ後に、ID3v2タグのフレーム内容が書き込まれているため。

else iItem-=v1frames;
}
//フレームの内容を取得します。
pID3File->GetFrame(iItem);
//メッセージボックスを出して、ユーザーに削除の確認を促します。
CString strMessage;
strMessage.Format(_T("%d行目の[%s]フレームを削除します。宜しいですか?"),
m_iItemClicked+1,pID3File->m_strID);
int res=MessageBox(strMessage.GetBuffer(),_T("フレームの削除"),MB_OKCANCEL);
if (res==IDOK){
//指定行のフレームを削除します。
pID3File->DeleteFrame(iItem);
//残りの行がない場合は、ID3タグごとを削除します。
if (pID3File->GetFrameCount()==0){
pID3File->Delete();
//CMP2Fileクラスの生データも削除します。
if (pID3File==m_pId3v1) m_pMP3File->m_byteId3v1.RemoveAll();
else m_pMP3File->m_byteId3v2.RemoveAll();
}
else
//CMP3FileクラスのID3タグの生データを格納するメンバー変数を、書き換えます。
pID3File->Update(pByteID3);

//ID3タグの内容変更フラグを立てます。
m_bID3TagModified=TRUE;
}
//リストビューを更新します。
UpdateListView(m_iItemClicked);
}
}
}


CMP3FileクラスID3タグの生データをMP3ファイルに書き込む関数です。

//ID3タグの生データをMP3ファイルに書き込みます。
void CMp3PropDlg::OnBnClickedButtonSaveID3tag()
{
// TODO: Add your control notification handler code here
ASSERT(m_pMP3File->IsMp3File());
//演奏中なら停止させます。
BOOL bActive=m_pMP3File->IsActivate();
BOOL bPaused=m_pMP3File->IsPaused();
UINT pos=m_pMP3File->GetPos();
if (bActive) m_pMP3File->Stop();

//現在のID3タグの生データを保存します。
m_pMP3File->SaveID3Tag();

//ファイルを開いて以前の状態に戻します。
m_pMP3File->OpenFile(m_pMP3File->GetPathName());
m_pMP3File->SetPos(pos);
if (bActive) m_pMP3File->Play();
if (bPaused) m_pMP3File->Pause();

//ID3タグの内容変更フラグをクリアします。
m_bID3TagModified=FALSE;

//リストビューを更新します。
UpdateListView(m_iItemClicked);
}


現在保持しているすべてのID3タグを削除します。

//すべてのID3タグの削除
void CMp3PropDlg::OnPopupDeletetag()
{
// TODO: Add your command handler code here
ASSERT((m_pId3v1)&&(m_pId3v2));
//メッセージボックスを出して、ユーザーに削除の確認を促します。
int res=MessageBox(_T("すべてのタグの内容を削除します。宜しいですか?"),
_T("タグの削除"),MB_OKCANCEL);
if (res==IDOK){
//すべてのID3タグを削除します。
m_pId3v1->Delete();
m_pId3v2->Delete();
//CMP3FileクラスのID3タグの生データもすべて削除します。
m_pMP3File->m_byteId3v1.RemoveAll();
m_pMP3File->m_byteId3v2.RemoveAll();
}
}


指定行にあるフレームのID3タグのバージョン変更をするPrivate関数です。

//タグバージョンの設定
BOOL CMp3PropDlg::SetTagVersion(CID3File* pID3File,int iItem)
{
ASSERT(pID3File);
//現在のタグバージョン文字列を取得します。
CStringA strVersion;
pID3File->TagVersion(strVersion);
//タグバージョンに変更がない場合は、何もせずに終了します。
if (strVersion==pID3File->m_strVersion) return TRUE;
//対象のタグがID3v1タグで、ID3v2に変更する場合。
if ((pID3File==m_pId3v1)&&(pID3File->m_strVersion.Find("ID3v2")!=-1))
{
//ID3v2タグがない場合は新たに作成し、ID3タグのバージョンを変更します。
if (m_pId3v2->GetFrameCount()==0){
m_pId3v2->TagNew();
m_pId3v2->SetTagVersion(pID3File->m_strVersion);
}
//ID3v1タグから対象のフレームを切り離して、ID3v2タグの末尾に追加します。
return m_pId3v2->InsertFrame(-1,pID3File->DetachFrame(iItem));
}
//対象のタグがID3v2タグで、ID3v1タグに変更する場合。
else if (pID3File->m_strVersion.Find("ID3v1")!=-1){
//ID3v1タグがない場合は新たに作成し、ID3タグのバージョンを変更します。
if (m_pId3v1->GetFrameCount()==0){
m_pId3v1->TagNew();
m_pId3v1->SetTagVersion(pID3File->m_strVersion);
}
//ID3v2タグから対象のフレームを切り離して、ID3v1タグの末尾に追加します。
return m_pId3v1->InsertFrame(-1,pID3File->DetachFrame(iItem));
}
//マイナーバージョンのみ変更する場合
return pID3File->SetTagVersion(pID3File->m_strVersion);
}


最後にID3タグの生データを書き込んだCMP3FileクラスCByteArrayクラスのメンバー変数を、MP3ファイルに書き込む関数です。

//ID3tagを現在のファイルに保存します。
inline BOOL CMP3File::SaveID3Tag()
{
return SaveFile(m_strPathName);
}



サンプルプログラム(VisualC++net2003ソリューション)MP3FileTest03.zip

上記のzipファイルをダウンロードして、「libid3tagのインストール」で作成した「libid3tag-0.15.1b」フォルダーと「zlib」フォルダーがある同じフォルダー内にWinRAR等を使って解凍すると、「MP3FileTest03」という名のフォルダーが作成されます。



「MP3FileTest03」フォルダー内にある「MP3FileTest.sln」を開いて「F5」キーを押すと、ビルド確認のダイヤログが表示されるので「Yes」を選択してソリューションをビルドします。



ビルドが終わると直ちにプログラムが自動起動して下の図にあるダイヤログが表示されます。



ダイヤログにある「ファイルを開く」ボタンを押すと、「ファイルを開く」ダイヤログが表示されます。



ID3タグのないMP3ファイルを選択し「開く」ボタンを押すと、コンボボックスにファイル名が表示され、スライドバーの動きに合わせて、MP3ファイルが再生されます。同時に「MP3のプロパティ」ダイヤログが表示されますが、リストビューには何も表示されません。



ここで「PAUSE」ボタンを押して演奏を一時停止させてから、リストビューの適当な行を右クリックしてポップアップメニューを表示させ、「新規フレームの挿入」を選択します。



「フレームの挿入」ダイヤログが表示されたところで、「ブラウズ」ボタンを押して適当な画像(JPEG画像もしくはPNG画像)を選択して「適用する」ボタンを押します。



引き続いて、入力した画像フレームの上に曲名、演奏者、アルバム名等のフレームを挿入します。



必要なフレームを書き終えたら、ポップアップメニューから「ファイルに書き込む」を選択してファイルに書き込みます。プログラムを終了してから、再度「F5」キーを押してプログラムを再起動させ、先ほど入力したID3タグが正しく表示されるか確認して下さい。



<<ID3タグの書き込み 第2部ページの先頭LAME ACMのインストール>>


スポンサーサイト



コメント: 0

この記事へのコメント
ブログ著者にのみ知らせます。

Trackback+Pingback: 0

TrackBack URL for this entry
http://hiroshi0945.blog75.fc2.com/tb.php/61-2b09937e
Listed below are links to weblogs that reference
ID3タグの書き込み 第3部 from マルチメディアファイルフォーマット

Home > MP3ファイルフォーマット > ID3タグの書き込み 第3部

タグクラウド
ブロとも申請フォーム

この人とブロともになる

ブロとも一覧

このページの先頭へ戻る