Well, I didn't get tagging to work w/ older mpg files, but if you have mp4/m4v video files and you want to manually tag them by pulling data out of the sidecar file, here's a script that should work. Also supports adding/embedding cover art. Should be pretty self-explanatory, couple of bits of twisty logic to handle date conversion...
#!/bin/env python
import mutagen
from mutagen.mp4 import *
import xml.etree.ElementTree as ET
import sys
import string
import optparse
# Modified Julian to DMY calculation with an addition of 2415019
# algorithm from
http://www.hermetic.ch/cal_stud/jdn.htmdef cvt_serial_date(serial_date):
l = int(serial_date) + 68569 + 2415019
n = ( 4 * l ) / 146097
l = l - (( 146097 * n + 3 ) / 4)
i = ( 4000 * ( l + 1 ) ) / 1461001
l = l - (( 1461 * i ) / 4) + 31
j = ( 80 * l ) / 2447
day = l - (( 2447 * j ) / 80)
l = j / 11
month = j + 2 - ( 12 * l )
year = 100 * ( n - 49 ) + i + l
return year, month, day
# parse XML file and update video file w/ known tags
def update_video_tags(video_file, xml_file):
modified = False
# parse the XML file
xml = ET.parse(xml_file)
# parse/open the video file w/ mutagen
video = mutagen.File(video_file)
tag_map = {
'Genre': '\xa9gen',
'Description': 'desc',
'Name': '\xa9nam',
'Keywords': 'keyw',
'Date': '\xa9day',
}
# traverse each field, matching against known tags
for field in xml.findall('./Item/Field'):
name = field.attrib.get('Name', '')
value = field.text
if name in tag_map:
tag_key = tag_map[name]
# special handling for date to convert
if name == 'Date':
y,m,d = cvt_serial_date(value)
value = [str(y)]
# otherwise... handle lists
elif ';' in value:
fields = value.split(';')
value = map(string.strip, fields)
# update tag if different
if video.get(tag_key) != value:
print 'adding tag: %s w/ value %s' % (tag_key, value)
video[tag_key] = value
modified = True
# save changes (if changes made)
if modified:
video.save()
def add_art(video_file, cover_file):
# parse/open the video file w/ mutagen
video = mutagen.File(video_file)
# load cover art
covr = []
data = open(cover_file, 'rb').read()
if cover_file.endswith('png'):
covr.append(MP4Cover(data, MP4Cover.FORMAT_PNG))
else:
covr.append(MP4Cover(data, MP4Cover.FORMAT_JPEG))
video['covr'] = covr
# save changes (if changes made)
video.save()
## MAIN
if __name__ == '__main__':
parser = optparse.OptionParser(
option_list = [
optparse.make_option("-x", "--xml", action="store", type="string",
help="XML file", default=None),
optparse.make_option("-v", "--video", help="video file",
default=None),
optparse.make_option("-c", "--cover", help="cover art jpg file",
default=None),
])
(options, args) = parser.parse_args()
if not options.xml or not options.video:
print 'missing required xml or video parameter'
sys.exit(1)
update_video_tags(options.video, options.xml)
if options.cover:
add_art(options.video, options.cover)