1# Copyright 2013 Christoph Reiter 2# 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 2 of the License, or 6# (at your option) any later version. 7 8import os 9from io import BytesIO 10import mutagen 11 12from tests import TestCase, get_data_path 13from quodlibet.formats.mp4 import MP4File 14from quodlibet.formats._image import EmbeddedImage 15 16import mutagen.mp4 17 18from .helper import get_temp_copy 19 20 21class TMP4File(TestCase): 22 23 def setUp(self): 24 self.f = get_temp_copy(get_data_path('test.m4a')) 25 self.song = MP4File(self.f) 26 27 def tearDown(self): 28 os.unlink(self.f) 29 30 def _assert_tag_supported(self, tag, value="SomeTestValue"): 31 self.song[tag] = value 32 self.song.write() 33 self.song.reload() 34 self.assertEqual(self.song(tag), value) 35 36 def test_format(self): 37 self.assertEqual(self.song("~format"), "MPEG-4") 38 39 def test_codec(self): 40 self.assertEqual(self.song("~codec"), "AAC LC") 41 42 def test_encoding(self): 43 self.assertEqual(self.song("~encoding"), "FAAC 1.24") 44 45 def test_mb_release_track_id(self): 46 tag = mutagen.mp4.MP4(self.f) 47 tag["----:com.apple.iTunes:MusicBrainz Release Track Id"] = [b"foo"] 48 tag.save() 49 song = MP4File(self.f) 50 self.assertEqual(song("musicbrainz_releasetrackid"), u"foo") 51 song["musicbrainz_releasetrackid"] = u"bla" 52 song.write() 53 tag = mutagen.mp4.MP4(self.f) 54 self.assertEqual( 55 tag["----:com.apple.iTunes:MusicBrainz Release Track Id"], 56 [b"bla"]) 57 58 def test_basic(self): 59 self._assert_tag_supported("title") 60 self._assert_tag_supported("artist") 61 self._assert_tag_supported("albumartist") 62 self._assert_tag_supported("album") 63 self._assert_tag_supported("genre") 64 self._assert_tag_supported("date") 65 66 def test_basic_numeric(self): 67 self._assert_tag_supported("tracknumber", "12") 68 self._assert_tag_supported("discnumber", "1") 69 self._assert_tag_supported("bpm", "132") 70 71 def test_less_common_tags(self): 72 self._assert_tag_supported("discsubtitle") 73 self._assert_tag_supported("mood") 74 self._assert_tag_supported("conductor") 75 76 def test_replaygain_tags(self): 77 self._assert_tag_supported('replaygain_album_gain', '-5.67 dB') 78 self._assert_tag_supported('replaygain_album_peak', '1.0') 79 self._assert_tag_supported('replaygain_track_gain', '-5.67 dB') 80 self._assert_tag_supported('replaygain_track_peak', '1.0') 81 self._assert_tag_supported('replaygain_reference_loudness', '89 dB') 82 83 def test_length(self): 84 self.assertAlmostEqual(self.song("~#length"), 3.7079, 3) 85 86 def test_bitrate(self): 87 self.assertEqual(self.song("~#bitrate"), 2) 88 89 def test_channels(self): 90 assert self.song("~#channels") == 2 91 92 def test_samplerate(self): 93 assert self.song("~#samplerate") == 44100 94 95 def test_bitdepth(self): 96 assert self.song("~#bitdepth") == 16 97 98 def test_bpm_rounds(self): 99 self.song["bpm"] = "98.76" 100 self.song.write() 101 self.song.reload() 102 self.assertEqual(self.song("bpm"), "99") 103 self.assertEqual(self.song("~#bpm"), 99) 104 105 def test_empty_disk_trkn(self): 106 for key in ["trkn", "disk"]: 107 tag = mutagen.mp4.MP4(self.f) 108 tag[key] = [] 109 tag.save() 110 tag = mutagen.mp4.MP4(self.f) 111 assert tag[key] == [] 112 self.song.reload() 113 114 def test_write(self): 115 self.song.write() 116 117 def test_can_change(self): 118 self.assertTrue(self.song.can_change("title")) 119 self.assertFalse(self.song.can_change("foobar")) 120 self.assertTrue("albumartist" in self.song.can_change()) 121 122 def test_invalid(self): 123 path = get_data_path('empty.xm') 124 self.assertTrue(os.path.exists(path)) 125 self.assertRaises(Exception, MP4File, path) 126 127 def test_get_image(self): 128 image = self.song.get_primary_image() 129 self.assertTrue(image) 130 self.assertEqual(image.mime_type, "image/png") 131 132 def test_get_images(self): 133 images = self.song.get_images() 134 self.assertTrue(images and len(images) == 2) 135 136 def test_get_image_non(self): 137 tag = mutagen.mp4.MP4(self.f) 138 tag.pop("covr", None) 139 tag.save() 140 self.song.reload() 141 142 self.assertFalse(self.song.get_primary_image()) 143 144 def test_clear_images(self): 145 self.assertTrue(self.song.valid()) 146 self.assertTrue(self.song.has_images) 147 self.song.clear_images() 148 self.assertFalse(self.song.has_images) 149 self.assertFalse(self.song.get_primary_image()) 150 151 tag = mutagen.mp4.MP4(self.f) 152 self.assertFalse("covr" in tag) 153 154 def test_set_image(self): 155 self.assertTrue(self.song.has_images) 156 fileobj = BytesIO(b"foo") 157 image = EmbeddedImage(fileobj, "image/jpeg", 10, 10, 8) 158 self.song.set_image(image) 159 image = self.song.get_primary_image() 160 self.assertTrue(image) 161 self.assertEqual(image.read(), b"foo") 162 self.assertTrue(self.song.has_images) 163 164 def test_can_change_images(self): 165 self.assertTrue(self.song.can_change_images) 166 167 def test_can_multiple_values(self): 168 self.assertEqual(self.song.can_multiple_values(), []) 169 self.assertFalse(self.song.can_multiple_values("artist")) 170