This commit is contained in:
aoright 2026-06-30 16:03:19 +08:00 committed by GitHub
commit d39c2b557e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 80 additions and 15 deletions

View file

@ -1186,6 +1186,42 @@ class TestYoutubeDLCookies(unittest.TestCase):
self.assertFalse(result.get('cookies'), msg='Cookies set in cookies field for wrong domain')
self.assertFalse(ydl.cookiejar.get_cookie_header(fmt['url']), msg='Cookies set in cookiejar for wrong domain')
def test_correct_ext_case_insensitive(self):
from youtube_dl.utils import join_nonempty
exts = ['mp4', 'mp4']
def correct_ext(filename, ext=exts[1]):
if filename == '-':
return filename
f_name, f_real_ext = os.path.splitext(filename)
f_real_ext = f_real_ext[1:]
filename_wo_ext = f_name if f_real_ext.lower() in [e.lower() for e in exts if e] else filename
if ext is None:
ext = f_real_ext or None
return join_nonempty(filename_wo_ext, ext, delim='.')
self.assertEqual(correct_ext('video.MP4', 'mp4'), 'video.mp4')
self.assertEqual(correct_ext('video.MP4', 'mkv'), 'video.mkv')
def test_compatible_formats_case_insensitive(self):
def compatible_formats(formats):
video, audio = formats
video_ext, audio_ext = video.get('ext'), audio.get('ext')
if video_ext and audio_ext:
video_ext_lower = video_ext.lower()
audio_ext_lower = audio_ext.lower()
COMPATIBLE_EXTS = (
('mp3', 'mp4', 'm4a', 'm4p', 'm4b', 'm4r', 'm4v', 'ismv', 'isma'),
('webm')
)
for exts in COMPATIBLE_EXTS:
if video_ext_lower in exts and audio_ext_lower in exts:
return True
return False
self.assertTrue(compatible_formats([{'ext': 'MP4'}, {'ext': 'M4A'}]))
self.assertTrue(compatible_formats([{'ext': 'webm'}, {'ext': 'WEBM'}]))
self.assertFalse(compatible_formats([{'ext': 'mp4'}, {'ext': 'webm'}]))
if __name__ == '__main__':
unittest.main()

View file

@ -15,3 +15,22 @@ class TestMetadataFromTitle(unittest.TestCase):
def test_format_to_regex(self):
pp = MetadataFromTitlePP(None, '%(title)s - %(artist)s')
self.assertEqual(pp._titleregex, r'(?P<title>.+)\ \-\ (?P<artist>.+)')
class TestEmbedThumbnail(unittest.TestCase):
def test_run_case_insensitive(self):
from youtube_dl.postprocessor import EmbedThumbnailPP
class DummyDownloader(object):
params = {}
def to_screen(self, msg):
pass
pp = EmbedThumbnailPP(DummyDownloader())
res_files, res_info = pp.run({'ext': 'MP3', 'filepath': 'file.mp3', 'thumbnails': []})
self.assertEqual(res_files, [])
self.assertEqual(res_info['ext'], 'MP3')
res_files, res_info = pp.run({'ext': 'MP4', 'filepath': 'file.mp4', 'thumbnails': []})
self.assertEqual(res_files, [])
self.assertEqual(res_info['ext'], 'MP4')

View file

@ -336,6 +336,7 @@ class TestUtil(unittest.TestCase):
def test_subtitles_filename(self):
self.assertEqual(subtitles_filename('abc.ext', 'en', 'vtt'), 'abc.en.vtt')
self.assertEqual(subtitles_filename('abc.ext', 'en', 'vtt', 'ext'), 'abc.en.vtt')
self.assertEqual(subtitles_filename('abc.EXT', 'en', 'vtt', 'ext'), 'abc.en.vtt')
self.assertEqual(subtitles_filename('abc.unexpected_ext', 'en', 'vtt', 'ext'), 'abc.unexpected_ext.en.vtt')
def test_remove_start(self):
@ -444,10 +445,12 @@ class TestUtil(unittest.TestCase):
def test_determine_ext(self):
self.assertEqual(determine_ext('http://example.com/foo/bar.mp4/?download'), 'mp4')
self.assertEqual(determine_ext('http://example.com/foo/bar.MP4/?download'), 'MP4')
self.assertEqual(determine_ext('http://example.com/foo/bar/?download', None), None)
self.assertEqual(determine_ext('http://example.com/foo/bar.nonext/?download', None), None)
self.assertEqual(determine_ext('http://example.com/foo/bar/mp4?download', None), None)
self.assertEqual(determine_ext('http://example.com/foo/bar.m3u8//?download'), 'm3u8')
self.assertEqual(determine_ext('http://example.com/foo/bar.M3U8//?download'), 'M3U8')
self.assertEqual(determine_ext('foobar', None), None)
def test_find_xpath_attr(self):

View file

@ -2111,12 +2111,14 @@ class YoutubeDL(object):
# Check extension
video_ext, audio_ext = video.get('ext'), audio.get('ext')
if video_ext and audio_ext:
video_ext_lower = video_ext.lower()
audio_ext_lower = audio_ext.lower()
COMPATIBLE_EXTS = (
('mp3', 'mp4', 'm4a', 'm4p', 'm4b', 'm4r', 'm4v', 'ismv', 'isma'),
('webm')
)
for exts in COMPATIBLE_EXTS:
if video_ext in exts and audio_ext in exts:
if video_ext_lower in exts and audio_ext_lower in exts:
return True
# TODO: Check acodec/vcodec
return False
@ -2135,7 +2137,7 @@ class YoutubeDL(object):
return filename
f_name, f_real_ext = os.path.splitext(filename)
f_real_ext = f_real_ext[1:]
filename_wo_ext = f_name if f_real_ext in exts else filename
filename_wo_ext = f_name if f_real_ext.lower() in [e.lower() for e in exts if e] else filename
if ext is None:
ext = f_real_ext or None
return join_nonempty(filename_wo_ext, ext, delim='.')

View file

@ -77,7 +77,8 @@ class EmbedThumbnailPP(FFmpegPostProcessor):
os.rename(encodeFilename(escaped_thumbnail_jpg_filename), encodeFilename(thumbnail_jpg_filename))
thumbnail_filename = thumbnail_jpg_filename
if info['ext'] == 'mp3':
info_ext = info['ext'].lower()
if info_ext == 'mp3':
options = [
'-c', 'copy', '-map', '0', '-map', '1',
'-metadata:s:v', 'title="Album cover"', '-metadata:s:v', 'comment="Cover (Front)"']
@ -91,7 +92,7 @@ class EmbedThumbnailPP(FFmpegPostProcessor):
os.remove(encodeFilename(filename))
os.rename(encodeFilename(temp_filename), encodeFilename(filename))
elif info['ext'] in ['m4a', 'mp4']:
elif info_ext in ['m4a', 'mp4']:
atomicparsley = next((x
for x in ['AtomicParsley', 'atomicparsley']
if check_executable(x, ['-v'])), None)

View file

@ -352,7 +352,7 @@ class FFmpegVideoConvertorPP(FFmpegPostProcessor):
def run(self, information):
path = information['filepath']
if information['ext'] == self._preferedformat:
if information['ext'].lower() == self._preferedformat.lower():
self._downloader.to_screen('[ffmpeg] Not converting video file %s - already is in target format %s' % (path, self._preferedformat))
return [], information
options = []
@ -370,7 +370,7 @@ class FFmpegVideoConvertorPP(FFmpegPostProcessor):
class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
def run(self, information):
if information['ext'] not in ('mp4', 'webm', 'mkv'):
if information['ext'].lower() not in ('mp4', 'webm', 'mkv'):
self._downloader.to_screen('[ffmpeg] Subtitles can only be embedded in mp4, webm or mkv files')
return [], information
subtitles = information.get('requested_subtitles')
@ -385,13 +385,15 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
sub_filenames = []
webm_vtt_warn = False
ext_lower = ext.lower()
for lang, sub_info in subtitles.items():
sub_ext = sub_info['ext']
if ext != 'webm' or ext == 'webm' and sub_ext == 'vtt':
sub_ext_lower = sub_ext.lower()
if ext_lower != 'webm' or ext_lower == 'webm' and sub_ext_lower == 'vtt':
sub_langs.append(lang)
sub_filenames.append(subtitles_filename(filename, lang, sub_ext, ext))
else:
if not webm_vtt_warn and ext == 'webm' and sub_ext != 'vtt':
if not webm_vtt_warn and ext_lower == 'webm' and sub_ext_lower != 'vtt':
webm_vtt_warn = True
self._downloader.to_screen('[ffmpeg] Only WebVTT subtitles can be embedded in webm files')
@ -410,7 +412,7 @@ class FFmpegEmbedSubtitlePP(FFmpegPostProcessor):
# https://trac.ffmpeg.org/ticket/6016)
'-map', '-0:d',
]
if information['ext'] == 'mp4':
if information['ext'].lower() == 'mp4':
opts += ['-c:s', 'mov_text']
for (i, lang) in enumerate(sub_langs):
opts.extend(['-map', '%d:0' % (i + 1)])
@ -474,7 +476,7 @@ class FFmpegMetadataPP(FFmpegPostProcessor):
in_filenames = [filename]
options = []
if info['ext'] == 'm4a':
if info['ext'].lower() == 'm4a':
options.extend(['-vn', '-acodec', 'copy'])
else:
options.extend(['-c', 'copy'])
@ -609,7 +611,9 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):
sub_filenames = []
for lang, sub in subs.items():
ext = sub['ext']
if ext == new_ext:
ext_lower = ext.lower()
new_ext_lower = new_ext.lower()
if ext_lower == new_ext_lower:
self._downloader.to_screen(
'[ffmpeg] Subtitle file for %s is already in the requested format' % new_ext)
continue
@ -617,7 +621,7 @@ class FFmpegSubtitlesConvertorPP(FFmpegPostProcessor):
sub_filenames.append(old_file)
new_file = subtitles_filename(filename, lang, new_ext, info.get('ext'))
if ext in ('dfxp', 'ttml', 'tt'):
if ext_lower in ('dfxp', 'ttml', 'tt'):
self._downloader.report_warning(
'You have requested to convert dfxp (TTML) subtitles into another format, '
'which results in style information loss')

View file

@ -3273,7 +3273,7 @@ def determine_ext(url, default_ext='unknown_video'):
if re.match(r'^[A-Za-z0-9]+$', guess):
return guess
# Try extract ext from URLs like http://example.com/foo/bar.mp4/?download
elif guess.rstrip('/') in KNOWN_EXTENSIONS:
elif guess.rstrip('/').lower() in KNOWN_EXTENSIONS:
return guess.rstrip('/')
else:
return default_ext
@ -3992,7 +3992,7 @@ def _change_extension(prepend, filename, ext, expected_real_ext=None):
name, real_ext = os.path.splitext(filename)
sanitize_extension = _UnsafeExtensionError.sanitize_extension
if not expected_real_ext or real_ext.partition('.')[0::2] == ('', expected_real_ext):
if not expected_real_ext or real_ext.lower().partition('.')[0::2] == ('', expected_real_ext.lower()):
filename = name
if prepend and real_ext:
sanitize_extension(ext, prepend=prepend)
@ -6855,7 +6855,7 @@ class _UnsafeExtensionError(Exception):
if not prepend:
last = extension.rpartition('.')[-1]
if last == 'bin':
if last.lower() == 'bin':
extension = last = 'unknown_video'
if not (cls.lenient or last.lower() in cls._ALLOWED_EXTENSIONS):
raise cls(extension)