読者です 読者をやめる 読者になる 読者になる

ヨヨギ産のブログ

明日になったら、今日は過去。

.mp3、.m4aファイルに含まれるID3タグを読めなくするルーチン

http://www.flickr.com/photos/74796608@N00/4103986832
photo by garageolimpo

これ、仕事で、音源ファイルを扱う業務アプリに
組み込んで使うために作ったんですが、

mp3ファイルを管理するときって、
だいたい「iTunes」とかで管理するじゃないですか。

そうすると、各曲ファイルの「プロパティ」に、
個人的にいろいろメモしたりすることもあると思うんですね。

そうするとその情報は、ID3タグとして音源ファイル中に埋め込まれるわけで。。。

で、これを人に渡したりする場合、

自分でメモった情報を相手に「見られたくない」こともあったりするかもなので、
そんなとき、これを使って、iTune上では読めなくするわけです。

まあ、渡す相手がバイナリエディタを使ってたりすると意味ゼロなんですが(^^)
そんな人はいないよな~と勝手に解釈しつつ・・・。

とりあえずiTunes上のプロパティ項目には、ID3タグ情報は表示されなくなります。

ちなみに言語はVBAです。Access用に作ったので(^^;)
原理は単純なので、たぶん他の言語に移植するのも難しくないと思います。

Public Function id3_Remove(FilePath As String)

    'mp3ファイルとm4aファイルのID3タグを読めなくするルーチン
    'どんな処理を行ったかをメモって返す機能付き
    
    Dim msg As String
    Dim chgflg As Boolean
    chgflg = False
    
    Dim FSO As Object
    Set FSO = CreateObject("Scripting.FileSystemObject")
    
    'パスが存在しなければID3チェックしない
    If FSO.FileExists(FilePath) = False Then GoTo id3_remove_ret
    
    '拡張子がmp3、m4a以外はID3チェックしない
    If Not ext(Nz(FilePath)) = ".mp3" And Not ext(Nz(FilePath)) = ".m4a" Then GoTo id3_remove_ret
    
    'ID3タグ消し----------
    
    Dim sFPathIn As String '入力ファイル
    Dim sFPathOt As String '出力ファイル
    Dim lFileLen As Long 'ファイル長
    Dim iFileNo As Integer 'ファイル番号
    Dim yBuf() As Byte 'バイト配列
    Dim i As Long, j As Long
    
    'ファイル設定
    sFPathIn = FilePath
    sFPathOt = FilePath '※1
    '入力ファイル長取得
    lFileLen = FileLen(sFPathIn)
    'バイト配列確保
    ReDim yBuf(lFileLen - 1)
    'ファイル番号取得
    iFileNo = FreeFile
    '入力ファイルオープン
    Open sFPathIn For Binary As #iFileNo
    'バイト配列yBufにファイルデータ読込
    Get #iFileNo, , yBuf
    '入力ファイルクローズ
    Close #iFileNo
    
    'ID3v2.X用:バイナリの0~3バイト目が"ID3"の場合
    If yBuf(0) = "&H49" And yBuf(0) = "&H44" And yBuf(0) = "&H33" Then
        'ID3ヘッダエリアが終わったすぐ後(フレームエリアの始まり)のデータを壊すと、
        'ID3v2のフレーム内部の整合性が失われて、プロパティを表示しなくなる
        yBuf(10) = 0
        msg = msg & " ・ID3v2.Xタグを無効化しました。" & vbCrLf
        chgflg = True
    End If
    
    'iTunes製「m4a」 のメタデータ無効化:文字列"meta”があったらそれを&H00に編集
    If ext(Nz(FilePath)) = ".m4a" Then
        DoCmd.Hourglass True
        For j = 0 To lFileLen - 4
            If yBuf(j) = "&H6D" And yBuf(j + 1) = "&H65" And yBuf(j + 2) = "&H74" And yBuf(j + 3) = "&H61" Then
                yBuf(j) = "&H00"
                msg = msg & " ・iTunes用メタデータを無効化しました。" & vbCrLf
                chgflg = True
                Exit For
            End If
            '「mdat」より後ろは音声データなのでシーク動作を終了する
            If yBuf(j) = "&H6D" And yBuf(j + 1) = "&H64" And yBuf(j + 2) = "&H61" And yBuf(j + 3) = "&H74" Then Exit For
        Next j
        DoCmd.Hourglass False
    End If
    
    'ID3v1用:バイナリの最後128バイトがタグ:最後から128バイト目に文字列"TAG"があったらそれを&H00に編集
    If yBuf(lFileLen - 128) = "&H54" And yBuf(lFileLen - 127) = "&H41" And yBuf(lFileLen - 126) = "&H47" Then
        yBuf(lFileLen - 128) = "&H00"
        msg = msg & " ・ID3v1.Xタグを無効化しました。" & vbCrLf
        chgflg = True
    End If
    
    If chgflg Then
        'ファイル番号取得
        iFileNo = FreeFile
        '出力ファイルオープン
        Open sFPathOt For Binary Access Write As #iFileNo
        'データ書込
        Put #iFileNo, , yBuf
        '出力ファイルクローズ
        Close #iFileNo
    End If

id3_remove_ret:
    If Bchange = 0 Then msg = " ・ID3タグが見つかりませんでした。" & vbCrLf
    id3Remove = msg
    
End Function

使い方は?

このモジュールをAccessとかExcelとかの標準モジュールとして
音源ファイルのファイルパスを引数にして、呼び出します。

すると、指定されたファイルがmp3かm4aなら、
プレーヤー上でID3タグを見えないようにしてくれます。

呼び出し元にループ作って処理するようにすれば、
大量の音楽ファイルのID3タグを一気に不可視にできます。

ちなみに、ID3タグ的なものには「id3v1」「id3v2.X」「iTunesの独自タグ」があって
それらをすべて不可視にしています。

それと、このルーチンで
「世の中に存在するすべてのID3タグ」に対応しているか、というと
自信はありません。ごめんなさい<O>(と先に謝っておきます)

ID3タグって、世の中のいろいろなプレイヤーアプリで作られていて
独自仕様みたいなものもすさまじく多いので・・・。

まあ、最近のiTunesエンコードしたmp3・m4aファイルとかなら
これで大丈夫だと思います。

注意

コード中※1のところで、別のファイル名を作って指定すれば、別ファイルとして書き出します。
このコードのままだと、元ファイルを上書きしますので注意!です。

Apple iPod touch 32GB ホワイト&シルバー MD720J/A  <第5世代>

Apple iPod touch 32GB ホワイト&シルバー MD720J/A <第5世代>