]> jfr.im git - yt-dlp.git/blob - youtube_dlc/postprocessor/sponskrub.py
[sponskrub] Print "unrecognized args" message correctly
[yt-dlp.git] / youtube_dlc / postprocessor / sponskrub.py
1 from __future__ import unicode_literals
2 import os
3 import subprocess
4
5 from .common import PostProcessor
6 from ..compat import compat_shlex_split
7 from ..utils import (
8 check_executable,
9 encodeArgument,
10 encodeFilename,
11 shell_quote,
12 str_or_none,
13 PostProcessingError,
14 prepend_extension,
15 )
16
17
18 class SponSkrubPP(PostProcessor):
19 _temp_ext = 'spons'
20 _exe_name = 'sponskrub'
21
22 def __init__(self, downloader, path='', args=None, ignoreerror=False, cut=False, force=False):
23 PostProcessor.__init__(self, downloader)
24 self.force = force
25 self.cutout = cut
26 self.args = str_or_none(args) or '' # For backward compatibility
27 self.path = self.get_exe(path)
28
29 if not ignoreerror and self.path is None:
30 if path:
31 raise PostProcessingError('sponskrub not found in "%s"' % path)
32 else:
33 raise PostProcessingError('sponskrub not found. Please install or provide the path using --sponskrub-path.')
34
35 def get_exe(self, path=''):
36 if not path or not check_executable(path, ['-h']):
37 path = os.path.join(path, self._exe_name)
38 if not check_executable(path, ['-h']):
39 return None
40 return path
41
42 def run(self, information):
43 if self.path is None:
44 return [], information
45
46 if information['extractor_key'].lower() != 'youtube':
47 self.to_screen('Skipping sponskrub since it is not a YouTube video')
48 return [], information
49 if self.cutout and not self.force and not information.get('__real_download', False):
50 self.report_warning(
51 'Skipping sponskrub since the video was already downloaded. '
52 'Use --sponskrub-force to run sponskrub anyway')
53 return [], information
54
55 self.to_screen('Trying to %s sponsor sections' % ('remove' if self.cutout else 'mark'))
56 if self.cutout:
57 self.report_warning('Cutting out sponsor segments will cause the subtitles to go out of sync.')
58 if not information.get('__real_download', False):
59 self.report_warning('If sponskrub is run multiple times, unintended parts of the video could be cut out.')
60
61 filename = information['filepath']
62 temp_filename = prepend_extension(filename, self._temp_ext)
63 if os.path.exists(encodeFilename(temp_filename)):
64 os.remove(encodeFilename(temp_filename))
65
66 cmd = [self.path]
67 if not self.cutout:
68 cmd += ['-chapter']
69 cmd += compat_shlex_split(self.args) # For backward compatibility
70 cmd += self._configuration_args(exe=self._exe_name)
71 cmd += ['--', information['id'], filename, temp_filename]
72 cmd = [encodeArgument(i) for i in cmd]
73
74 self.write_debug('sponskrub command line: %s' % shell_quote(cmd))
75 p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
76 stdout, stderr = p.communicate()
77
78 if p.returncode == 0:
79 os.remove(encodeFilename(filename))
80 os.rename(encodeFilename(temp_filename), encodeFilename(filename))
81 self.to_screen('Sponsor sections have been %s' % ('removed' if self.cutout else 'marked'))
82 elif p.returncode == 3:
83 self.to_screen('No segments in the SponsorBlock database')
84 else:
85 msg = stderr.decode('utf-8', 'replace').strip() or stdout.decode('utf-8', 'replace').strip()
86 self.write_debug(msg, prefix=False)
87 line = 0 if msg[:12].lower() == 'unrecognised' else -1
88 msg = msg.split('\n')[line]
89 raise PostProcessingError(msg if msg else 'sponskrub failed with error code %s' % p.returncode)
90 return [], information