From 27fd2f16e6e777de85ec081abbe78c6ddaae72ab Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 12 Apr 2009 10:20:14 +0000 Subject: [PATCH] * morituri/image/image.py: * morituri/test/test_image_image.py: Add a task for calculating frame length of an audio file. Add a test for it. --- ChangeLog | 7 +++++ morituri/image/image.py | 44 +++++++++++++++++++++++++++++++ morituri/test/test_image_image.py | 9 +++++++ 3 files changed, 60 insertions(+) diff --git a/ChangeLog b/ChangeLog index dce906b..e1c94a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-04-12 Thomas Vander Stichele + + * morituri/image/image.py: + * morituri/test/test_image_image.py: + Add a task for calculating frame length of an audio file. + Add a test for it. + 2009-04-12 Thomas Vander Stichele * morituri/common/task.py: diff --git a/morituri/image/image.py b/morituri/image/image.py index 05641ad..6a6ce73 100644 --- a/morituri/image/image.py +++ b/morituri/image/image.py @@ -26,6 +26,8 @@ Wrap on-disk CD images based on the .cue file. import os +import gst + from morituri.common import task, crc from morituri.image import cue @@ -120,3 +122,45 @@ class AudioRipCRCTask(task.Task): # pick another self.start(self.runner) + +class AudioLengthTask(task.Task): + """ + I calculate the length of a track in audio frames. + + @ivar length: length of the decoded audio file, in audio frames. + """ + + length = None + + def __init__(self, path): + self._path = path + + def debug(self, *args, **kwargs): + return + print args, kwargs + + def start(self, runner): + task.Task.start(self, runner) + self._pipeline = gst.parse_launch(''' + filesrc location="%s" ! + decodebin ! audio/x-raw-int ! + fakesink name=sink''' % self._path) + self.debug('pausing') + self._pipeline.set_state(gst.STATE_PAUSED) + self._pipeline.get_state() + self.debug('paused') + + self.debug('query duration') + sink = self._pipeline.get_by_name('sink') + assert sink, 'Error constructing pipeline' + + length, format = sink.query_duration(gst.FORMAT_DEFAULT) + # wavparse 0.10.14 returns in bytes + if format == gst.FORMAT_BYTES: + self.debug('query returned in BYTES format') + length /= 4 + self.debug('total length', length) + self.length = length + self._pipeline.set_state(gst.STATE_NULL) + + self.stop() diff --git a/morituri/test/test_image_image.py b/morituri/test/test_image_image.py index 112b8b5..37ba006 100644 --- a/morituri/test/test_image_image.py +++ b/morituri/test/test_image_image.py @@ -45,4 +45,13 @@ class KingsSeparateTestCase(unittest.TestCase): self.assertEquals(h(crctask.crcs[2]), '0xd63dc2d2') self.assertEquals(h(crctask.crcs[3]), '0x7271db39') +class AudioLengthTestCase(unittest.TestCase): + def testLength(self): + path = os.path.join(os.path.dirname(__file__), 'track.flac') + t = image.AudioLengthTask(path) + runner = task.SyncRunner() + runner.run(t, verbose=False) + self.assertEquals(t.length, 5880) + +