From 62a34cfee87f4e6ad17c3bbdf213bc899b644bc8 Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Tue, 30 Aug 2022 11:42:47 +0200 Subject: [PATCH 1/4] Make it possible to pass file handles or in memory wav data to wavinfo. Some of the fields for the __repr__ where not available for files. For these the url member is set to "about:blank", and the self.path to the representation of the incoming object. The formating in __repr__ turned out to be broken, with fixing that we also had to fix the test on __repr__. --- tests/test_wave_parsing.py | 2 +- wavinfo/wave_reader.py | 68 +++++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/tests/test_wave_parsing.py b/tests/test_wave_parsing.py index db4b8e2..63f67e1 100644 --- a/tests/test_wave_parsing.py +++ b/tests/test_wave_parsing.py @@ -12,7 +12,7 @@ class TestWaveInfo(TestCase): def test_sanity(self): for wav_file in all_files(): info = wavinfo.WavInfoReader(wav_file) - self.assertEqual(info.__repr__(), 'WavInfoReader(%s, %s, %s)'.format(wav_file, 'latin_1', 'ascii')) + self.assertEqual(info.__repr__(), 'WavInfoReader({}, latin_1, ascii)'.format(os.path.abspath(wav_file))) self.assertIsNotNone(info) def test_fmt_against_ffprobe(self): diff --git a/wavinfo/wave_reader.py b/wavinfo/wave_reader.py index 85b68a0..1ff8e24 100644 --- a/wavinfo/wave_reader.py +++ b/wavinfo/wave_reader.py @@ -27,43 +27,57 @@ class WavInfoReader: """ Create a new reader object. - :param path: A filesystem path to the wav file you wish to probe. + :param path: + A filesystem path to the wav file you wish to probe or a + file handle to an open file. - :param info_encoding: The text encoding of the INFO metadata fields. - latin_1/Win CP1252 has always been a pretty good guess for this. + :param info_encoding: + The text encoding of the INFO metadata fields. + latin_1/Win CP1252 has always been a pretty good guess for this. - :param bext_encoding: The text encoding to use when decoding the string - fields of the Broadcast-WAV extension. Per EBU 3285 this is ASCII - but this parameter is available to you if you encounter a weirdo. + :param bext_encoding: + The text encoding to use when decoding the string + fields of the Broadcast-WAV extension. Per EBU 3285 this is ASCII + but this parameter is available to you if you encounter a weirdo. """ - absolute_path = os.path.abspath(path) - - #: `file://` url for the file. - self.url = pathlib.Path(absolute_path).as_uri() - - # for __repr__() - self.path = absolute_path + self.info_encoding = info_encoding self.bext_encoding = bext_encoding + + if hasattr(path, 'read'): + self.get_wav_info(path) + self.url = 'about:blank' + self.path = repr(path) + else: + absolute_path = os.path.abspath(path) - with open(path, 'rb') as f: - chunks = parse_chunk(f) + #: `file://` url for the file. + self.url = pathlib.Path(absolute_path).as_uri() - self.main_list = chunks.children - f.seek(0) + # for __repr__() + self.path = absolute_path + + with open(path, 'rb') as f: + self.get_wav_info(f) + + def get_wav_info(self, wavfile): + chunks = parse_chunk(wavfile) - #: :class:`wavinfo.wave_reader.WavAudioFormat` - self.fmt = self._get_format(f) + self.main_list = chunks.children + wavfile.seek(0) - #: :class:`wavinfo.wave_bext_reader.WavBextReader` with Broadcast-WAV metadata - self.bext = self._get_bext(f, encoding=bext_encoding) + #: :class:`wavinfo.wave_reader.WavAudioFormat` + self.fmt = self._get_format(wavfile) - #: :class:`wavinfo.wave_ixml_reader.WavIXMLFormat` with iXML metadata - self.ixml = self._get_ixml(f) + #: :class:`wavinfo.wave_bext_reader.WavBextReader` with Broadcast-WAV metadata + self.bext = self._get_bext(wavfile, encoding=self.bext_encoding) - #: :class:`wavinfo.wave_info_reader.WavInfoChunkReader` with RIFF INFO metadata - self.info = self._get_info(f, encoding=info_encoding) - self.data = self._describe_data() + #: :class:`wavinfo.wave_ixml_reader.WavIXMLFormat` with iXML metadata + self.ixml = self._get_ixml(wavfile) + + #: :class:`wavinfo.wave_info_reader.WavInfoChunkReader` with RIFF INFO metadata + self.info = self._get_info(wavfile, encoding=self.info_encoding) + self.data = self._describe_data() def _find_chunk_data(self, ident, from_stream, default_none=False): top_chunks = (chunk for chunk in self.main_list if type(chunk) is ChunkDescriptor and chunk.ident == ident) @@ -146,4 +160,4 @@ class WavInfoReader: yield 'info', key, info_dict[key] def __repr__(self): - return 'WavInfoReader(%s, %s, %s)'.format(self.path, self.info_encoding, self.bext_encoding) + return 'WavInfoReader({}, {}, {})'.format(self.path, self.info_encoding, self.bext_encoding) From ec327ee76fbd4fcc48c687d0938a162839a50014 Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Mon, 17 Oct 2022 13:25:41 +0200 Subject: [PATCH 2/4] Move version and author information to separate file. The current location leads to problems with dependencies which are only resolved after running pip. --- metadata.py | 4 ++++ setup.py | 2 +- wavinfo/__init__.py | 3 --- 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 metadata.py diff --git a/metadata.py b/metadata.py new file mode 100644 index 0000000..e7ba61e --- /dev/null +++ b/metadata.py @@ -0,0 +1,4 @@ + +__version__ = '1.6.3' +__author__ = 'Jamie Hardt ' +__license__ = "MIT" diff --git a/setup.py b/setup.py index ee26d90..ed2ac7a 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,5 @@ from setuptools import setup -from wavinfo import __author__, __license__, __version__ +from metadata import __author__, __license__, __version__ with open("README.md", "r") as fh: long_description = fh.read() diff --git a/wavinfo/__init__.py b/wavinfo/__init__.py index 02d6843..c030227 100644 --- a/wavinfo/__init__.py +++ b/wavinfo/__init__.py @@ -7,6 +7,3 @@ Go to the documentation for wavinfo.WavInfoReader for more information. from .wave_reader import WavInfoReader from .riff_parser import WavInfoEOFError -__version__ = '1.6.3' -__author__ = 'Jamie Hardt ' -__license__ = "MIT" From 6a69df2ee8069378d1ef000c6dc202fa7723a0ff Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Mon, 17 Oct 2022 13:28:28 +0200 Subject: [PATCH 3/4] Move version and author information to separate file. The current location leads to problems with dependencies which are only resolved after running pip. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index ed2ac7a..549b725 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ setup(name='wavinfo', "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10"], keywords='waveform metadata audio ebu smpte avi library film tv editing editorial', - install_requires=['lxml', 'ear'], + install_requires=['lxml', 'wheel', 'ear'], entry_points={ 'console_scripts': [ 'wavinfo = wavinfo.__main__:main' From 048f20c64c838a430f5fb8a55fd9b95b955b013f Mon Sep 17 00:00:00 2001 From: Ronald van Elburg Date: Mon, 17 Oct 2022 15:18:24 +0200 Subject: [PATCH 4/4] Move version and author information to separate file. The current location leads to problems with dependencies which are only resolved after running pip. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 549b725..ed2ac7a 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,7 @@ setup(name='wavinfo', "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10"], keywords='waveform metadata audio ebu smpte avi library film tv editing editorial', - install_requires=['lxml', 'wheel', 'ear'], + install_requires=['lxml', 'ear'], entry_points={ 'console_scripts': [ 'wavinfo = wavinfo.__main__:main'