audiometa-python 1.0.0__tar.gz → 1.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {audiometa_python-1.0.0/audiometa_python.egg-info → audiometa_python-1.1.2}/PKG-INFO +9 -9
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/README.md +8 -8
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/__init__.py +14 -26
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/cli.py +7 -2
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_MetadataManager.py +8 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/_Id3v2Manager.py +9 -41
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/riff/_RiffManager.py +7 -5
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/riff/_riff_info_chunk.py +19 -31
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/vorbis/_VorbisManager.py +6 -4
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v2/id3v2_metadata_setter.py +11 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/riff/riff_manual_metadata_creator.py +7 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/vorbis/vorbis_metadata_setter.py +6 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_binary_data_filtering.py +79 -117
- audiometa_python-1.1.2/audiometa/test/tests/integration/get_full_metadata/test_raw_metadata_includes_unsupported_tags.py +80 -0
- audiometa_python-1.1.2/audiometa/test/tests/unit/metadata_managers/header_info/test_riff_info_chunk_fourcc.py +70 -0
- audiometa_python-1.1.2/audiometa/test/tests/unit/utils/__init__.py +0 -0
- audiometa_python-1.1.2/audiometa/test/tests/unit/utils/test_raw_metadata_sanitizer.py +59 -0
- audiometa_python-1.1.2/audiometa/utils/raw_metadata_sanitizer.py +95 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2/audiometa_python.egg-info}/PKG-INFO +9 -9
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa_python.egg-info/SOURCES.txt +5 -1
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/pyproject.toml +1 -1
- audiometa_python-1.0.0/audiometa/test/tests/integration/get_full_metadata/options/test_include_cover.py +0 -30
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/LICENSE +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/__main__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/_audio_file.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/exceptions.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/_RatingSupportingMetadataManager.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/_id3v1_preserver.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/_id3v2_constants.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/_id3v2_flac_handler.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/_id3v2_reader.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/id3v2/_id3v2_writer.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/riff/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/riff/_riff_bext_chunk.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/riff/_riff_constants.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/riff/_riff_file_structure.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/vorbis/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/_rating_supporting/vorbis/_vorbis_constants.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/id3v1/_Id3v1Manager.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/id3v1/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/id3v1/_constants.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/id3v1/id3v1_raw_metadata.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/manager/id3v1/id3v1_raw_metadata_key.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/assets/create_test_files.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/common/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/common/audio_file_creator.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/common/external_tool_runner.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v1/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v1/id3v1_header_verifier.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v1/id3v1_metadata_deleter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v1/id3v1_metadata_getter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v1/id3v1_metadata_setter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v2/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v2/id3v2_frame_manual_creator.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v2/id3v2_header_verifier.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v2/id3v2_metadata_deleter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/id3v2/id3v2_metadata_getter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/riff/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/riff/riff_header_verifier.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/riff/riff_metadata_deleter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/riff/riff_metadata_getter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/riff/riff_metadata_setter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/scripts/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/technical_info_inspector.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/temp_file_with_metadata.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/vorbis/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/vorbis/vorbis_header_verifier.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/vorbis/vorbis_metadata_deleter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/helpers/vorbis/vorbis_metadata_getter.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/conftest.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_command_structure_errors.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_file_access_errors.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_format_output_errors.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_input_validation_errors.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_missing_fields_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_multiple_files_errors.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_rating_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/error_handling/test_year_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_basic.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_comprehensive.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_formats.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_metadata_content.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_multiple_files.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_options.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/read/test_unified.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/test_delete.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/test_formatting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/test_help.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_basic.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_comprehensive.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_force_format.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_integer_fields.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_list_fields.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_rating.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_string_fields.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/cli/write/test_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/scenarios/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/scenarios/test_user_scenarios.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/workflows/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/workflows/test_core_workflows.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/workflows/test_deletion_workflows.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/workflows/test_error_handling_workflows.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/workflows/test_format_specific_workflows.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/e2e/workflows/test_rating_workflows.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/flac/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/flac/test_flac_delete_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/flac/test_flac_reading_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/flac/test_flac_reading_field.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/flac/test_flac_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/mp3/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_delete_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_reading_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_reading_field.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/mp3/test_mp3_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/wav/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/wav/test_wav_delete_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/wav/test_wav_reading_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/wav/test_wav_reading_field.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/audio_format/wav/test_wav_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/conftest.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/delete_all_metadata/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/delete_all_metadata/test_audio_format_all.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/delete_all_metadata/test_audio_format_header_deletion.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/delete_all_metadata/test_basic_functionality.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/delete_all_metadata/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/encoding/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/encoding/test_encoding.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/encoding/test_special_characters_edge_cases.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/options/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/options/test_include_headers.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/options/test_include_technical.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_audio_formats.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_consistency.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_edge_cases.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_get_full_metadata.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_performance.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_riff_bext.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/get_full_metadata/test_structure.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album_artists/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album_artists/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album_artists/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/album_artists/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/artists/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/artists/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/artists/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/artists/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/bpm/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/bpm/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/bpm/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/bpm/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/comment/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/comment/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/comment/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/comment/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/composer/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/composer/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/composer/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/composer/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/copyright/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/copyright/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/copyright/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/copyright/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/description/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/description/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/description/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/description/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/disc_number/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/disc_number/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/disc_number/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/disc_number/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/field_not_supported/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/field_not_supported/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/field_not_supported/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/field_not_supported/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_id3v1_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_id3v2_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_riff_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/metadata_format/test_vorbis_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/reading/test_smart_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/genre/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/isrc/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/isrc/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/isrc/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/isrc/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/language/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/language/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/language/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/language/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/lyrics/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/lyrics/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/lyrics/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/lyrics/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_artistid/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/musicbrainz_trackid/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/originator/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/originator/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/originator/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/originator/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/publisher/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/publisher/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/publisher/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/publisher/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/reading/test_base_100_proportional.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_non_proportional.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/reading/test_base_255_proportional.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/writing/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_id3v2.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_riff.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/writing/metadata_format/test_vorbis.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/rating/writing/test_comprehensive.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/release_date/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/release_date/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/release_date/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/release_date/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/release_date/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/test_metadata_field_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/title/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/title/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/title/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/title/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/title/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/track_number/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/track_number/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/track_number/reading/test_edge_cases.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/track_number/reading/test_metadata_format.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/track_number/test_deleting.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/metadata_field/track_number/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v1.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v2_3.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_id3v2_4.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_riff.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/metadata_format/test_vorbis.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/test_performance_large_data.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/test_smart_parsing_scenarios.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/reading/test_unicode_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v1.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v2_3.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_id3v2_4.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_riff.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/metadata_format/test_vorbis.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/multiple_values/writing/test_large_values.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/reading/test_read_multiple_metadata.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/reading/test_reading_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/real_audio_files/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/real_audio_files/test_reading.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/real_audio_files/test_writing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/conftest.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_audio_data_corruption.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_file.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_invalid_md5.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_invalid_with_metadata_combinations.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_state_precedence.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_unset_with_metadata_combinations.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_validation_fails_with_id3v1.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_validation_with_id3v2_only.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_validation_works_without_id3v1.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_metadata_combinations/test_md5_with_metadata_combinations.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_checking/test_unset_md5.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_delete_original.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/test_flipped_md5.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/test_partial_md5.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_invalid_md5/test_random_md5.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_md5_repair_with_metadata.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_non_flac_error.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/flac_md5/md5_repair/test_unset_md5.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/test_bitrate.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/test_channels.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/test_duration_in_sec.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/technical_info/test_sample_rate.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/test_audio_file.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/test_audio_format_readable_after_update_all_metadata_formats.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/test_forced_format.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/test_multiple_format_preservation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/test_partial_update.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/test_flac_sync.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/test_mp3_sync.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/sync_strategy/test_wav_sync.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/test_cleanup_strategy.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/test_preserve_strategy.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_fail_behavior.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_no_writing_on_failure.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/integration/writing/writing_strategies/unsupported_fields/test_strategy_specific.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_bitrate.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_channels.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_duration_in_sec.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_error_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_file_size.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_format_name.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/technical_info/test_sample_rate.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/test_context_manager.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/test_file_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/test_is_audio_file.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/test_operations.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/audio_file/test_path_handling.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/cli/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/cli/test_expand_file_patterns.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/conftest.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/header_info/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/header_info/test_id3v1.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/header_info/test_id3v2.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/header_info/test_riff.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/header_info/test_vorbis.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/disc_number/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/disc_number/test_disc_number_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/isrc/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/isrc/test_isrc_format_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/isrc/test_isrc_type_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/reading/test_smart_parsing.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/test_separator_selection.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/multiple_values/writing/test_value_filtering.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_artistid/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_artistid/test_musicbrainz_artistid_format_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_artistid/test_musicbrainz_artistid_type_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_trackid/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_trackid/test_musicbrainz_trackid_format_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_trackid/test_musicbrainz_trackid_type_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_uuid/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/musicbrainz_uuid/test_uuid_format_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/test_normalization.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/reading/test_profiles_values.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/test_rating_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_configuration_error.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/rating/writing/test_writing_profiles.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/release_date/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/release_date/test_date_format_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/test_type_validation_exception.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/test_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/track_number/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/metadata_field/track_number/test_track_number_validation.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/test_metadata_format_managers_write_and_read.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/test/tests/unit/metadata_managers/test_riff_configuration_error.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/flac_md5_state.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/id3v1_genre_code_map.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/metadata_format.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/metadata_writing_strategy.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/mutagen_exception_handler.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/os_dependencies_checker/__init__.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/os_dependencies_checker/base.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/os_dependencies_checker/config.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/os_dependencies_checker/macos.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/os_dependencies_checker/ubuntu.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/os_dependencies_checker/windows.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/rating_profiles.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/tool_path_resolver.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/types.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa/utils/unified_metadata_key.py +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa_python.egg-info/dependency_links.txt +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa_python.egg-info/entry_points.txt +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa_python.egg-info/requires.txt +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/audiometa_python.egg-info/top_level.txt +0 -0
- {audiometa_python-1.0.0 → audiometa_python-1.1.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: audiometa-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: A comprehensive Python library for reading and writing audio metadata across multiple formats
|
|
5
5
|
Author: AudioMeta Python Contributors
|
|
6
6
|
Author-email: Andreas Garcia <garcia.andreas.1991@gmail.com>
|
|
@@ -46,7 +46,7 @@ Dynamic: license-file
|
|
|
46
46
|
|
|
47
47
|
# AudioMeta Python
|
|
48
48
|
|
|
49
|
-
[](https://github.com/BehindTheMusicTree/audiometa/actions/workflows/lint-and-test.yml)
|
|
50
50
|
[](https://www.python.org/)
|
|
51
51
|
[](LICENSE)
|
|
52
52
|
[](https://pypi.org/project/audiometa-python/)
|
|
@@ -413,7 +413,7 @@ except MetadataFieldNotSupportedByMetadataFormatError as e:
|
|
|
413
413
|
|
|
414
414
|
#### Reading Full Metadata From All Formats Including Headers and Technical Info
|
|
415
415
|
|
|
416
|
-
**`get_full_metadata(file_path, include_headers=True, include_technical=True,
|
|
416
|
+
**`get_full_metadata(file_path, include_headers=True, include_technical=True, include_raw_binary_data=False)`**
|
|
417
417
|
|
|
418
418
|
Gets comprehensive metadata including all available information from a file, including headers and technical details even when no metadata is present.
|
|
419
419
|
|
|
@@ -688,7 +688,7 @@ id3v2_rating = get_unified_metadata_field("song.mp3", UnifiedMetadataKey.RATING,
|
|
|
688
688
|
|
|
689
689
|
#### Reading Full Metadata From All Formats Including Headers and Technical Info
|
|
690
690
|
|
|
691
|
-
**`get_full_metadata(file_path, include_headers=True, include_technical=True,
|
|
691
|
+
**`get_full_metadata(file_path, include_headers=True, include_technical=True, include_raw_binary_data=False)`**
|
|
692
692
|
|
|
693
693
|
Gets comprehensive metadata including all available information from a file, including headers and technical details even when no metadata is present.
|
|
694
694
|
|
|
@@ -699,7 +699,7 @@ This function provides the most complete view of an audio file by combining:
|
|
|
699
699
|
- All metadata from all supported formats (ID3v1, ID3v2, Vorbis, RIFF)
|
|
700
700
|
- Technical information (duration, bitrate, sample rate, channels, file size)
|
|
701
701
|
- Format-specific headers and structure information
|
|
702
|
-
- Raw metadata details from each format
|
|
702
|
+
- Raw metadata details from each format (when include_raw_binary_data is False, binary/opaque content such as APIC, PRIV, TRAKTOR4 is summarized as size placeholders)
|
|
703
703
|
|
|
704
704
|
```python
|
|
705
705
|
from audiometa import get_full_metadata, UnifiedMetadataKey
|
|
@@ -738,7 +738,7 @@ print(f"Raw Vorbis Comments: {full_metadata['raw_metadata']['vorbis']['comments'
|
|
|
738
738
|
- `file_path`: Path to the audio file (str or Path)
|
|
739
739
|
- `include_headers`: Whether to include format-specific header information (default: True)
|
|
740
740
|
- `include_technical`: Whether to include technical audio information (default: True)
|
|
741
|
-
- `
|
|
741
|
+
- `include_raw_binary_data`: If True, include raw binary/opaque content in raw_metadata (e.g. PRIV, APIC, TRAKTOR4). If False (default), such content is replaced by size placeholders.
|
|
742
742
|
|
|
743
743
|
**Returns:**
|
|
744
744
|
A comprehensive dictionary containing:
|
|
@@ -866,9 +866,6 @@ metadata_only = get_full_metadata("song.mp3", include_technical=False)
|
|
|
866
866
|
# Get only technical info without headers
|
|
867
867
|
tech_only = get_full_metadata("song.mp3", include_headers=False)
|
|
868
868
|
|
|
869
|
-
# Exclude cover/art from raw metadata
|
|
870
|
-
no_cover = get_full_metadata("song.mp3", include_cover=False)
|
|
871
|
-
|
|
872
869
|
# Check if file has specific format headers
|
|
873
870
|
if full_info['headers']['id3v2']['present']:
|
|
874
871
|
print("File has ID3v2 tags")
|
|
@@ -1514,6 +1511,9 @@ audiometa read song.mp3 --no-technical
|
|
|
1514
1511
|
# Exclude header information
|
|
1515
1512
|
audiometa read song.mp3 --no-headers
|
|
1516
1513
|
|
|
1514
|
+
# Include raw binary/opaque content in raw_metadata (default: size placeholders)
|
|
1515
|
+
audiometa read song.mp3 --include-raw-binary-data
|
|
1516
|
+
|
|
1517
1517
|
# Save to file
|
|
1518
1518
|
audiometa read song.mp3 --output metadata.json
|
|
1519
1519
|
```
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# AudioMeta Python
|
|
6
6
|
|
|
7
|
-
[](https://github.com/BehindTheMusicTree/audiometa/actions/workflows/lint-and-test.yml)
|
|
8
8
|
[](https://www.python.org/)
|
|
9
9
|
[](LICENSE)
|
|
10
10
|
[](https://pypi.org/project/audiometa-python/)
|
|
@@ -371,7 +371,7 @@ except MetadataFieldNotSupportedByMetadataFormatError as e:
|
|
|
371
371
|
|
|
372
372
|
#### Reading Full Metadata From All Formats Including Headers and Technical Info
|
|
373
373
|
|
|
374
|
-
**`get_full_metadata(file_path, include_headers=True, include_technical=True,
|
|
374
|
+
**`get_full_metadata(file_path, include_headers=True, include_technical=True, include_raw_binary_data=False)`**
|
|
375
375
|
|
|
376
376
|
Gets comprehensive metadata including all available information from a file, including headers and technical details even when no metadata is present.
|
|
377
377
|
|
|
@@ -646,7 +646,7 @@ id3v2_rating = get_unified_metadata_field("song.mp3", UnifiedMetadataKey.RATING,
|
|
|
646
646
|
|
|
647
647
|
#### Reading Full Metadata From All Formats Including Headers and Technical Info
|
|
648
648
|
|
|
649
|
-
**`get_full_metadata(file_path, include_headers=True, include_technical=True,
|
|
649
|
+
**`get_full_metadata(file_path, include_headers=True, include_technical=True, include_raw_binary_data=False)`**
|
|
650
650
|
|
|
651
651
|
Gets comprehensive metadata including all available information from a file, including headers and technical details even when no metadata is present.
|
|
652
652
|
|
|
@@ -657,7 +657,7 @@ This function provides the most complete view of an audio file by combining:
|
|
|
657
657
|
- All metadata from all supported formats (ID3v1, ID3v2, Vorbis, RIFF)
|
|
658
658
|
- Technical information (duration, bitrate, sample rate, channels, file size)
|
|
659
659
|
- Format-specific headers and structure information
|
|
660
|
-
- Raw metadata details from each format
|
|
660
|
+
- Raw metadata details from each format (when include_raw_binary_data is False, binary/opaque content such as APIC, PRIV, TRAKTOR4 is summarized as size placeholders)
|
|
661
661
|
|
|
662
662
|
```python
|
|
663
663
|
from audiometa import get_full_metadata, UnifiedMetadataKey
|
|
@@ -696,7 +696,7 @@ print(f"Raw Vorbis Comments: {full_metadata['raw_metadata']['vorbis']['comments'
|
|
|
696
696
|
- `file_path`: Path to the audio file (str or Path)
|
|
697
697
|
- `include_headers`: Whether to include format-specific header information (default: True)
|
|
698
698
|
- `include_technical`: Whether to include technical audio information (default: True)
|
|
699
|
-
- `
|
|
699
|
+
- `include_raw_binary_data`: If True, include raw binary/opaque content in raw_metadata (e.g. PRIV, APIC, TRAKTOR4). If False (default), such content is replaced by size placeholders.
|
|
700
700
|
|
|
701
701
|
**Returns:**
|
|
702
702
|
A comprehensive dictionary containing:
|
|
@@ -824,9 +824,6 @@ metadata_only = get_full_metadata("song.mp3", include_technical=False)
|
|
|
824
824
|
# Get only technical info without headers
|
|
825
825
|
tech_only = get_full_metadata("song.mp3", include_headers=False)
|
|
826
826
|
|
|
827
|
-
# Exclude cover/art from raw metadata
|
|
828
|
-
no_cover = get_full_metadata("song.mp3", include_cover=False)
|
|
829
|
-
|
|
830
827
|
# Check if file has specific format headers
|
|
831
828
|
if full_info['headers']['id3v2']['present']:
|
|
832
829
|
print("File has ID3v2 tags")
|
|
@@ -1472,6 +1469,9 @@ audiometa read song.mp3 --no-technical
|
|
|
1472
1469
|
# Exclude header information
|
|
1473
1470
|
audiometa read song.mp3 --no-headers
|
|
1474
1471
|
|
|
1472
|
+
# Include raw binary/opaque content in raw_metadata (default: size placeholders)
|
|
1473
|
+
audiometa read song.mp3 --include-raw-binary-data
|
|
1474
|
+
|
|
1475
1475
|
# Save to file
|
|
1476
1476
|
audiometa read song.mp3 --output metadata.json
|
|
1477
1477
|
```
|
|
@@ -1264,7 +1264,7 @@ def get_full_metadata(
|
|
|
1264
1264
|
file: PublicFileType,
|
|
1265
1265
|
include_headers: bool = True,
|
|
1266
1266
|
include_technical: bool = True,
|
|
1267
|
-
|
|
1267
|
+
include_raw_binary_data: bool = False,
|
|
1268
1268
|
) -> dict[str, Any]:
|
|
1269
1269
|
"""Get comprehensive metadata including all available information from a file.
|
|
1270
1270
|
|
|
@@ -1274,13 +1274,20 @@ def get_full_metadata(
|
|
|
1274
1274
|
- All metadata from all supported formats (ID3v1, ID3v2, Vorbis, RIFF)
|
|
1275
1275
|
- Technical information (duration, bitrate, sample rate, channels, file size)
|
|
1276
1276
|
- Format-specific headers and structure information
|
|
1277
|
-
- Raw metadata details from each format
|
|
1277
|
+
- Raw metadata details from each format. When include_raw_binary_data is False (default),
|
|
1278
|
+
binary/opaque frames (e.g. APIC, PRIV, TRAKTOR4) are summarized as size placeholders.
|
|
1279
|
+
|
|
1280
|
+
The result's raw_metadata contains every tag present in the file for each format:
|
|
1281
|
+
ID3v2 (all frames including custom TXXX/PRIV), Vorbis (all comments), ID3v1 (fixed set),
|
|
1282
|
+
RIFF (all INFO chunk FourCCs including custom), and BWF bext in chunk_structure.
|
|
1283
|
+
Per-format keys: id3v2.frames, vorbis.comments, id3v1/riff.parsed_fields, riff.chunk_structure.bext.
|
|
1278
1284
|
|
|
1279
1285
|
Args:
|
|
1280
1286
|
file: Audio file path (str or Path)
|
|
1281
1287
|
include_headers: Whether to include format-specific header information (default: True)
|
|
1282
1288
|
include_technical: Whether to include technical audio information (default: True)
|
|
1283
|
-
|
|
1289
|
+
include_raw_binary_data: If True, include raw binary/opaque content in raw_metadata (e.g. PRIV, APIC,
|
|
1290
|
+
TRAKTOR4). If False (default), such content is replaced by size placeholders.
|
|
1284
1291
|
|
|
1285
1292
|
Returns:
|
|
1286
1293
|
Comprehensive dictionary containing all available metadata and technical information
|
|
@@ -1395,10 +1402,12 @@ def get_full_metadata(
|
|
|
1395
1402
|
"extended_header": {},
|
|
1396
1403
|
}
|
|
1397
1404
|
|
|
1398
|
-
# Get raw metadata information
|
|
1405
|
+
# Get raw metadata information (optionally sanitize binary/opaque to placeholders)
|
|
1399
1406
|
try:
|
|
1400
1407
|
raw_info = manager.get_raw_metadata_info()
|
|
1401
|
-
raw_metadata_dict[format_key] =
|
|
1408
|
+
raw_metadata_dict[format_key] = (
|
|
1409
|
+
raw_info if include_raw_binary_data else manager.sanitize_raw_metadata_for_display(raw_info)
|
|
1410
|
+
)
|
|
1402
1411
|
except Exception:
|
|
1403
1412
|
raw_metadata_dict[format_key] = {
|
|
1404
1413
|
"raw_data": None,
|
|
@@ -1427,25 +1436,4 @@ def get_full_metadata(
|
|
|
1427
1436
|
"chunk_structure": {},
|
|
1428
1437
|
}
|
|
1429
1438
|
|
|
1430
|
-
if not include_cover:
|
|
1431
|
-
id3v2_raw = raw_metadata_dict.get("id3v2", {})
|
|
1432
|
-
frames = id3v2_raw.get("frames", {})
|
|
1433
|
-
if "APIC:" in frames:
|
|
1434
|
-
raw_metadata_dict["id3v2"] = {
|
|
1435
|
-
**id3v2_raw,
|
|
1436
|
-
"frames": {k: v for k, v in frames.items() if k != "APIC:"},
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
riff_raw = raw_metadata_dict.get("riff", {})
|
|
1440
|
-
riff_cover_parsed_keys = frozenset({"ICON"})
|
|
1441
|
-
riff_cover_chunk_keys = frozenset({"cover", "image"})
|
|
1442
|
-
parsed = riff_raw.get("parsed_fields", {})
|
|
1443
|
-
chunk = riff_raw.get("chunk_structure", {})
|
|
1444
|
-
if riff_cover_parsed_keys & frozenset(parsed) or riff_cover_chunk_keys & frozenset(chunk):
|
|
1445
|
-
raw_metadata_dict["riff"] = {
|
|
1446
|
-
**riff_raw,
|
|
1447
|
-
"parsed_fields": {k: v for k, v in parsed.items() if k not in riff_cover_parsed_keys},
|
|
1448
|
-
"chunk_structure": {k: v for k, v in chunk.items() if k not in riff_cover_chunk_keys},
|
|
1449
|
-
}
|
|
1450
|
-
|
|
1451
1439
|
return result
|
|
@@ -147,7 +147,7 @@ def _read_metadata(args: argparse.Namespace) -> None:
|
|
|
147
147
|
file_path,
|
|
148
148
|
include_headers=not getattr(args, "no_headers", False),
|
|
149
149
|
include_technical=not getattr(args, "no_technical", False),
|
|
150
|
-
|
|
150
|
+
include_raw_binary_data=getattr(args, "include_raw_binary_data", False),
|
|
151
151
|
)
|
|
152
152
|
|
|
153
153
|
output = format_output(metadata, args.output_format)
|
|
@@ -391,7 +391,12 @@ Examples:
|
|
|
391
391
|
read_parser.add_argument("--output", "-o", help="Output file (default: stdout)")
|
|
392
392
|
read_parser.add_argument("--no-headers", action="store_true", help="Exclude header information")
|
|
393
393
|
read_parser.add_argument("--no-technical", action="store_true", help="Exclude technical information")
|
|
394
|
-
read_parser.add_argument(
|
|
394
|
+
read_parser.add_argument(
|
|
395
|
+
"--include-raw-binary-data",
|
|
396
|
+
action="store_true",
|
|
397
|
+
dest="include_raw_binary_data",
|
|
398
|
+
help="Include raw binary/opaque in raw_metadata (e.g. APIC, PRIV); default: size placeholders",
|
|
399
|
+
)
|
|
395
400
|
read_parser.add_argument("--recursive", "-r", action="store_true", help="Process directories recursively")
|
|
396
401
|
read_parser.add_argument(
|
|
397
402
|
"--continue-on-error", action="store_true", help="Continue processing other files on error"
|
|
@@ -816,6 +816,14 @@ class _MetadataManager:
|
|
|
816
816
|
msg = "Not implemented for this format"
|
|
817
817
|
raise NotImplementedError(msg)
|
|
818
818
|
|
|
819
|
+
def sanitize_raw_metadata_for_display(self, raw_info: dict) -> dict:
|
|
820
|
+
"""Return raw_info with binary/opaque content replaced by size placeholders for safe display.
|
|
821
|
+
|
|
822
|
+
Override in managers whose raw metadata can contain binary or opaque data (e.g. ID3v2, Vorbis).
|
|
823
|
+
Default returns raw_info unchanged.
|
|
824
|
+
"""
|
|
825
|
+
return raw_info
|
|
826
|
+
|
|
819
827
|
def update_metadata(self, unified_metadata: UnifiedMetadata) -> None:
|
|
820
828
|
if not self.metadata_keys_direct_map_write:
|
|
821
829
|
msg = "This format does not support metadata modification"
|
|
@@ -30,6 +30,7 @@ from mutagen.id3._frames import (
|
|
|
30
30
|
)
|
|
31
31
|
from mutagen.id3._util import ID3NoHeaderError
|
|
32
32
|
|
|
33
|
+
from audiometa.utils.raw_metadata_sanitizer import sanitize_id3v2_raw_info
|
|
33
34
|
from audiometa.utils.unified_metadata_key import UnifiedMetadataKey
|
|
34
35
|
|
|
35
36
|
if TYPE_CHECKING:
|
|
@@ -620,49 +621,13 @@ class _Id3v2Manager(_RatingSupportingMetadataManager):
|
|
|
620
621
|
|
|
621
622
|
id3_metadata: ID3 = cast(ID3, self.raw_mutagen_metadata)
|
|
622
623
|
|
|
623
|
-
# Get raw frames (exclude binary frames like APIC)
|
|
624
624
|
frames = {}
|
|
625
|
-
binary_frame_types = {
|
|
626
|
-
"APIC:",
|
|
627
|
-
"GEOB:",
|
|
628
|
-
"AENC:",
|
|
629
|
-
"RVA2:",
|
|
630
|
-
"RVRB:",
|
|
631
|
-
"EQU2:",
|
|
632
|
-
"PCNT:",
|
|
633
|
-
"POPM:",
|
|
634
|
-
"RBUF:",
|
|
635
|
-
"LINK:",
|
|
636
|
-
"POSS:",
|
|
637
|
-
"SYLT:",
|
|
638
|
-
"USLT:",
|
|
639
|
-
"SYTC:",
|
|
640
|
-
"ETCO:",
|
|
641
|
-
"MLLT:",
|
|
642
|
-
"OWNE:",
|
|
643
|
-
"COMR:",
|
|
644
|
-
"ENCR:",
|
|
645
|
-
"GRID:",
|
|
646
|
-
"PRIV:",
|
|
647
|
-
"SIGN:",
|
|
648
|
-
"SEEK:",
|
|
649
|
-
"ASPI:",
|
|
650
|
-
}
|
|
651
|
-
|
|
652
625
|
for frame_id, frame in id3_metadata.items():
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
"flags": getattr(frame, "flags", 0),
|
|
659
|
-
}
|
|
660
|
-
else:
|
|
661
|
-
frames[frame_id] = {
|
|
662
|
-
"text": str(frame) if hasattr(frame, "__str__") else repr(frame),
|
|
663
|
-
"size": getattr(frame, "size", 0),
|
|
664
|
-
"flags": getattr(frame, "flags", 0),
|
|
665
|
-
}
|
|
626
|
+
frames[frame_id] = {
|
|
627
|
+
"text": str(frame) if hasattr(frame, "__str__") else repr(frame),
|
|
628
|
+
"size": getattr(frame, "size", 0),
|
|
629
|
+
"flags": getattr(frame, "flags", 0),
|
|
630
|
+
}
|
|
666
631
|
except Exception:
|
|
667
632
|
return {"raw_data": None, "parsed_fields": {}, "frames": {}, "comments": {}, "chunk_structure": {}}
|
|
668
633
|
else:
|
|
@@ -673,3 +638,6 @@ class _Id3v2Manager(_RatingSupportingMetadataManager):
|
|
|
673
638
|
"comments": {},
|
|
674
639
|
"chunk_structure": {},
|
|
675
640
|
}
|
|
641
|
+
|
|
642
|
+
def sanitize_raw_metadata_for_display(self, raw_info: dict) -> dict:
|
|
643
|
+
return sanitize_id3v2_raw_info(raw_info)
|
|
@@ -95,6 +95,10 @@ class _RiffManager(_RatingSupportingMetadataManager):
|
|
|
95
95
|
Note: This manager is the preferred way to handle WAV metadata, as it uses the format's native metadata system
|
|
96
96
|
rather than non-standard alternatives like ID3v2 tags. The custom implementation ensures proper handling of RIFF
|
|
97
97
|
chunk structures, maintaining word alignment and size fields according to the specification.
|
|
98
|
+
|
|
99
|
+
Raw metadata: get_raw_metadata_info() (and thus get_full_metadata()["raw_metadata"]["riff"]) includes every
|
|
100
|
+
INFO chunk FourCC present in the file in parsed_fields (no filtering by RiffTagKey). Only subchunks with
|
|
101
|
+
a valid 4-byte printable-ASCII FourCC are included; custom and known FourCCs are both returned.
|
|
98
102
|
"""
|
|
99
103
|
|
|
100
104
|
class RiffTagKey(RawMetadataKey):
|
|
@@ -193,7 +197,7 @@ class _RiffManager(_RatingSupportingMetadataManager):
|
|
|
193
197
|
|
|
194
198
|
This method directly parses the RIFF structure to extract metadata from the INFO chunk.
|
|
195
199
|
"""
|
|
196
|
-
return extract_riff_metadata_directly(file_data, self._skip_id3v2_tags
|
|
200
|
+
return extract_riff_metadata_directly(file_data, self._skip_id3v2_tags)
|
|
197
201
|
|
|
198
202
|
def _extract_bext_chunk(self, file_data: bytes) -> dict[str, Any] | None:
|
|
199
203
|
"""Extract and parse the bext chunk from BWF files."""
|
|
@@ -253,10 +257,8 @@ class _RiffManager(_RatingSupportingMetadataManager):
|
|
|
253
257
|
if hasattr(raw_mutagen_metadata_wav, "info") and raw_mutagen_metadata_wav.info is not None:
|
|
254
258
|
info_tags = raw_mutagen_metadata_wav.info
|
|
255
259
|
for key, value in info_tags.items():
|
|
256
|
-
#
|
|
257
|
-
|
|
258
|
-
# info_tags now contains lists of values, so we can pass them directly
|
|
259
|
-
raw_metadata_dict[key] = value
|
|
260
|
+
# info_tags contains lists of values; include every FourCC (known and custom)
|
|
261
|
+
raw_metadata_dict[key] = value
|
|
260
262
|
|
|
261
263
|
return raw_metadata_dict
|
|
262
264
|
|
|
@@ -5,37 +5,34 @@ standard metadata fields like title, artist, album, etc.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from collections.abc import Callable
|
|
8
|
-
from typing import TYPE_CHECKING, cast
|
|
9
8
|
|
|
10
9
|
from ....utils.types import RawMetadataKey
|
|
10
|
+
from ._riff_constants import RIFF_CHUNK_ID_SIZE, RIFF_HEADER_SIZE, RIFF_WAVE_FORMAT_POSITION
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
_FOURCC_MIN = 0x20
|
|
13
|
+
_FOURCC_MAX = 0x7E
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
|
|
16
|
+
def _is_valid_fourcc(fourcc_bytes: bytes) -> bool:
|
|
17
|
+
"""Return True if the 4 bytes form a valid INFO chunk FourCC (printable ASCII)."""
|
|
18
|
+
if len(fourcc_bytes) != RIFF_CHUNK_ID_SIZE:
|
|
19
|
+
return False
|
|
20
|
+
return all(_FOURCC_MIN <= b <= _FOURCC_MAX for b in fourcc_bytes)
|
|
16
21
|
|
|
17
22
|
|
|
18
23
|
def extract_riff_metadata_directly(
|
|
19
|
-
file_data: bytes, skip_id3v2_tags_func: Callable[[bytes], bytes]
|
|
24
|
+
file_data: bytes, skip_id3v2_tags_func: Callable[[bytes], bytes]
|
|
20
25
|
) -> dict[str, list[str]]:
|
|
21
26
|
"""Manually extract metadata from RIFF chunks without relying on external libraries.
|
|
22
27
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
file_data: Full file data (may include ID3v2 tags)
|
|
27
|
-
skip_id3v2_tags_func: Function to skip ID3v2 tags from file data
|
|
28
|
-
riff_tag_key_class: RiffTagKey class for validation
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
Dictionary mapping RIFF tag IDs to lists of values
|
|
28
|
+
Parses the RIFF structure and returns every INFO chunk field. No filtering by
|
|
29
|
+
RiffTagKey—known and custom FourCCs are included. Only subchunks with a valid
|
|
30
|
+
4-byte printable-ASCII FourCC are accepted.
|
|
32
31
|
"""
|
|
33
32
|
info_tags: dict[str, list[str]] = {}
|
|
34
33
|
|
|
35
|
-
# Skip ID3v2 if present
|
|
36
34
|
file_data = skip_id3v2_tags_func(file_data)
|
|
37
35
|
|
|
38
|
-
# Validate RIFF header
|
|
39
36
|
if (
|
|
40
37
|
len(file_data) < RIFF_HEADER_SIZE
|
|
41
38
|
or file_data[:RIFF_CHUNK_ID_SIZE] != b"RIFF"
|
|
@@ -43,40 +40,31 @@ def extract_riff_metadata_directly(
|
|
|
43
40
|
):
|
|
44
41
|
return info_tags
|
|
45
42
|
|
|
46
|
-
pos = 12
|
|
43
|
+
pos = 12
|
|
47
44
|
while pos < len(file_data) - 8:
|
|
48
45
|
chunk_id = file_data[pos : pos + 4]
|
|
49
46
|
chunk_size = int.from_bytes(file_data[pos + 4 : pos + 8], "little")
|
|
50
47
|
|
|
51
48
|
if chunk_id == b"LIST" and pos + 12 <= len(file_data) and file_data[pos + 8 : pos + 12] == b"INFO":
|
|
52
|
-
# Process INFO chunk
|
|
53
49
|
info_pos = pos + 12
|
|
54
50
|
info_end = pos + 8 + chunk_size
|
|
55
51
|
|
|
56
52
|
while info_pos < info_end - 8:
|
|
57
|
-
|
|
58
|
-
field_id = file_data[info_pos : info_pos + 4].decode("ascii", errors="ignore")
|
|
53
|
+
field_id_bytes = file_data[info_pos : info_pos + 4]
|
|
59
54
|
field_size = int.from_bytes(file_data[info_pos + 4 : info_pos + 8], "little")
|
|
60
55
|
|
|
61
|
-
if field_size > 0 and info_pos + 8 + field_size <= info_end:
|
|
62
|
-
|
|
56
|
+
if field_size > 0 and info_pos + 8 + field_size <= info_end and _is_valid_fourcc(field_id_bytes):
|
|
57
|
+
field_id = field_id_bytes.decode("ascii")
|
|
63
58
|
field_data = file_data[info_pos + 8 : info_pos + 8 + field_size - 1]
|
|
64
59
|
try:
|
|
65
|
-
|
|
66
|
-
field_value
|
|
67
|
-
# Split on null byte and take first part if exists
|
|
68
|
-
field_value = field_value.split("\x00")[0].strip()
|
|
69
|
-
# Compare field_id with enum member values (FourCC strings)
|
|
70
|
-
# Use getattr to safely access __members__ for type checking
|
|
71
|
-
members = getattr(riff_tag_key_class, "__members__", {})
|
|
72
|
-
if any(field_id == member.value for member in cast(dict, members).values()) and field_value:
|
|
60
|
+
field_value = field_data.decode("utf-8", errors="ignore").split("\x00")[0].strip()
|
|
61
|
+
if field_value:
|
|
73
62
|
if field_id not in info_tags:
|
|
74
63
|
info_tags[field_id] = []
|
|
75
64
|
info_tags[field_id].append(field_value)
|
|
76
65
|
except UnicodeDecodeError:
|
|
77
66
|
pass
|
|
78
67
|
|
|
79
|
-
# Move to next field, maintaining alignment
|
|
80
68
|
info_pos += 8 + ((field_size + 1) & ~1)
|
|
81
69
|
break
|
|
82
70
|
|
|
@@ -7,6 +7,7 @@ if TYPE_CHECKING:
|
|
|
7
7
|
from ...._audio_file import _AudioFile
|
|
8
8
|
from ....exceptions import FileCorruptedError, InvalidRatingValueError, MetadataFieldNotSupportedByMetadataFormatError
|
|
9
9
|
from ....utils.rating_profiles import RatingWriteProfile
|
|
10
|
+
from ....utils.raw_metadata_sanitizer import sanitize_vorbis_raw_info
|
|
10
11
|
from ....utils.tool_path_resolver import get_tool_path
|
|
11
12
|
from ....utils.types import RawMetadataDict, RawMetadataKey, UnifiedMetadata, UnifiedMetadataValue
|
|
12
13
|
from ....utils.unified_metadata_key import UnifiedMetadataKey
|
|
@@ -480,19 +481,20 @@ class _VorbisManager(_RatingSupportingMetadataManager):
|
|
|
480
481
|
|
|
481
482
|
def get_raw_metadata_info(self) -> dict:
|
|
482
483
|
try:
|
|
483
|
-
# Use custom parsing to get metadata
|
|
484
484
|
metadata = self._extract_mutagen_metadata()
|
|
485
|
-
|
|
486
485
|
return {
|
|
487
|
-
"raw_data": None,
|
|
486
|
+
"raw_data": None,
|
|
488
487
|
"parsed_fields": {},
|
|
489
488
|
"frames": {},
|
|
490
|
-
"comments": dict(metadata),
|
|
489
|
+
"comments": dict(metadata),
|
|
491
490
|
"chunk_structure": {},
|
|
492
491
|
}
|
|
493
492
|
except Exception:
|
|
494
493
|
return {"raw_data": None, "parsed_fields": {}, "frames": {}, "comments": {}, "chunk_structure": {}}
|
|
495
494
|
|
|
495
|
+
def sanitize_raw_metadata_for_display(self, raw_info: dict) -> dict:
|
|
496
|
+
return sanitize_vorbis_raw_info(raw_info)
|
|
497
|
+
|
|
496
498
|
def delete_metadata(self) -> bool:
|
|
497
499
|
"""Delete all metadata from the FLAC file by removing the VORBIS_COMMENT block."""
|
|
498
500
|
import subprocess
|
|
@@ -667,3 +667,14 @@ class ID3v2MetadataSetter:
|
|
|
667
667
|
|
|
668
668
|
data_bytes = data.encode("utf-8")
|
|
669
669
|
ManualID3v2FrameCreator.create_ufid_frame(file_path, owner, data_bytes, version="2.4")
|
|
670
|
+
|
|
671
|
+
@staticmethod
|
|
672
|
+
def set_custom_txxx(file_path: Path, description: str, value: str) -> None:
|
|
673
|
+
"""Set a custom TXXX frame (for testing raw_metadata includes unsupported frames)."""
|
|
674
|
+
command = [
|
|
675
|
+
get_tool_path("mid3v2"),
|
|
676
|
+
"--TXXX",
|
|
677
|
+
f"{description}:{value}",
|
|
678
|
+
str(file_path),
|
|
679
|
+
]
|
|
680
|
+
run_external_tool(command, "mid3v2")
|
|
@@ -342,3 +342,10 @@ class ManualRIFFMetadataCreator:
|
|
|
342
342
|
pos = chunk_end
|
|
343
343
|
|
|
344
344
|
return bytes(result)
|
|
345
|
+
|
|
346
|
+
@staticmethod
|
|
347
|
+
def add_custom_info_field(file_path: Path, fourcc: str, value: str) -> None:
|
|
348
|
+
"""Append a custom INFO chunk field (FourCC + value) for testing raw_metadata includes all tags."""
|
|
349
|
+
existing_fields = ManualRIFFMetadataCreator._read_existing_info_fields(file_path)
|
|
350
|
+
new_field = ManualRIFFMetadataCreator._create_info_field(fourcc, value)
|
|
351
|
+
ManualRIFFMetadataCreator._write_riff_info_chunk(file_path, [*existing_fields, new_field])
|
|
@@ -33,6 +33,12 @@ class VorbisMetadataSetter:
|
|
|
33
33
|
command = ["metaflac", "--set-tag", f"{tag_name}={value}", str(file_path)]
|
|
34
34
|
run_external_tool(command, "metaflac")
|
|
35
35
|
|
|
36
|
+
@staticmethod
|
|
37
|
+
def set_tag(file_path: Path, tag_name: str, value: str) -> None:
|
|
38
|
+
"""Set a single Vorbis comment tag (e.g. TRAKTOR4) using metaflac."""
|
|
39
|
+
command = ["metaflac", "--set-tag", f"{tag_name}={value}", str(file_path)]
|
|
40
|
+
run_external_tool(command, "metaflac")
|
|
41
|
+
|
|
36
42
|
@staticmethod
|
|
37
43
|
def set_metadata(file_path: Path, metadata: dict[str, Any]) -> None:
|
|
38
44
|
"""Set FLAC metadata using metaflac tool."""
|