1
0
mirror of https://github.com/l1ving/youtube-dl synced 2024-12-21 16:45:13 +08:00

Add metadata from title parser

(Closes #5125)
This commit is contained in:
phiresky 2015-03-04 22:33:56 +01:00 committed by Jaime Marquínez Ferrándiz
parent 082b1155a3
commit e7db87f700
5 changed files with 72 additions and 2 deletions

View File

@ -213,6 +213,11 @@ def _real_main(argv=None):
# PostProcessors # PostProcessors
postprocessors = [] postprocessors = []
# Add the metadata pp first, the other pps will copy it # Add the metadata pp first, the other pps will copy it
if opts.metafromtitle:
postprocessors.append({
'key': 'MetadataFromTitle',
'titleformat': opts.metafromtitle
})
if opts.addmetadata: if opts.addmetadata:
postprocessors.append({'key': 'FFmpegMetadata'}) postprocessors.append({'key': 'FFmpegMetadata'})
if opts.extractaudio: if opts.extractaudio:

View File

@ -735,6 +735,15 @@ def parseOpts(overrideArguments=None):
'--add-metadata', '--add-metadata',
action='store_true', dest='addmetadata', default=False, action='store_true', dest='addmetadata', default=False,
help='write metadata to the video file') help='write metadata to the video file')
postproc.add_option(
'--metadata-from-title',
metavar='FORMAT', dest='metafromtitle',
help='parse additional metadata like song title / artist from the video title. \n'
'The format syntax is the same as --output, '
'the parsed parameters replace existing values.\n'
'Additional templates: %(songtitle), %(album), %(artist). \n'
'Example: --metadata-from-title "%(artist)s - %(title)s" matches a title like '
'"Coldplay - Paradise"')
postproc.add_option( postproc.add_option(
'--xattrs', '--xattrs',
action='store_true', dest='xattrs', default=False, action='store_true', dest='xattrs', default=False,

View File

@ -15,6 +15,7 @@ from .ffmpeg import (
) )
from .xattrpp import XAttrMetadataPP from .xattrpp import XAttrMetadataPP
from .execafterdownload import ExecAfterDownloadPP from .execafterdownload import ExecAfterDownloadPP
from .metadatafromtitle import MetadataFromTitlePP
def get_postprocessor(key): def get_postprocessor(key):
@ -34,5 +35,6 @@ __all__ = [
'FFmpegPostProcessor', 'FFmpegPostProcessor',
'FFmpegSubtitlesConvertorPP', 'FFmpegSubtitlesConvertorPP',
'FFmpegVideoConvertorPP', 'FFmpegVideoConvertorPP',
'MetadataFromTitlePP',
'XAttrMetadataPP', 'XAttrMetadataPP',
] ]

View File

@ -541,11 +541,15 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
class FFmpegMetadataPP(FFmpegPostProcessor): class FFmpegMetadataPP(FFmpegPostProcessor):
def run(self, info): def run(self, info):
metadata = {} metadata = {}
if info.get('title') is not None: if info.get('songtitle') is not None:
metadata['title'] = info['songtitle']
elif info.get('title') is not None:
metadata['title'] = info['title'] metadata['title'] = info['title']
if info.get('upload_date') is not None: if info.get('upload_date') is not None:
metadata['date'] = info['upload_date'] metadata['date'] = info['upload_date']
if info.get('uploader') is not None: if info.get('artist') is not None:
metadata['artist'] = info['artist']
elif info.get('uploader') is not None:
metadata['artist'] = info['uploader'] metadata['artist'] = info['uploader']
elif info.get('uploader_id') is not None: elif info.get('uploader_id') is not None:
metadata['artist'] = info['uploader_id'] metadata['artist'] = info['uploader_id']
@ -554,6 +558,8 @@ class FFmpegMetadataPP(FFmpegPostProcessor):
metadata['comment'] = info['description'] metadata['comment'] = info['description']
if info.get('webpage_url') is not None: if info.get('webpage_url') is not None:
metadata['purl'] = info['webpage_url'] metadata['purl'] = info['webpage_url']
if info.get('album') is not None:
metadata['album'] = info['album']
if not metadata: if not metadata:
self._downloader.to_screen('[ffmpeg] There isn\'t any metadata to add') self._downloader.to_screen('[ffmpeg] There isn\'t any metadata to add')

View File

@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-
import re
from .common import PostProcessor
from ..utils import PostProcessingError
class MetadataFromTitlePPError(PostProcessingError):
pass
class MetadataFromTitlePP(PostProcessor):
def __init__(self, downloader, titleformat):
self._titleformat = titleformat
self._titleregex = self.fmtToRegex(titleformat)
def fmtToRegex(self, fmt):
"""
Converts a string like
'%(title)s - %(artist)s'
to a regex like
'(?P<title>.+)\ \-\ (?P<artist>.+)'
and a list of the named groups [title, artist]
"""
lastpos = 0
regex = ""
groups = []
# replace %(..)s with regex group and escape other string parts
for match in re.finditer(r'%\((\w+)\)s', fmt):
regex += re.escape(fmt[lastpos:match.start()])
regex += r'(?P<' + match.group(1) + '>.+)'
lastpos = match.end()
if lastpos < len(fmt):
regex += re.escape(fmt[lastpos:len(fmt)])
return regex
def run(self, info):
title = info['title']
match = re.match(self._titleregex, title)
if match is None:
raise MetadataFromTitlePPError('Could not interpret title of video as "%s"' % self._titleformat)
for attribute, value in match.groupdict().items():
value = match.group(attribute)
info[attribute] = value
self._downloader.to_screen('[fromtitle] parsed ' + attribute + ': ' + value)
return True, info