diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py
index d994682b2..2b3d684bb 100644
--- a/test/test_YoutubeDL.py
+++ b/test/test_YoutubeDL.py
@@ -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()
diff --git a/test/test_postprocessors.py b/test/test_postprocessors.py
index 4209d1d9a..2d2338cac 100644
--- a/test/test_postprocessors.py
+++ b/test/test_postprocessors.py
@@ -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
.+)\ \-\ (?P.+)')
+
+
+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')
+
diff --git a/test/test_utils.py b/test/test_utils.py
index 1106f2819..6f818e806 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -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):
diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py
index 4c762bf2c..8ba794b31 100755
--- a/youtube_dl/YoutubeDL.py
+++ b/youtube_dl/YoutubeDL.py
@@ -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='.')
diff --git a/youtube_dl/postprocessor/embedthumbnail.py b/youtube_dl/postprocessor/embedthumbnail.py
index b6c60e127..7cb42795d 100644
--- a/youtube_dl/postprocessor/embedthumbnail.py
+++ b/youtube_dl/postprocessor/embedthumbnail.py
@@ -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)
diff --git a/youtube_dl/postprocessor/ffmpeg.py b/youtube_dl/postprocessor/ffmpeg.py
index 214825aa9..1ebe5f6c1 100644
--- a/youtube_dl/postprocessor/ffmpeg.py
+++ b/youtube_dl/postprocessor/ffmpeg.py
@@ -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')
diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py
index 02a49ff49..4d65afe85 100644
--- a/youtube_dl/utils.py
+++ b/youtube_dl/utils.py
@@ -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)