]> jfr.im git - yt-dlp.git/commitdiff
Add option `--skip-playlist-after-errors`
authorpukkandan <redacted>
Wed, 21 Apr 2021 06:00:43 +0000 (11:30 +0530)
committerpukkandan <redacted>
Wed, 21 Apr 2021 20:46:31 +0000 (02:16 +0530)
Allows to skip the rest of a playlist after a given number of errors are encountered

README.md
yt_dlp/YoutubeDL.py
yt_dlp/__init__.py
yt_dlp/options.py

index b1068421bee2879a2d4b642339caab6d1fbf56b8..b4e60eff628b776614de5be41e5a835e2188ff36 100644 (file)
--- a/README.md
+++ b/README.md
@@ -305,6 +305,8 @@ ## Video Selection:
                                      a file that is in the archive
     --break-on-reject                Stop the download process when encountering
                                      a file that has been filtered out
+    --skip-playlist-after-errors N   Number of allowed failures until the rest
+                                     of the playlist is skipped
     --no-download-archive            Do not use archive file (default)
 
 ## Download Options:
index 29931474d596ec6b3fd642bf495f4e9ba50a2f52..a3d7968ff995afee0c45bd330fbec9e85def8452 100644 (file)
@@ -214,6 +214,8 @@ class YoutubeDL(object):
     ignoreerrors:      Do not stop on download errors
                        (Default True when running yt-dlp,
                        but False when directly accessing YoutubeDL class)
+    skip_playlist_after_errors: Number of allowed failures until the rest of
+                       the playlist is skipped
     force_generic_extractor: Force downloader to use the generic extractor
     overwrites:        Overwrite all video and metadata files if True,
                        overwrite only non-video files if None
@@ -1327,6 +1329,8 @@ def make_playlistitems_entries(list_ie_entries):
         x_forwarded_for = ie_result.get('__x_forwarded_for_ip')
 
         self.to_screen('[%s] playlist %s: %s' % (ie_result['extractor'], playlist, msg))
+        failures = 0
+        max_failures = self.params.get('skip_playlist_after_errors') or float('inf')
         for i, entry in enumerate(entries, 1):
             self.to_screen('[download] Downloading video %s of %s' % (i, n_entries))
             # This __x_forwarded_for_ip thing is a bit ugly but requires
@@ -1351,6 +1355,12 @@ def make_playlistitems_entries(list_ie_entries):
                 continue
 
             entry_result = self.__process_iterable_entry(entry, download, extra)
+            if not entry_result:
+                failures += 1
+            if failures >= max_failures:
+                self.report_error(
+                    'Skipping the remaining entries in playlist "%s" since %d items failed extraction' % (playlist, failures))
+                break
             # TODO: skip failed (empty) entries?
             playlist_results.append(entry_result)
         ie_result['entries'] = playlist_results
index 4f0684236ed692dfb653ad3f6e22ef50f712299a..bf5896f0c6079587631024779af5d1c53186605c 100644 (file)
@@ -544,6 +544,7 @@ def report_args_compat(arg, name):
         'download_archive': download_archive_fn,
         'break_on_existing': opts.break_on_existing,
         'break_on_reject': opts.break_on_reject,
+        'skip_playlist_after_errors': opts.skip_playlist_after_errors,
         'cookiefile': opts.cookiefile,
         'nocheckcertificate': opts.no_check_certificate,
         'prefer_insecure': opts.prefer_insecure,
index a16604b7332905785d5814c2465c91c66bf77220..c21c453edf7905552d0a0fe230dbdc7bded6e5df 100644 (file)
@@ -395,6 +395,10 @@ def _dict_from_multiple_values_options_callback(
         '--break-on-reject',
         action='store_true', dest='break_on_reject', default=False,
         help='Stop the download process when encountering a file that has been filtered out')
+    selection.add_option(
+        '--skip-playlist-after-errors', metavar='N',
+        dest='skip_playlist_after_errors', default=None, type=int,
+        help='Number of allowed failures until the rest of the playlist is skipped')
     selection.add_option(
         '--no-download-archive',
         dest='download_archive', action="store_const", const=None,