25 Commits

Author SHA1 Message Date
Jamie Hardt
edbe748718 Update metadata.py 2022-11-15 11:17:02 -08:00
Jamie Hardt
2019a4ec63 Update pythonpublish.yml
Switched to pypi token authentication
2022-11-15 11:12:00 -08:00
Jamie Hardt
fb43838c7d Update README.md 2022-11-15 11:06:28 -08:00
Jamie Hardt
4cd58b8ddd Delete .travis.yml 2022-11-15 11:04:30 -08:00
Jamie Hardt
38dab7723f Update python-package.yml
Changed action name
2022-11-15 11:02:14 -08:00
Jamie Hardt
354d88a5b2 Update python-package.yml
Removed 3.6 and 3.7 from test grid
2022-11-15 10:58:51 -08:00
Jamie Hardt
d8a405b6d2 Update setup.py
Dropping 3.6 and 3.7, there seems to be a lxml conflict with its dependencies on numpy.
2022-11-15 10:58:12 -08:00
Jamie Hardt
5f7e467fbd Update python-package.yml 2022-11-15 10:56:11 -08:00
Jamie Hardt
3377ddb4b9 Updated ear to latest version 2022-11-15 10:53:12 -08:00
Jamie Hardt
9cd6cf7f12 Relieved requirements for attrs package 2022-11-15 10:51:02 -08:00
Jamie Hardt
1f8ebe253b Updated requirements for pytest 2022-11-15 10:49:18 -08:00
Jamie Hardt
fe46d1b242 Update python-package.yml 2022-11-15 10:37:04 -08:00
Jamie Hardt
b213933ad8 Update README.md 2022-11-15 10:35:59 -08:00
Jamie Hardt
7e314f7475 Update README.md 2022-11-15 10:34:41 -08:00
Jamie Hardt
b2d6fd3c92 Update README.md 2022-11-15 10:34:07 -08:00
Jamie Hardt
c4d8608c8f Create python-package.yml 2022-11-15 10:33:36 -08:00
Jamie Hardt
5605b05f9f Update README.md 2022-11-15 10:32:11 -08:00
Jamie Hardt
5d71cabda7 Delete .coveragerc 2022-11-15 10:30:31 -08:00
Jamie Hardt
c2f87b1fef Update README.md 2022-11-15 10:29:58 -08:00
Jamie Hardt
3db40d4f12 Added dosctring 2022-11-13 22:43:22 +00:00
Jamie Hardt
40b30f5bd8 Merge pull request #11 from soundappraisal/master
Make wavinfo work with filehandles.
2022-11-03 18:03:51 -07:00
Ronald van Elburg
048f20c64c Move version and author information to separate file. The current location leads to problems with dependencies which are only resolved after running pip. 2022-10-17 15:18:24 +02:00
Ronald van Elburg
6a69df2ee8 Move version and author information to separate file. The current location leads to problems with dependencies which are only resolved after running pip. 2022-10-17 13:28:28 +02:00
Ronald van Elburg
ec327ee76f Move version and author information to separate file. The current location leads to problems with dependencies which are only resolved after running pip. 2022-10-17 13:25:41 +02:00
Ronald van Elburg
62a34cfee8 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__. 2022-08-30 11:42:47 +02:00
11 changed files with 112 additions and 85 deletions

View File

@@ -1,13 +0,0 @@
[run]
branch = True
source = wavinfo
[report]
exclude_lines =
if self.debug:
pragma: no cover
raise NotImplementedError
if __name__ == .__main__.:
ignore_errors = True
omit =
tests/*

42
.github/workflows/python-package.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
name: Python Lint and Test
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.8", "3.9", "3.10"]
steps:
- uses: actions/checkout@v2.5.0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4.3.0
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Setup FFmpeg
uses: FedericoCarboni/setup-ffmpeg@v2
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
run: |
pytest

View File

@@ -19,7 +19,7 @@ jobs:
pip install setuptools wheel twine lxml
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel

View File

@@ -1,27 +0,0 @@
dist: xenial
language: python
python:
# - "2.7"
# - "3.5"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
script:
- "gunzip tests/test_files/rf64/*.gz"
- "python setup.py test"
- "python -m pytest tests/ -v --cov wavinfo --cov-report term-missing"
before_install:
- "sudo apt-get update"
- "sudo add-apt-repository universe"
- "sudo apt-get install -y ffmpeg"
- "pip install pytest"
- "pip install lxml"
- "pip install coverage"
- "pip install codecov"
- "pip install pytest-cov==2.5.0"
- "pip install coverage==4.4"
install:
- "pip install setuptools"
after_success:
- "codecov"

View File

@@ -1,6 +1,5 @@
[![Build Status](https://travis-ci.com/iluvcapra/wavinfo.svg?branch=master)](https://travis-ci.com/iluvcapra/wavinfo)
[![codecov](https://codecov.io/gh/iluvcapra/wavinfo/branch/master/graph/badge.svg)](https://codecov.io/gh/iluvcapra/wavinfo)
[![Documentation Status](https://readthedocs.org/projects/wavinfo/badge/?version=latest)](https://wavinfo.readthedocs.io/en/latest/?badge=latest) ![](https://img.shields.io/github/license/iluvcapra/wavinfo.svg) ![](https://img.shields.io/pypi/pyversions/wavinfo.svg) [![](https://img.shields.io/pypi/v/wavinfo.svg)](https://pypi.org/project/wavinfo/) ![](https://img.shields.io/pypi/wheel/wavinfo.svg)
![Lint and Test](https://github.com/iluvcapra/wavinfo/actions/workflows/python-package.yml/badge.svg)
<!-- ![Test](https://github.com/iluvcapra/wavinfo/workflows/Upload%20Python%20Package/badge.svg) -->
@@ -60,10 +59,6 @@ The length of the file in frames (interleaved samples) and bytes is available, a
>>> (48000, 2, 6, 24)
```
## Platform Lifecycle Stuff
Python 3.5 support is deprecated.
## Other Resources
* For other file formats and ID3 decoding, look at [audio-metadata](https://github.com/thebigmunch/audio-metadata).

6
metadata.py Normal file
View File

@@ -0,0 +1,6 @@
"""
Wavinfo
"""
__version__ = '1.7.0'
__author__ = 'Jamie Hardt <jamiehardt@gmail.com>'
__license__ = "MIT"

View File

@@ -1,3 +1,19 @@
lxml>=4.6.5
setuptools~=49.6.0
ear~=2.0.0
attrs==21.4.0
ear==2.1.0
enum34==1.1.10
exceptiongroup==1.0.4
iniconfig==1.1.1
lxml==4.9.1
multipledispatch==0.6.0
numpy==1.23.3
packaging==21.3
pluggy==1.0.0
pyparsing==3.0.9
pytest==7.2.0
ruamel.yaml==0.17.21
ruamel.yaml.clib==0.2.6
scipy==1.9.1
six==1.16.0
style==1.1.0
tomli==2.0.1
update==0.0.1

View File

@@ -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()
@@ -26,9 +26,6 @@ setup(name='wavinfo',
'License :: OSI Approved :: MIT License',
'Topic :: Multimedia',
'Topic :: Multimedia :: Sound/Audio',
# "Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10"],

View File

@@ -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):

View File

@@ -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 <jamiehardt@gmail.com>'
__license__ = "MIT"

View File

@@ -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)