Exemplo n.º 1
0
    def test_parse(self):
        for valid, expected_hdr in VALID_MP3_HEADERS.items():
            hdr = mp3_header.parse(valid)
            self.assertTrue(hdr)
            self.assertTrue(hdr.is_complete())
            self.assertTrue(hdr.match(expected_hdr))
            # Now try with a non-zero offset.
            hdr = mp3_header.parse("xxxx" + valid + "xxxx", offset=4)
            self.assertTrue(hdr)
            self.assertTrue(hdr.is_complete())
            self.assertTrue(hdr.match(expected_hdr))

        for invalid in INVALID_MP3_HEADERS:
            self.assertTrue(mp3_header.parse(invalid) is None)
Exemplo n.º 2
0
 def test_rollover(self):
     # Set up a test archiver.
     src = message.MessageSource()
     arch = archiver.Archiver(src)
     arch.ROOT_DIR = "/tmp/archiver_test/%d" % time.time()
     arch.loop_in_thread()
     # The archiver's rollover count should start out at zero.
     self.assertEqual(0, arch.rollover_count)
     # Construct a test frame.
     test_ms = 1262648655000  # Jan 4, 2010, 5:43pm
     msg = message.Message()
     msg.message_type = message.FRAME
     msg.payload = mp3_frame.dead_air(1)  # 1ms = 1 frame
     msg.mp3_header = mp3_header.parse(msg.payload)
     msg.start_timestamp_ms = test_ms
     msg.end_timestamp_ms = test_ms + msg.mp3_header.duration_ms
     # Add the message to our source, twice, and wait for it to be
     # processed.  We add the message twice to work around the bug
     # whereby mutagen will choke on a single-frame MP3.
     src._add_message(msg)
     src._add_message(msg)
     src.wait_until_empty()
     # The archiver's rollover count should still be zero.
     self.assertEqual(0, arch.rollover_count)
     # Now advance the timestamp by one hour and re-add the message.
     # That should trigger a rollover.
     one_hour_in_ms = 1000 * 60 * 60
     msg.start_timestamp_ms += one_hour_in_ms
     msg.end_timestamp_ms += one_hour_in_ms
     src._add_message(msg)
     src.wait_until_empty()
     # Now there should have been a rollover.
     self.assertEqual(1, arch.rollover_count)
     src._add_message(msg)  # Again, to avoid the mutagen bug.
     # Shut down the archiver's thread, then wait for it to terminate.
     src._add_stop_message()
     arch.wait()
Exemplo n.º 3
0
    def test_basic(self):
        # Create a test MP3Writer.
        test_prefix = "/tmp/mp3_writer_test"
        test_start_ms = 1262479500000
        writer = mp3_writer.MP3Writer(prefix=test_prefix,
                                      start_ms=test_start_ms)
        self.assertEqual("/tmp/mp3_writer_test-20100102-184500.000.mp3",
                         writer.path)

        # Set up a dummy MP3 frame (corresonding to our dead air)
        # message and repeatedly add it to the writer.
        msg = message.Message()
        msg.message_type = message.FRAME
        msg.payload = mp3_frame.dead_air(1)  # 1 ms => a single frame
        msg.mp3_header = mp3_header.parse(msg.payload)

        # Set up a dummy block message.
        block_msg = message.Message()
        block_msg.message_type = message.BLOCK
        block_msg.payload = "FOO BAR BAZ"

        # Now repeatedly add the test message to the writer.
        time_ms = test_start_ms
        for i in xrange(10):
            msg.start_timestamp_ms = time_ms
            time_ms += msg.mp3_header.duration_ms
            msg.end_timestamp_ms = time_ms
            writer.write(msg)
            # Also add the block message in.  It should be ignored.
            writer.write(block_msg)

        # At this point the duration should be 10x the individual frame
        # duration.
        self.assertAlmostEqual(10*msg.mp3_header.duration_ms,
                               writer.duration_ms)
        # We should also have the correct frame count and size.
        self.assertEqual(10, writer.frame_count)
        self.assertEqual(10*len(msg.payload), writer.frame_size)

        # The file should be fully flushed out to disk, so we should be
        # able to inspect it with mutagen and see something with the
        # expected duration and tags.
        partial_mp3 = mutagen.mp3.MP3(writer.path)
        self.assertAlmostEqual(writer.duration_ms/1000,  # mutagen uses seconds
                               partial_mp3.info.length)
        # These are only some of the tags.
        self.assertTrue("TRSN" in partial_mp3)
        self.assertEqual([u"CHIRP Radio"], partial_mp3["TRSN"].text)
        self.assertTrue("TIT1" in partial_mp3)
        self.assertEqual([u"20100102-184500.000 to ???????????????????"],
                         partial_mp3["TIT1"].text)

        # Now close the writer.  After that, we should be able to open
        # it with mutagen and see the final tags.
        writer.close()
        final_mp3 = mutagen.mp3.MP3(writer.path)
        self.assertAlmostEqual(writer.duration_ms/1000, final_mp3.info.length)
        # Check finalized title.
        self.assertEqual([u"20100102-184500.000 to 20100102-184500.261"],
                         final_mp3["TIT1"].text)
        # Check frame count.
        self.assertTrue(constants.TXXX_FRAME_COUNT_KEY in final_mp3)
        self.assertEqual([unicode(writer.frame_count)],
                         final_mp3[constants.TXXX_FRAME_COUNT_KEY].text)
        # Check frame size.
        self.assertTrue(constants.TXXX_FRAME_SIZE_KEY in final_mp3)
        self.assertEqual([unicode(writer.frame_size)],
                         final_mp3[constants.TXXX_FRAME_SIZE_KEY].text)
        # Check UFID.
        self.assertTrue(constants.MUTAGEN_UFID_KEY in final_mp3)
        self.assertEqual(
            "volff/20100102-184500/8f5bb4f4b0ded8d29baa778f121ef3063db7a3f7",
            final_mp3[constants.MUTAGEN_UFID_KEY].data)

        # It should be safe to call close twice.
        writer.close()