mirror of
https://github.com/ytdl-org/youtube-dl.git
synced 2025-02-03 16:49:48 +00:00
do similar stuff as for output template
This commit is contained in:
parent
0b4a957f28
commit
2e45a51464
@ -5,7 +5,23 @@ import os
|
|||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
|
import collections
|
||||||
|
from string import ascii_letters
|
||||||
|
import random
|
||||||
|
from ..utils import expand_path
|
||||||
|
# from youtube_dl import YoutubeDL
|
||||||
|
# todo fail to import youtubedl class for _NUMERIC_FIELDS
|
||||||
|
# http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html
|
||||||
|
_NUMERIC_FIELDS = set((
|
||||||
|
'width', 'height', 'tbr', 'abr', 'asr', 'vbr', 'fps', 'filesize', 'filesize_approx',
|
||||||
|
'timestamp', 'upload_year', 'upload_month', 'upload_day',
|
||||||
|
'duration', 'view_count', 'like_count', 'dislike_count', 'repost_count',
|
||||||
|
'average_rating', 'comment_count', 'age_limit',
|
||||||
|
'start_time', 'end_time',
|
||||||
|
'chapter_number', 'season_number', 'episode_number',
|
||||||
|
'track_number', 'disc_number', 'release_year',
|
||||||
|
'playlist_index',
|
||||||
|
))
|
||||||
|
|
||||||
from .common import AudioConversionError, PostProcessor
|
from .common import AudioConversionError, PostProcessor
|
||||||
|
|
||||||
@ -181,7 +197,7 @@ class FFmpegPostProcessor(PostProcessor):
|
|||||||
oldest_mtime = min(
|
oldest_mtime = min(
|
||||||
os.stat(encodeFilename(path)).st_mtime for path in input_paths)
|
os.stat(encodeFilename(path)).st_mtime for path in input_paths)
|
||||||
|
|
||||||
opts += map(lambda s: s % info, self._configuration_args())
|
opts += map(lambda s: self._resolve_postprocessor_arg_var(s, info), self._configuration_args())
|
||||||
|
|
||||||
files_cmd = []
|
files_cmd = []
|
||||||
for path in input_paths:
|
for path in input_paths:
|
||||||
@ -214,6 +230,83 @@ class FFmpegPostProcessor(PostProcessor):
|
|||||||
# Also leave '-' intact in order not to break streaming to stdout.
|
# Also leave '-' intact in order not to break streaming to stdout.
|
||||||
return 'file:' + fn if fn != '-' else fn
|
return 'file:' + fn if fn != '-' else fn
|
||||||
|
|
||||||
|
def _resolve_postprocessor_arg_var(self, arg, info):
|
||||||
|
# map(lambda s: s % info, args)
|
||||||
|
if "%(" not in arg:
|
||||||
|
return arg
|
||||||
|
|
||||||
|
template_dict = dict(info)
|
||||||
|
template_dict['epoch'] = int(time.time())
|
||||||
|
# autonumber_size = self.params.get('autonumber_size')
|
||||||
|
# if autonumber_size is None:
|
||||||
|
autonumber_size = 5
|
||||||
|
#
|
||||||
|
# template_dict['autonumber'] = self.params.get('autonumber_start', 1) - 1 + self._num_downloads
|
||||||
|
# if template_dict.get('resolution') is None:
|
||||||
|
# if template_dict.get('width') and template_dict.get('height'):
|
||||||
|
# template_dict['resolution'] = '%dx%d' % (template_dict['width'], template_dict['height'])
|
||||||
|
# elif template_dict.get('height'):
|
||||||
|
# template_dict['resolution'] = '%sp' % template_dict['height']
|
||||||
|
# elif template_dict.get('width'):
|
||||||
|
# template_dict['resolution'] = '%dx?' % template_dict['width']
|
||||||
|
# sanitize = lambda k, v: sanitize_filename(
|
||||||
|
# compat_str(v),
|
||||||
|
# restricted=self.params.get('restrictfilenames'),
|
||||||
|
# is_id=(k == 'id' or k.endswith('_id')))
|
||||||
|
# template_dict = dict((k, v if isinstance(v, compat_numeric_types) else sanitize(k, v))
|
||||||
|
# for k, v in template_dict.items()
|
||||||
|
# if v is not None and not isinstance(v, (list, tuple, dict)))
|
||||||
|
template_dict = collections.defaultdict(lambda: 'NA', template_dict)
|
||||||
|
outtmpl = arg
|
||||||
|
|
||||||
|
# For fields playlist_index and autonumber convert all occurrences
|
||||||
|
# of %(field)s to %(field)0Nd for backward compatibility
|
||||||
|
field_size_compat_map = {
|
||||||
|
'playlist_index': len(str(template_dict['n_entries'])),
|
||||||
|
'autonumber': autonumber_size,
|
||||||
|
}
|
||||||
|
FIELD_SIZE_COMPAT_RE = r'(?<!%)%\((?P<field>autonumber|playlist_index)\)s'
|
||||||
|
mobj = re.search(FIELD_SIZE_COMPAT_RE, outtmpl)
|
||||||
|
if mobj:
|
||||||
|
outtmpl = re.sub(
|
||||||
|
FIELD_SIZE_COMPAT_RE,
|
||||||
|
r'%%(\1)0%dd' % field_size_compat_map[mobj.group('field')],
|
||||||
|
outtmpl)
|
||||||
|
# Missing numeric fields used together with integer presentation types
|
||||||
|
# in format specification will break the argument substitution since
|
||||||
|
# string 'NA' is returned for missing fields. We will patch output
|
||||||
|
# template for missing fields to meet string presentation type.
|
||||||
|
for numeric_field in _NUMERIC_FIELDS:
|
||||||
|
if numeric_field not in template_dict:
|
||||||
|
# As of [1] format syntax is:
|
||||||
|
# %[mapping_key][conversion_flags][minimum_width][.precision][length_modifier]type
|
||||||
|
# 1. https://docs.python.org/2/library/stdtypes.html#string-formatting
|
||||||
|
FORMAT_RE = r'''(?x)
|
||||||
|
(?<!%)
|
||||||
|
%
|
||||||
|
\({0}\) # mapping key
|
||||||
|
(?:[#0\-+ ]+)? # conversion flags (optional)
|
||||||
|
(?:\d+)? # minimum field width (optional)
|
||||||
|
(?:\.\d+)? # precision (optional)
|
||||||
|
[hlL]? # length modifier (optional)
|
||||||
|
[diouxXeEfFgGcrs%] # conversion type
|
||||||
|
'''
|
||||||
|
outtmpl = re.sub(
|
||||||
|
FORMAT_RE.format(numeric_field),
|
||||||
|
r'%({0})s'.format(numeric_field), outtmpl)
|
||||||
|
# expand_path translates '%%' into '%' and '$$' into '$'
|
||||||
|
# correspondingly that is not what we want since we need to keep
|
||||||
|
# '%%' intact for template dict substitution step. Working around
|
||||||
|
# with boundary-alike separator hack.
|
||||||
|
sep = ''.join([random.choice(ascii_letters) for _ in range(32)])
|
||||||
|
outtmpl = outtmpl.replace('%%', '%{0}%'.format(sep)).replace('$$', '${0}$'.format(sep))
|
||||||
|
# outtmpl should be expand_path'ed before template dict substitution
|
||||||
|
# because meta fields may contain env variables we don't want to
|
||||||
|
# be expanded. For example, for outtmpl "%(title)s.%(ext)s" and
|
||||||
|
# title "Hello $PATH", we don't want `$PATH` to be expanded.
|
||||||
|
# todo need encoding & sanitize_path ?
|
||||||
|
return expand_path(outtmpl).replace(sep, '') % template_dict
|
||||||
|
|
||||||
|
|
||||||
class FFmpegExtractAudioPP(FFmpegPostProcessor):
|
class FFmpegExtractAudioPP(FFmpegPostProcessor):
|
||||||
def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, nopostoverwrites=False):
|
def __init__(self, downloader=None, preferredcodec=None, preferredquality=None, nopostoverwrites=False):
|
||||||
|
Loading…
Reference in New Issue
Block a user