youtube_dlc/postprocessor/__init__.py for a list.
as well as any further keyword arguments for the
postprocessor.
+ post_hooks: A list of functions that get called as the final step
+ for each video file, after all postprocessors have been
+ called. The filename will be passed as the only argument.
progress_hooks: A list of functions that get called on download
progress, with a dictionary with the entries
* status: One of "downloading", "error", or "finished".
otherwise prefer ffmpeg.
ffmpeg_location: Location of the ffmpeg/avconv binary; either the path
to the binary or its containing directory.
- postprocessor_args: A list of additional command-line arguments for the
- postprocessor.
+ postprocessor_args: A dictionary of postprocessor names (in lower case) and a list
+ of additional command-line arguments for the postprocessor.
+ Use 'default' as the name for arguments to passed to all PP.
The following options are used by the Youtube extractor:
youtube_include_dash_manifest: If True (default), DASH manifests and related
self._ies = []
self._ies_instances = {}
self._pps = []
+ self._post_hooks = []
self._progress_hooks = []
self._download_retcode = 0
self._num_downloads = 0
pp = pp_class(self, **compat_kwargs(pp_def))
self.add_post_processor(pp)
+ for ph in self.params.get('post_hooks', []):
+ self.add_post_hook(ph)
+
for ph in self.params.get('progress_hooks', []):
self.add_progress_hook(ph)
self._pps.append(pp)
pp.set_downloader(self)
+ def add_post_hook(self, ph):
+ """Add the post hook"""
+ self._post_hooks.append(ph)
+
def add_progress_hook(self, ph):
"""Add the progress hook (currently only for the file downloader)"""
self._progress_hooks.append(ph)
self.add_extra_info(ie_result, {
'extractor': ie.IE_NAME,
'webpage_url': url,
+ 'duration_string': (
+ formatSeconds(ie_result['duration'], '-')
+ if ie_result.get('duration', None) is not None
+ else None),
'webpage_url_basename': url_basename(url),
'extractor_key': ie.ie_key(),
})
and download
and (
not can_merge()
- or info_dict.get('is_live')
+ or info_dict.get('is_live', False)
or self.params.get('outtmpl', DEFAULT_OUTTMPL) == '-'))
return (
'best/bestvideo+bestaudio'
if prefer_best
else 'bestvideo*+bestaudio/best'
- if self.params.get('allow_multiple_audio_streams', False)
+ if not self.params.get('allow_multiple_audio_streams', False)
else 'bestvideo+bestaudio/best')
def build_format_selector(self, format_spec):
except (PostProcessingError) as err:
self.report_error('postprocessing: %s' % str(err))
return
+ try:
+ for ph in self._post_hooks:
+ ph(filename)
+ except Exception as err:
+ self.report_error('post hooks: %s' % str(err))
+ return
must_record_download_archive = True
if must_record_download_archive or self.params.get('force_write_download_archive', False):