修改mp3的id3 tag内容

清华大佬耗费三个月吐血整理的几百G的资源,免费分享!....>>>

#! /usr/bin/env python
# encoding: utf8
import sys
import os
import binascii
import json

def getId3Info(fp):
    id3Tags = []
    frameIds = ['AENC', 'APIC', 'COMM', 'COMR', 'ENCR', 'ETC0', 'GEOB', 'GRID', 'IPLS',
                'MCDI', 'MLLT', 'OWNE', 'PRIV', 'PCNT', 'POPM', 'POSS', 'RBUF', 'RVAD',
                'RVRB', 'SYLT', 'SYTC', 'TALB', 'TBPM', 'TCOM', 'TCON', 'TCOP', 'TDAT',
                'TDLY', 'TENC', 'TEXT', 'TFLT', 'TIME', 'TIT1', 'TIT2', 'TIT3', 'TKEY',
                'TLAN', 'TLEN', 'TMED', 'TOAL', 'TOFN', 'TOLY', 'TOPE', 'TORY', 'TOWM',
                'TPE1', 'TPE2', 'TPE3', 'TPE4', 'TPOS', 'TPUB', 'TRCK', 'TRDA', 'TRSN',
                'TRSO', 'TSIZ', 'TSRC', 'TSSE', 'TYER', 'TXXX', 'UFID', 'USER', 'USLT',
                'WCOM', 'WCOP', 'WOAF', 'WOAR', 'WOAS', 'WORS', 'WPAY', 'WPUB', 'WXXX']
    fp.read(10)
    while True:
        id3Info = {}
        tag = fp.read(4)
        if tag not in frameIds:
            break
        sizePos = fp.tell()
        binSize = fp.read(4)
        size = int(binascii.b2a_hex(binSize), 16)
        fp.read(2)
        conPos = fp.tell()
        cont = fp.read(size)
        id3Info['sizePos'] = sizePos
        id3Info['size'] = size
        id3Info['tag'] = tag
        id3Info['conPos'] = conPos
        id3Info['con'] = cont
        id3Tags.append(id3Info)
    return id3Tags

def getCon(id3Info, tag):
    for info in id3Info:
        if tag == info['tag']:
            return info['con']

def getConPos(id3Info, tag):
    for info in id3Info:
        if tag == info['tag']:
            return info['conPos']

def getConSize(id3Info, tag):
    for info in id3Info:
        if tag == info['tag']:
            return info['size']

def getConSizePos(id3Info, tag):
    for info in id3Info:
        if tag == info['tag']:
            return info['sizePos']

def writeInfo(path, tag, newCon):
    fp = open(path, 'rb')
    id3Info = getId3Info(fp)
    fp.seek(0)
    oldCon = getCon(id3Info, tag)
    size = getConSize(id3Info, tag)
    sizePos = getConSizePos(id3Info, tag)
    tmpSize = str(len(newCon) + 1)
    while(len(tmpSize) < 8):
        tmpSize = '0' + tmpSize
    newSize = binascii.a2b_hex(tmpSize)
    split = binascii.a2b_hex('0000')
    newCon = binascii.a2b_hex('00') + newCon

    pre = fp.read(sizePos)
    fp.seek(getConPos(id3Info, tag) + size)
    last = fp.read()

    newFile = pre + newSize + split + newCon + last

    p,n = os.path.split(path)
    b,l = os.path.splitext(n)
    newPath = os.path.join(p, b + "_" + newCon.strip('\x00') + l)
    newFp = open(newPath, 'wb')
    newFp.write(newFile)

    newFp.close()
    fp.close()
    return newPath

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print "用法: getGenre.py 新的genre mp3文件"
        exit()
    newCon = sys.argv[1]
    abspath = os.path.abspath(sys.argv[2])
    ret = writeInfo(abspath, "TCON", newCon)
    print ret + " OK"