FC2ブログ

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

ID3タグの書き込み(id3lib) 第2部



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

ID3タグの内容を表示したリストビューにおいて、選択された行のID3タグフレームの内容を削除します。

void CID3TabSheet::OnMetaDelete()
{
// TODO: Add your command handler code here
DoDelete();
}

BOOL CID3TabSheet::DoDelete()
{
//現在選択されている行を取得します。
int index=-1;
CUIntArray listItem;
while((index=m_listMeta.GetNextItem(index,LVNI_ALL|LVNI_SELECTED))!=-1)
listItem.Add(index);

//選択された行がなければ、終了します。
int nCount=(int)listItem.GetCount();
if (!nCount) return FALSE;

//選択された行を削除します。
for(int i=nCount-1;i>=0;i--){
UINT item=listItem.GetAt(i);
m_pID3Tag->DeleteFrame(item);
}

//CMP3FileクラスのID3タグの生データを格納するメンバー変数を、書き換えます。
m_pID3Tag->Update(GetID3RawData());
m_pDlgProp->SetModify();
Update(listItem.GetAt(0));
return TRUE;
}


ID3タグの内容を表示したリストビューにおいて、選択された行のID3タグフレームの内容をクリップボードに取り込む関数です。

void CID3TabSheet::OnMetaCopy()
{
// TODO: Add your command handler code here
DoCopy();
}

void CID3TabSheet::OnMetaCut()
{
// TODO: Add your command handler code here
DoCopy();
DoDelete();
}

//リストビューにおいて現在選択されている行を、クリップボードに取り込みます。
BOOL CID3TabSheet::DoCopy()
{
CStringA strACSV;
//フレームの内容を格納した文字列を、CSV文字列に変換します。
int item=-1;
while((item=m_listMeta.GetNextItem(item,LVNI_ALL|LVNI_SELECTED))!=-1){
m_pID3Tag->GetFrame(item);
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strID));
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strTitle));
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strDesc));
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strText));
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strTextEnc));
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strImmediate));
//バイナリーデータをダンプテキスト文字列に変換します。
int length=m_pID3Tag->m_strBinary.GetAllocLength();
BYTE* binary=(BYTE*)m_pID3Tag->m_strBinary.GetBuffer();
CString strBinaryText=g_BinaryToDumpText(binary,length);

strACSV.AppendFormat("%s,",_StringToCSVA(strBinaryText));
strACSV.AppendFormat("%s,",_StringToCSVA(m_pID3Tag->m_strTimeStamp));
strACSV.AppendFormat("%s\r\n",_StringToCSVA(m_pID3Tag->m_strPictureName));
}
int length=strACSV.GetLength();
if (!length) return FALSE;

// クリップボードのオープン
if(!::OpenClipboard(m_hWnd)) return FALSE;
::EmptyClipboard(); // クリップボードの中身を空にする

//メモリ領域を確保し、文字列をコピー
HGLOBAL hText=::GlobalAlloc(GHND,length+1);
char* pText=(char*)::GlobalLock(hText);
::strcpy(pText,strACSV.GetBuffer());

// クリップボードへ文字列をコピーし、クローズ
::SetClipboardData(CF_TEXT,hText);
::CloseClipboard();
return TRUE;
}

//文字列をCSV文字列に変換します。
CStringA __stdcall _StringToCSVA(CString& str)
{
CStringA strA=(CStringA)str;
CStringA strAResult;
strAResult.AppendChar('"');
int length=strA.GetLength();
for(int i=0;i<length;i++){
char ch=strA[i];
if (ch==0) break;
strAResult.AppendChar(ch);
if (ch=='"') strAResult.AppendChar('"');
}
strAResult.AppendChar('"');
strAResult.ReleaseBuffer();
return strAResult;
}


現在クリップボードに取り込まれているリストビューの内容を、ID3タグに貼り付けます。

void CID3TabSheet::OnMetaPaste()
{
// TODO: Add your command handler code here
DoPaste();
}

//クリップボードの内容を指定行のリストに書き込む
BOOL CID3TabSheet::DoPaste()
{
//現在選択されている行を取得します。
int index=-1;
CUIntArray listItem;
while((index=m_listMeta.GetNextItem(index,LVNI_ALL|LVNI_SELECTED))!=-1)
listItem.Add(index);

//選択された行があれば、その最上位行を貼り付け位置とし、
//なければ、最後尾行を貼り付け位置とします。

INT_PTR nCount=listItem.GetCount();
int indexInsert=(nCount>0)?listItem.GetAt(0):m_listMeta.GetItemCount();

//選択された行が複数あれば、削除します。
if (nCount>1) DoDelete();

// クリップボードのオープン
if(!::OpenClipboard(m_hWnd)) return FALSE;
BOOL bResult=FALSE;
HANDLE hText=::GetClipboardData(CF_TEXT);
CStringA strACSV;
int iItem=indexInsert;
if (hText){
//ID3タグがまだない場合
if (!m_pID3Tag->GetFrameCount()) m_pID3Tag->TagNew(ID3TagVersionSuggest());

SIZE_T size=::GlobalSize(hText);
LPTSTR lpsz=strACSV.GetBufferSetLength((int)(INT_PTR)size);
char* pText=(char*)::GlobalLock(hText);
::strcpy(lpsz,pText);
::GlobalUnlock(hText);
//CSV文字列をメンバー変数文字列に変換します。
int iStart=0;
while(TRUE){
if ((iStart=_CSVAToString(m_pID3Tag->m_strID,strACSV,iStart))==-1) break;
if ((iStart=_CSVAToString(m_pID3Tag->m_strTitle,strACSV,iStart))==-1) break;
if ((iStart=_CSVAToString(m_pID3Tag->m_strDesc,strACSV,iStart))==-1) break;
if ((iStart=_CSVAToString(m_pID3Tag->m_strText,strACSV,iStart))==-1) break;
if ((iStart=_CSVAToString(m_pID3Tag->m_strTextEnc,strACSV,iStart))==-1) break;
if ((iStart=_CSVAToString(m_pID3Tag->m_strImmediate,strACSV,iStart))==-1) break;

CString strBinaryText;
if ((iStart=_CSVAToString(strBinaryText,strACSV,iStart))==-1) break;
//ダンプテキストからバイナリーデータに変換します。
int length=g_DumpTextToBinary(NULL,strBinaryText);
PBYTE buffer=(PBYTE)m_pID3Tag->m_strBinary.GetBufferSetLength(length/sizeof(TCHAR));
g_DumpTextToBinary(buffer,strBinaryText);

if ((iStart=_CSVAToString(m_pID3Tag->m_strTimeStamp,strACSV,iStart))==-1) break;
if ((iStart=_CSVAToString(m_pID3Tag->m_strPictureName,strACSV,iStart))==-1) break;

//画像フレームの場合
if ((strBinaryText.GetLength())&&
((m_pID3Tag->m_strID==_T("PIC"))||(m_pID3Tag->m_strID==_T("APIC"))))
{
//画像のMIMETYPEを取得します。
::g_GetFileType(m_pID3Tag->m_strImmediate,buffer);

CString strVersion;
//ID3v2.2の場合、MIMETYPEからIMAGEFORMATに変換します。
m_pID3Tag->TagVersion(strVersion);
if (strVersion.Find(_T("ID3v2.2"))>=0)
{
if (m_pID3Tag->m_strImmediate==_T("image/jpeg"))
m_pID3Tag->m_strImmediate=_T("JPG");
else if (m_pID3Tag->m_strImmediate==_T("image/png"))
m_pID3Tag->m_strImmediate=_T("PNG");
else if (m_pID3Tag->m_strImmediate==_T("image/gif"))
m_pID3Tag->m_strImmediate=_T("GIF");
}
}
//新規フレームを挿入します。
m_pID3Tag->InsertFrameNew(iItem,m_pID3Tag->m_strID);
//フレームにクリップボードデータを設定します。
if (!m_pID3Tag->SetFrame(iItem))
//設定に失敗したら、削除します。
m_pID3Tag->DeleteFrame(iItem);
else iItem++;
}
}
::CloseClipboard();
if (iItem==indexInsert) return FALSE;

//CMP3FileクラスのID3タグの生データを格納するメンバー変数を、書き換えます。
m_pID3Tag->Update(GetID3RawData());
m_pDlgProp->SetModify();
Update(iItem);
return TRUE;
}

//CSV文字列の指定開始位置から1カラム分の文字列を取得します。
int __stdcall _CSVAToString(CString& str,const char* pText,int iStart)
{
ASSERT(AfxIsValidAddress(pText,iStart,FALSE));
CStringA strA;
int i=iStart;
char ch;
while((ch=pText[i++])!='\0'){
if (i==iStart+1){
if (ch!='"') return -1;
}
else if (ch=='"'){
if (pText[i]==','){
str=strA;
return ++i;
}
else if ((pText[i]=='\r')&&(pText[i+1]=='\n')){
str=strA;
return i+2;
}
else if (pText[i]=='"'){
i++;
strA.AppendChar(ch);
}
}
else strA.AppendChar(ch);
}
return -1;
}



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

上記のzipファイルをダウンロードして、「id3libのインストール」で作成した「id3lib-3.8.3」フォルダーと「ID3タグの読み込み(id3lib) 第3部」で作成した「MP3FileTest05R」フォルダーがある同じフォルダー内にWinRAR等を使って解凍すると、「MP3FileTest05W」という名のフォルダーが作成されます。



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



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




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



ID3タグの入ったMP3ファイルを選択し「開く」ボタンを押すと、コンボボックスにファイル名が表示され、スライドバーの動きに合わせて、MP3ファイルが再生されます。同時に「MP3のプロパティ」ダイヤログが表示され、画像があればメインダイヤログ上部に表示されます。


sideback




ここで「PAUSE」ボタンを押して演奏を一時停止させてから、ID3v2.3タブに表示されたリストビューの内容を「Ctrl+A」キーを押してすべて選択し、「Ctrl+C」キーでID3v2.3タグの内容をクリップボードにコピーします。



ID3v1タブを開いて「Ctrl+A」キーを押してすべての行を選択し、先ほどクリップボードにコピーしたID3v2.3タグの内容を「Ctrl+V」キーで貼り付けます。



ID3v2.2タブとID3v2.4タブについても同様に、ID3v2.3タグの内容を「Ctrl+V」キーで貼り付けます。



最後に「リストの内容をファイルに保存」ボタンを押してID3タグの内容をファイルに保存します。プログラムを終了してから、再度「F5」キーを押してプログラムを再起動させ、先ほど貼り付けたID3v2.3タグの内容がそれぞれのバージョンタグに正しくコピーされているか確認して下さい。


sideback




スポンサーサイト



コメント: 0

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

Trackback+Pingback: 0

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

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

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

この人とブロともになる

ブロとも一覧

このページの先頭へ戻る