mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-09 19:00:39 +00:00
[ie] Add new fields with proper support for multiple values
This commit is contained in:
parent
85b33f5c16
commit
071326c0cc
@ -24,6 +24,7 @@ import traceback
|
|||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
from .cache import Cache
|
from .cache import Cache
|
||||||
|
|
||||||
from .compat import functools, urllib # isort: split
|
from .compat import functools, urllib # isort: split
|
||||||
from .compat import compat_os_name, compat_shlex_quote, urllib_req_to_req
|
from .compat import compat_os_name, compat_shlex_quote, urllib_req_to_req
|
||||||
from .cookies import LenientSimpleCookie, load_cookies
|
from .cookies import LenientSimpleCookie, load_cookies
|
||||||
@ -1735,6 +1736,7 @@ class YoutubeDL:
|
|||||||
'_type': 'compat_list',
|
'_type': 'compat_list',
|
||||||
'entries': ie_result,
|
'entries': ie_result,
|
||||||
}
|
}
|
||||||
|
self.fix_deprecated_fields(ie_result)
|
||||||
if extra_info.get('original_url'):
|
if extra_info.get('original_url'):
|
||||||
ie_result.setdefault('original_url', extra_info['original_url'])
|
ie_result.setdefault('original_url', extra_info['original_url'])
|
||||||
self.add_default_extra_info(ie_result, ie, url)
|
self.add_default_extra_info(ie_result, ie, url)
|
||||||
@ -1744,6 +1746,19 @@ class YoutubeDL:
|
|||||||
else:
|
else:
|
||||||
return ie_result
|
return ie_result
|
||||||
|
|
||||||
|
def fix_deprecated_fields(self, ie_result):
|
||||||
|
deprecated_multivalue_fields = {
|
||||||
|
'artist': 'artist_list',
|
||||||
|
'composer': 'composer_list',
|
||||||
|
'album_artist': 'album_artist_list',
|
||||||
|
'genre': 'genre_list',
|
||||||
|
}
|
||||||
|
for deprecated_field, new_field in deprecated_multivalue_fields.items():
|
||||||
|
if deprecated_field not in ie_result:
|
||||||
|
continue
|
||||||
|
self.deprecation_warning(f'"{deprecated_field}" field is deprecated. Use "{new_field}" instead')
|
||||||
|
ie_result[new_field] = re.split(r', ?', ie_result[deprecated_field])
|
||||||
|
|
||||||
def add_default_extra_info(self, ie_result, ie, url):
|
def add_default_extra_info(self, ie_result, ie, url):
|
||||||
if url is not None:
|
if url is not None:
|
||||||
self.add_extra_info(ie_result, {
|
self.add_extra_info(ie_result, {
|
||||||
@ -3918,10 +3933,9 @@ class YoutubeDL:
|
|||||||
|
|
||||||
# These imports can be slow. So import them only as needed
|
# These imports can be slow. So import them only as needed
|
||||||
from .extractor.extractors import _LAZY_LOADER
|
from .extractor.extractors import _LAZY_LOADER
|
||||||
from .extractor.extractors import (
|
from .extractor.extractors import _PLUGIN_CLASSES as plugin_ies
|
||||||
_PLUGIN_CLASSES as plugin_ies,
|
from .extractor.extractors import \
|
||||||
_PLUGIN_OVERRIDES as plugin_ie_overrides
|
_PLUGIN_OVERRIDES as plugin_ie_overrides
|
||||||
)
|
|
||||||
|
|
||||||
def get_encoding(stream):
|
def get_encoding(stream):
|
||||||
ret = str(getattr(stream, 'encoding', 'missing (%s)' % type(stream).__name__))
|
ret = str(getattr(stream, 'encoding', 'missing (%s)' % type(stream).__name__))
|
||||||
|
@ -670,6 +670,11 @@ def get_postprocessors(opts):
|
|||||||
'add_metadata': opts.addmetadata,
|
'add_metadata': opts.addmetadata,
|
||||||
'add_infojson': opts.embed_infojson,
|
'add_infojson': opts.embed_infojson,
|
||||||
}
|
}
|
||||||
|
# MutagenMetadata must run after FFmpegMetadata
|
||||||
|
if opts.addmetadata:
|
||||||
|
yield {
|
||||||
|
'key': 'MutagenMetadata',
|
||||||
|
}
|
||||||
# Deprecated
|
# Deprecated
|
||||||
# This should be above EmbedThumbnail since sponskrub removes the thumbnail attachment
|
# This should be above EmbedThumbnail since sponskrub removes the thumbnail attachment
|
||||||
# but must be below EmbedSubtitle and FFmpegMetadata
|
# but must be below EmbedSubtitle and FFmpegMetadata
|
||||||
|
@ -422,16 +422,23 @@ class InfoExtractor:
|
|||||||
track_number: Number of the track within an album or a disc, as an integer.
|
track_number: Number of the track within an album or a disc, as an integer.
|
||||||
track_id: Id of the track (useful in case of custom indexing, e.g. 6.iii),
|
track_id: Id of the track (useful in case of custom indexing, e.g. 6.iii),
|
||||||
as a unicode string.
|
as a unicode string.
|
||||||
artist: Artist(s) of the track.
|
artist_list: Artist(s) of the track, as a list of unicode strings.
|
||||||
genre: Genre(s) of the track.
|
composer_list: Composer(s) of the piece, as a list of unicode strings.
|
||||||
|
genre_list: Genre(s) of the track, as a list of unicode strings.
|
||||||
|
|
||||||
album: Title of the album the track belongs to.
|
album: Title of the album the track belongs to.
|
||||||
album_type: Type of the album (e.g. "Demo", "Full-length", "Split", "Compilation", etc).
|
album_type: Type of the album (e.g. "Demo", "Full-length", "Split", "Compilation", etc).
|
||||||
album_artist: List of all artists appeared on the album (e.g.
|
album_artist_list: All artists appeared on the album, as a list of unicode strings.
|
||||||
"Ash Borer / Fell Voices" or "Various Artists", useful for splits
|
(e.g. ["Ash Borer", "Fell Voices"] or ["Various Artists"],
|
||||||
and compilations).
|
useful for splits and compilations).
|
||||||
disc_number: Number of the disc or other physical medium the track belongs to,
|
disc_number: Number of the disc or other physical medium the track belongs to,
|
||||||
as an integer.
|
as an integer.
|
||||||
composer: Composer of the piece
|
composer: Deprecated, use "composer_list" instead. Composer(s) of the piece,
|
||||||
|
comma-separated
|
||||||
|
artist: Deprecated, use "artist_list" instead. Artist(s) of the track, comma-separated.
|
||||||
|
genre: Deprecated, use "genre_list" instead. Genre(s) of the track, comma-separated.
|
||||||
|
album_artist: Deprecated, use "album_artist_list" instead. All artists appeared on the
|
||||||
|
album, comma-separated.
|
||||||
|
|
||||||
The following fields should only be set for clips that should be cut from the original video:
|
The following fields should only be set for clips that should be cut from the original video:
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ from .metadataparser import (
|
|||||||
)
|
)
|
||||||
from .modify_chapters import ModifyChaptersPP
|
from .modify_chapters import ModifyChaptersPP
|
||||||
from .movefilesafterdownload import MoveFilesAfterDownloadPP
|
from .movefilesafterdownload import MoveFilesAfterDownloadPP
|
||||||
|
from .mutagenmetadata import MutagenMetadataPP
|
||||||
from .sponskrub import SponSkrubPP
|
from .sponskrub import SponSkrubPP
|
||||||
from .sponsorblock import SponsorBlockPP
|
from .sponsorblock import SponsorBlockPP
|
||||||
from .xattrpp import XAttrMetadataPP
|
from .xattrpp import XAttrMetadataPP
|
||||||
|
@ -23,6 +23,7 @@ from ..utils import (
|
|||||||
encodeFilename,
|
encodeFilename,
|
||||||
filter_dict,
|
filter_dict,
|
||||||
float_or_none,
|
float_or_none,
|
||||||
|
is_iterable_like,
|
||||||
is_outdated_version,
|
is_outdated_version,
|
||||||
orderedSet,
|
orderedSet,
|
||||||
prepend_extension,
|
prepend_extension,
|
||||||
@ -738,9 +739,12 @@ class FFmpegMetadataPP(FFmpegPostProcessor):
|
|||||||
|
|
||||||
def add(meta_list, info_list=None):
|
def add(meta_list, info_list=None):
|
||||||
value = next((
|
value = next((
|
||||||
str(info[key]) for key in [f'{meta_prefix}_'] + list(variadic(info_list or meta_list))
|
info[key] for key in [f'{meta_prefix}_'] + list(variadic(info_list or meta_list))
|
||||||
if info.get(key) is not None), None)
|
if info.get(key) is not None), None)
|
||||||
if value not in ('', None):
|
if value not in ('', None):
|
||||||
|
if is_iterable_like(value):
|
||||||
|
value = ', '.join(value)
|
||||||
|
value = str(value)
|
||||||
value = value.replace('\0', '') # nul character cannot be passed in command line
|
value = value.replace('\0', '') # nul character cannot be passed in command line
|
||||||
metadata['common'].update({meta_f: value for meta_f in variadic(meta_list)})
|
metadata['common'].update({meta_f: value for meta_f in variadic(meta_list)})
|
||||||
|
|
||||||
@ -754,10 +758,11 @@ class FFmpegMetadataPP(FFmpegPostProcessor):
|
|||||||
add(('description', 'synopsis'), 'description')
|
add(('description', 'synopsis'), 'description')
|
||||||
add(('purl', 'comment'), 'webpage_url')
|
add(('purl', 'comment'), 'webpage_url')
|
||||||
add('track', 'track_number')
|
add('track', 'track_number')
|
||||||
add('artist', ('artist', 'creator', 'uploader', 'uploader_id'))
|
add('artist', ('artist_list', 'creator', 'uploader', 'uploader_id'))
|
||||||
add('genre')
|
add('composer', 'composer_list')
|
||||||
|
add('genre', 'genre_list')
|
||||||
add('album')
|
add('album')
|
||||||
add('album_artist')
|
add('album_artist', 'album_artist_list')
|
||||||
add('disc', 'disc_number')
|
add('disc', 'disc_number')
|
||||||
add('show', 'series')
|
add('show', 'series')
|
||||||
add('season_number')
|
add('season_number')
|
||||||
|
42
yt_dlp/postprocessor/mutagenmetadata.py
Normal file
42
yt_dlp/postprocessor/mutagenmetadata.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
from .common import PostProcessor
|
||||||
|
from ..dependencies import mutagen
|
||||||
|
|
||||||
|
if mutagen:
|
||||||
|
from mutagen.easymp4 import EasyMP4
|
||||||
|
from mutagen.flac import FLAC
|
||||||
|
from mutagen.mp3 import EasyMP3
|
||||||
|
from mutagen.musepack import Musepack
|
||||||
|
from mutagen.oggopus import OggOpus
|
||||||
|
from mutagen.oggvorbis import OggVorbis
|
||||||
|
|
||||||
|
|
||||||
|
class MutagenMetadataPP(PostProcessor):
|
||||||
|
def __init__(self, downloader):
|
||||||
|
PostProcessor.__init__(self, downloader)
|
||||||
|
|
||||||
|
@PostProcessor._restrict_to(images=False)
|
||||||
|
def run(self, information):
|
||||||
|
extension = information['ext']
|
||||||
|
ret = [], information
|
||||||
|
if not mutagen:
|
||||||
|
if extension in ['mp3', 'm4a', 'ogg', 'opus', 'flac', '.mpc']:
|
||||||
|
self.report_warning('module mutagen was not found. Tags with multiple values (e.g. artist, album artist and genre) may be set incorrectly. Please install using `python -m pip install mutagen`')
|
||||||
|
return ret
|
||||||
|
tag_mapping = {
|
||||||
|
'artist': 'artist_list',
|
||||||
|
'albumartist': 'album_artist_list',
|
||||||
|
'genre': 'genre_list',
|
||||||
|
'composer': 'composer_list'
|
||||||
|
}
|
||||||
|
supported_formats = [EasyMP3, EasyMP4, OggVorbis, OggOpus, FLAC, Musepack]
|
||||||
|
file = mutagen.File(information['filepath'], supported_formats)
|
||||||
|
if not file:
|
||||||
|
return ret
|
||||||
|
if isinstance(file, EasyMP4):
|
||||||
|
file.RegisterTextKey('composer', '\251wrt')
|
||||||
|
for tag_key, info_key in tag_mapping.items():
|
||||||
|
value = information.get(info_key)
|
||||||
|
if value:
|
||||||
|
file[tag_key] = value
|
||||||
|
file.save()
|
||||||
|
return ret
|
Loading…
Reference in New Issue
Block a user