Created
August 5, 2014 01:51
-
-
Save halloleo/d1b56f6826a8b09b8130 to your computer and use it in GitHub Desktop.
copying text tags between mp3 files using id3v2 as a back-end.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""id3copy - copy id3 (text) tags from mp3 file SRC to mp3 file DEST | |
usage: id3copy [-h] [-v... | -q] SRC DEST | |
options: | |
-h, --help show this help message and exit | |
-v, --verbose verbose output (give it twice for debug output) | |
-q, --quiet no information output | |
note 1: | |
this tool uses the program `id3v2` to read and then write the tags. it got | |
developed, because the `id3cp` program adds wrong characters into the text | |
tags. | |
note 2: | |
this tool writes only TEXT tags (no images, etc). therefore use `id3cp' | |
first and then correct the text tags with this tool. | |
""" | |
import os | |
import sys | |
import docopt | |
import atexit | |
import subprocess | |
def exename(): | |
exepath=sys.argv[0] | |
pathparts=exepath.split(os.sep) | |
return pathparts[-1] | |
args = {} | |
def get_tagtext(src): | |
tagtext = subprocess.check_output(['id3v2', '-l', src], universal_newlines=True, stderr=subprocess.STDOUT) | |
print_verbose("tagtext:\n%s" % tagtext) | |
return tagtext | |
# List of allow keys | |
ALLOWEDKEYS = ['IPLS', 'LINK', 'SYLT', 'TALB', 'TBPM', 'TCOM', 'TCOP', 'TDAT', 'TDLY', 'TENC', 'TEXT', 'TIME', 'TIT2', 'TIT3', 'TKEY', 'TLAN', 'TOAL', 'TOFN', 'TOLY', 'TOPE', 'TORY', 'TOWN', 'TPE1', 'TPE2', 'TPE3', 'TPE4', 'TPUB', 'TRCK', 'TRDA', 'TRSN', 'TRSO', 'TSSE', 'TXXX', 'TYER', 'USER', 'USLT', 'WCOM', 'WCOP', 'WOAF', 'WOAR', 'WOAS', 'WORS', 'WPUB', 'WXXX'] | |
# Seperator of comment from real value | |
INVALUESEP = ": " | |
def get_tagdict(tagtext): | |
tagdict = {} | |
pre=True | |
try : | |
for line in tagtext.splitlines(): | |
if pre: | |
if line.find("id3v2 tag info for")>=0: | |
pre=False | |
else: | |
(k, v) = line.split(" ", 1) | |
if k in ALLOWEDKEYS: | |
i = v.find(INVALUESEP) | |
if i >= 0: | |
v = v[i+len(INVALUESEP):] | |
print_verbose("keep frame '%s' with value '%s'" % (k,v)) | |
tagdict[k]=v | |
else: | |
print_verbose("cannot copy frame '%s'" % k) | |
except ValueError, e: | |
raise ValueError("cannot read id3 information properly") | |
if pre==True: | |
# raise exception if no id3(v2) information found (either no present or fopen error or... ) | |
raise ValueError("no id3 information found") | |
print_verbose (tagdict) | |
return tagdict | |
def apply_tagdict(dest, tagdict): | |
for k in tagdict: | |
v = tagdict[k] | |
print_verbose("write frame '%s' with value '%s'" % (k, v)) | |
tagtext = subprocess.check_call(['id3v2', '--%s' % k, v, dest], stderr=subprocess.STDOUT) | |
def work(): | |
src = args['SRC'] | |
dest = args['DEST'] | |
tagtext = get_tagtext(src) | |
tagdict = get_tagdict(tagtext) | |
apply_tagdict(dest, tagdict) | |
def print_verbose(msg): | |
if args['--verbose']: | |
print("--- %s" % str(msg)) | |
if __name__ == '__main__': | |
try: | |
args = docopt.docopt(__doc__, version='0.1.0') | |
print_verbose("args:\n%s" % str(args)) | |
work() | |
except docopt.DocoptExit as e: | |
print ("%s: wrong commandline" % exename()) | |
print (str(e)) | |
print ("try '%s -h' for more information." % exename()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment