fix: derive media content type from container
This commit is contained in:
@@ -928,26 +928,35 @@ class Media(models.Model):
|
||||
|
||||
@property
|
||||
def content_type(self):
|
||||
if not self.downloaded:
|
||||
return 'video/mp4'
|
||||
vcodec = self.downloaded_video_codec
|
||||
if vcodec is None:
|
||||
acodec = self.downloaded_audio_codec
|
||||
if acodec is None:
|
||||
raise TypeError() # nothing here.
|
||||
acodec = acodec.upper()
|
||||
if acodec == Val(YouTube_AudioCodec.MP4A):
|
||||
return "audio/mp4"
|
||||
elif acodec == Val(YouTube_AudioCodec.OPUS):
|
||||
return "audio/opus"
|
||||
else:
|
||||
# fall-fall-back.
|
||||
return 'audio/ogg'
|
||||
vcodec = vcodec.upper()
|
||||
if vcodec == Val(YouTube_VideoCodec.AVC1):
|
||||
return 'video/mp4'
|
||||
else:
|
||||
return 'video/matroska'
|
||||
"""Return a MIME type without requiring downloaded codec metadata.
|
||||
|
||||
Imported media can be marked downloaded while codec fields are empty.
|
||||
MIME type is determined primarily by the container/file extension.
|
||||
"""
|
||||
container = (self.downloaded_container or '').strip().lower()
|
||||
if not container and self.media_file:
|
||||
container = Path(self.media_file.name).suffix.lstrip('.').lower()
|
||||
|
||||
if self.source.is_audio:
|
||||
return {
|
||||
'm4a': 'audio/mp4',
|
||||
'mp4': 'audio/mp4',
|
||||
'ogg': 'audio/ogg',
|
||||
'oga': 'audio/ogg',
|
||||
'opus': 'audio/ogg',
|
||||
'webm': 'audio/webm',
|
||||
'mp3': 'audio/mpeg',
|
||||
}.get(container, 'audio/ogg')
|
||||
|
||||
return {
|
||||
'mp4': 'video/mp4',
|
||||
'm4v': 'video/mp4',
|
||||
'mov': 'video/quicktime',
|
||||
'mkv': 'video/x-matroska',
|
||||
'matroska': 'video/x-matroska',
|
||||
'webm': 'video/webm',
|
||||
'avi': 'video/x-msvideo',
|
||||
}.get(container, 'video/mp4')
|
||||
|
||||
@property
|
||||
def nfoxml(self):
|
||||
|
||||
@@ -48,6 +48,24 @@ class MediaTestCase(TestCase):
|
||||
self.media.created = datetime(year=2020, month=1, day=1, hour=1,
|
||||
minute=1, second=1)
|
||||
|
||||
def test_content_type_uses_video_container_without_codec_metadata(self):
|
||||
self.media.downloaded = True
|
||||
self.media.downloaded_container = 'mkv'
|
||||
self.media.downloaded_video_codec = None
|
||||
self.media.downloaded_audio_codec = None
|
||||
|
||||
self.assertEqual(self.media.content_type, 'video/x-matroska')
|
||||
|
||||
def test_content_type_uses_audio_container_without_codec_metadata(self):
|
||||
self.source.source_resolution = Val(SourceResolution.AUDIO)
|
||||
self.source.save(update_fields=['source_resolution'])
|
||||
self.media.downloaded = True
|
||||
self.media.downloaded_container = 'mp3'
|
||||
self.media.downloaded_video_codec = None
|
||||
self.media.downloaded_audio_codec = None
|
||||
|
||||
self.assertEqual(self.media.content_type, 'audio/mpeg')
|
||||
|
||||
def test_nfo(self):
|
||||
expected_tree = ElementTree.fromstring(all_test_metadata['expected_nfo'])
|
||||
nfo_tree = ElementTree.fromstring(self.media.nfoxml)
|
||||
|
||||
Reference in New Issue
Block a user