1# -*- coding: utf-8 -*- 2 3import os 4import shutil 5 6from mutagen._compat import cBytesIO 7from mutagen.ogg import OggPage 8from mutagen.oggvorbis import OggVorbis, OggVorbisInfo, delete, error 9 10from tests import TestCase, DATA_DIR, get_temp_copy 11from tests.test_ogg import TOggFileTypeMixin 12 13 14class TOggVorbis(TestCase, TOggFileTypeMixin): 15 Kind = OggVorbis 16 17 def setUp(self): 18 self.filename = get_temp_copy(os.path.join(DATA_DIR, "empty.ogg")) 19 self.audio = self.Kind(self.filename) 20 21 def tearDown(self): 22 os.unlink(self.filename) 23 24 def test_module_delete(self): 25 delete(self.filename) 26 self.scan_file() 27 self.failIf(OggVorbis(self.filename).tags) 28 29 def test_bitrate(self): 30 self.failUnlessEqual(112000, self.audio.info.bitrate) 31 32 def test_channels(self): 33 self.failUnlessEqual(2, self.audio.info.channels) 34 35 def test_sample_rate(self): 36 self.failUnlessEqual(44100, self.audio.info.sample_rate) 37 38 def test_invalid_not_first(self): 39 with open(self.filename, "rb") as h: 40 page = OggPage(h) 41 page.first = False 42 self.failUnlessRaises(error, OggVorbisInfo, cBytesIO(page.write())) 43 44 def test_avg_bitrate(self): 45 with open(self.filename, "rb") as h: 46 page = OggPage(h) 47 packet = page.packets[0] 48 packet = (packet[:16] + b"\x00\x00\x01\x00" + b"\x00\x00\x00\x00" + 49 b"\x00\x00\x00\x00" + packet[28:]) 50 page.packets[0] = packet 51 info = OggVorbisInfo(cBytesIO(page.write())) 52 self.failUnlessEqual(info.bitrate, 32768) 53 54 def test_overestimated_bitrate(self): 55 with open(self.filename, "rb") as h: 56 page = OggPage(h) 57 packet = page.packets[0] 58 packet = (packet[:16] + b"\x00\x00\x01\x00" + b"\x00\x00\x00\x01" + 59 b"\x00\x00\x00\x00" + packet[28:]) 60 page.packets[0] = packet 61 info = OggVorbisInfo(cBytesIO(page.write())) 62 self.failUnlessEqual(info.bitrate, 65536) 63 64 def test_underestimated_bitrate(self): 65 with open(self.filename, "rb") as h: 66 page = OggPage(h) 67 packet = page.packets[0] 68 packet = (packet[:16] + b"\x00\x00\x01\x00" + b"\x01\x00\x00\x00" + 69 b"\x00\x00\x01\x00" + packet[28:]) 70 page.packets[0] = packet 71 info = OggVorbisInfo(cBytesIO(page.write())) 72 self.failUnlessEqual(info.bitrate, 65536) 73 74 def test_negative_bitrate(self): 75 with open(self.filename, "rb") as h: 76 page = OggPage(h) 77 packet = page.packets[0] 78 packet = (packet[:16] + b"\xff\xff\xff\xff" + b"\xff\xff\xff\xff" + 79 b"\xff\xff\xff\xff" + packet[28:]) 80 page.packets[0] = packet 81 info = OggVorbisInfo(cBytesIO(page.write())) 82 self.failUnlessEqual(info.bitrate, 0) 83 84 def test_vendor(self): 85 self.failUnless( 86 self.audio.tags.vendor.startswith("Xiph.Org libVorbis")) 87 self.failUnlessRaises(KeyError, self.audio.tags.__getitem__, "vendor") 88 89 def test_vorbiscomment(self): 90 self.audio.save() 91 self.scan_file() 92 if ogg is None: 93 return 94 self.failUnless(ogg.vorbis.VorbisFile(self.filename)) 95 96 def test_vorbiscomment_big(self): 97 self.test_really_big() 98 self.audio.save() 99 self.scan_file() 100 if ogg is None: 101 return 102 vfc = ogg.vorbis.VorbisFile(self.filename).comment() 103 self.failUnlessEqual(self.audio["foo"], vfc["foo"]) 104 105 def test_vorbiscomment_delete(self): 106 self.audio.delete() 107 self.scan_file() 108 if ogg is None: 109 return 110 vfc = ogg.vorbis.VorbisFile(self.filename).comment() 111 self.failUnlessEqual(vfc.keys(), ["VENDOR"]) 112 113 def test_vorbiscomment_delete_readd(self): 114 self.audio.delete() 115 self.audio.tags.clear() 116 self.audio["foobar"] = "foobar" * 1000 117 self.audio.save() 118 self.scan_file() 119 if ogg is None: 120 return 121 vfc = ogg.vorbis.VorbisFile(self.filename).comment() 122 self.failUnlessEqual(self.audio["foobar"], vfc["foobar"]) 123 self.failUnless("FOOBAR" in vfc.keys()) 124 self.failUnless("VENDOR" in vfc.keys()) 125 126 def test_huge_tag(self): 127 vorbis = self.Kind( 128 os.path.join(DATA_DIR, "multipagecomment.ogg")) 129 self.failUnless("big" in vorbis.tags) 130 self.failUnless("bigger" in vorbis.tags) 131 self.failUnlessEqual(vorbis.tags["big"], ["foobar" * 10000]) 132 self.failUnlessEqual(vorbis.tags["bigger"], ["quuxbaz" * 10000]) 133 self.scan_file() 134 135 def test_not_my_ogg(self): 136 fn = os.path.join(DATA_DIR, 'empty.oggflac') 137 self.failUnlessRaises(error, type(self.audio), fn) 138 self.failUnlessRaises(error, self.audio.save, fn) 139 self.failUnlessRaises(error, self.audio.delete, fn) 140 141 def test_save_split_setup_packet(self): 142 fn = os.path.join(DATA_DIR, "multipage-setup.ogg") 143 shutil.copy(fn, self.filename) 144 audio = OggVorbis(self.filename) 145 tags = audio.tags 146 self.failUnless(tags) 147 audio.save() 148 self.audio = OggVorbis(self.filename) 149 self.failUnlessEqual(self.audio.tags, tags) 150 151 def test_save_split_setup_packet_reference(self): 152 if ogg is None: 153 return 154 self.test_save_split_setup_packet() 155 vfc = ogg.vorbis.VorbisFile(self.filename).comment() 156 for key in self.audio: 157 self.failUnlessEqual(vfc[key], self.audio[key]) 158 self.ogg_reference(self.filename) 159 160 def test_save_grown_split_setup_packet_reference(self): 161 if ogg is None: 162 return 163 fn = os.path.join(DATA_DIR, "multipage-setup.ogg") 164 shutil.copy(fn, self.filename) 165 audio = OggVorbis(self.filename) 166 audio["foobar"] = ["quux" * 50000] 167 tags = audio.tags 168 self.failUnless(tags) 169 audio.save() 170 self.audio = OggVorbis(self.filename) 171 self.failUnlessEqual(self.audio.tags, tags) 172 vfc = ogg.vorbis.VorbisFile(self.filename).comment() 173 for key in self.audio: 174 self.failUnlessEqual(vfc[key], self.audio[key]) 175 self.ogg_reference(self.filename) 176 177 def test_mime(self): 178 self.failUnless("audio/vorbis" in self.audio.mime) 179 180 def test_init_padding(self): 181 self.assertEqual(self.audio.tags._padding, 0) 182 183try: 184 import ogg.vorbis 185except ImportError: 186 print("WARNING: Skipping Ogg Vorbis reference tests.") 187 ogg = None 188