3 Commits
v1.4.1 ... v1.5

Author SHA1 Message Date
Jamie Hardt
6c8cc47788 Update README.md
Added note on command-line entry point
2020-01-05 10:10:37 -08:00
Jamie Hardt
a90d3f4b38 Version 1.5
Added command-line entrypoint, more UMID implementation
2020-01-05 10:05:54 -08:00
Jamie Hardt
3ede4de06a Delete pypi_upload.sh 2020-01-04 22:30:15 -08:00
8 changed files with 75 additions and 18 deletions

2
.idea/vcs.xml generated
View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
</component> </component>
</project> </project>

View File

@@ -41,6 +41,12 @@ path = '../tests/test_files/A101_1.WAV'
info = WavInfoReader(path) info = WavInfoReader(path)
``` ```
The package also installs a shell command:
```sh
$ wavinfo test_files/A101_1.WAV
```
### Basic WAV Data ### Basic WAV Data
The length of the file in frames (interleaved samples) and bytes is available, as is the contents of the format chunk. The length of the file in frames (interleaved samples) and bytes is available, as is the contents of the format chunk.

View File

@@ -1,2 +0,0 @@
#!/bin/bash
python3 -m twine upload --repository-url https://upload.pypi.org/legacy/ dist/*

View File

@@ -1,15 +1,17 @@
from setuptools import setup from setuptools import setup
from wavinfo import __author__, __license__, __version__
with open("README.md", "r") as fh: with open("README.md", "r") as fh:
long_description = fh.read() long_description = fh.read()
setup(name='wavinfo', setup(name='wavinfo',
version='1.4.1', version=__version__,
author='Jamie Hardt', author=__author__,
author_email='jamiehardt@me.com', author_email='jamiehardt@me.com',
description='Probe WAVE Files for iXML, Broadcast-WAVE and other metadata.', description='Probe WAVE Files for iXML, Broadcast-WAVE and other metadata.',
long_description_content_type="text/markdown", long_description_content_type="text/markdown",
long_description=long_description, long_description=long_description,
license=__license__,
url='https://github.com/iluvcapra/wavinfo', url='https://github.com/iluvcapra/wavinfo',
project_urls={ project_urls={
'Source': 'Source':
@@ -29,5 +31,10 @@ setup(name='wavinfo',
"Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8"], "Programming Language :: Python :: 3.8"],
keywords='waveform metadata audio ebu smpte avi library film tv editing editorial', keywords='waveform metadata audio ebu smpte avi library film tv editing editorial',
install_requires=['lxml'] install_requires=['lxml'],
entry_points={
'console_scripts': [
'wavinfo = wavinfo.__main__:main'
]
}
) )

View File

@@ -7,6 +7,6 @@ Go to the documentation for wavinfo.WavInfoReader for more information.
from .wave_reader import WavInfoReader from .wave_reader import WavInfoReader
from .riff_parser import WavInfoEOFError from .riff_parser import WavInfoEOFError
__version__ = '1.4.1' __version__ = '1.5'
__author__ = 'Jamie Hardt <jamiehardt@gmail.com>' __author__ = 'Jamie Hardt <jamiehardt@gmail.com>'
__license__ = "MIT" __license__ = "MIT"

32
wavinfo/__main__.py Normal file
View File

@@ -0,0 +1,32 @@
from optparse import OptionParser, OptionGroup
import datetime
from . import WavInfoReader
import sys
import json
def main():
parser = OptionParser()
parser.usage = 'wavinfo [FILE.wav]*'
# parser.add_option('-f', dest='output_format', help='Set the output format',
# default='json',
# metavar='FORMAT')
(options, args) = parser.parse_args(sys.argv)
for arg in args[1:]:
try:
this_file = WavInfoReader(path=arg)
ret_dict = {'file_argument': arg, 'run_date': datetime.datetime.now().isoformat() , 'scopes': {}}
for scope, name, value in this_file.walk():
if scope not in ret_dict['scopes'].keys():
ret_dict['scopes'][scope] = {}
ret_dict['scopes'][scope][name] = value
json.dump(ret_dict, fp=sys.stdout, indent=2)
except Exception as e:
print(e)
if __name__ == "__main__":
main()

View File

@@ -10,10 +10,27 @@ class UMIDParser:
def __init__(self, raw_umid: bytearray): def __init__(self, raw_umid: bytearray):
self.raw_umid = raw_umid self.raw_umid = raw_umid
@classmethod
def binary_to_string(cls, binary_value):
result_str = ''
for n in range(len(binary_value)):
result_str = f'{binary_value[n]:x}' + result_str
return result_str
@property @property
def universal_label(self) -> bytearray: def universal_label(self) -> bytearray:
return self.raw_umid[0:12] return self.raw_umid[0:12]
@property
def basic_umid(self):
return self.raw_umid[0:32]
def basic_umid_to_str(self):
return "%024x-%06x-%032x" % (self.binary_to_string(self.universal_label),
self.binary_to_string(self.instance_number),
self.binary_to_string(self.material_number))
@property @property
def universal_label_is_valid(self) -> bool: def universal_label_is_valid(self) -> bool:
valid_preamble = b'\x06\x0a\x2b\x34\x01\x01\x01\x05\x01\x01' valid_preamble = b'\x06\x0a\x2b\x34\x01\x01\x01\x05\x01\x01'
@@ -95,19 +112,12 @@ class UMIDParser:
return 'extended' return 'extended'
@property @property
def instance_number(self) -> int: def instance_number(self) -> bytearray:
return struct.unpack('<I', self.raw_umid[13:4])[0] & 0x00ffffff return self.raw_umid[13:3]
@property @property
def material_number(self) -> bytearray: def material_number(self) -> bytearray:
return self.raw_umid[14:16] return self.raw_umid[16:16]
@property
def material_number_hex(self) -> str:
result_str = ''
for n in range(16):
result_str = '{:x}'.format(self.material_number[n]) + result_str
return result_str
@property @property
def source_pack(self) -> Union[bytearray, None]: def source_pack(self) -> Union[bytearray, None]:

View File

@@ -147,9 +147,13 @@ class WavInfoReader():
metadata field, and the value. metadata field, and the value.
""" """
scopes = ('fmt','data')#,'bext','ixml','info') scopes = ('fmt', 'data') #'bext', 'ixml', 'info')
for scope in scopes: for scope in scopes:
attr = self.__getattribute__(scope) attr = self.__getattribute__(scope)
for field in attr._fields: for field in attr._fields:
yield scope, field, attr.__getattribute__(field) yield scope, field, attr.__getattribute__(field)
bext_dict = self.bext.to_dict()
for key in bext_dict.keys():
yield 'bext', key, bext_dict[key]