|
| 1 | +import datetime |
1 | 2 | from abc import ABC |
2 | 3 | from datetime import timedelta |
3 | 4 | from typing import Any, Dict, Optional |
4 | 5 |
|
| 6 | +import isodate |
5 | 7 | import mutagen |
6 | 8 | import mutagen.mp3 |
7 | 9 | from mutagen.easyid3 import EasyID3 |
@@ -31,20 +33,29 @@ def _extract_metadata(self, file: File) -> Dict[str, Any]: |
31 | 33 | audio_file = mutagen.File(file.absolute_path) |
32 | 34 | if audio_file is None: |
33 | 35 | raise FileNotSupportedError() |
34 | | - metadata_dict = dict() |
35 | | - metadata_dict["duration"] = audio_file.info.length |
36 | | - metadata_dict["channels"] = audio_file.info.channels |
37 | | - metadata_dict["sample_rate"] = audio_file.info.sample_rate |
38 | | - metadata_dict["bitrate"] = audio_file.info.bitrate |
| 36 | + metadata_dict: Dict[str, Any] = dict() |
| 37 | + self.try_to_extract_property(metadata_dict, audio_file.info, "length") |
| 38 | + self.try_to_extract_property(metadata_dict, audio_file.info, "channels") |
| 39 | + self.try_to_extract_property(metadata_dict, audio_file.info, "sample_rate") |
| 40 | + self.try_to_extract_property(metadata_dict, audio_file.info, "bitrate") |
39 | 41 | if isinstance(audio_file, mutagen.mp3.MP3): |
40 | 42 | metadata_dict["comments"] = audio_file.get("COMM::XXX", "") |
41 | 43 | audio_file = mutagen.mp3.MP3(file.absolute_path, ID3=EasyID3) |
42 | 44 | else: |
43 | | - metadata_dict["bits_per_sample"] = audio_file.info.bits_per_sample |
| 45 | + self.try_to_extract_property( |
| 46 | + metadata_dict, audio_file.info, "bits_per_sample" |
| 47 | + ) |
44 | 48 |
|
45 | 49 | metadata_dict.update(dict(audio_file)) |
46 | 50 | return metadata_dict |
47 | 51 |
|
| 52 | + @staticmethod |
| 53 | + def try_to_extract_property( |
| 54 | + metadata_dict: Dict[str, Any], audio_info, property_name: str |
| 55 | + ): |
| 56 | + if hasattr(audio_info, property_name): |
| 57 | + metadata_dict[property_name] = getattr(audio_info, property_name) |
| 58 | + |
48 | 59 | def format_value(self, metadata_value: Any): |
49 | 60 | return metadata_value |
50 | 61 |
|
@@ -92,13 +103,13 @@ class TrackTag(MutagenTagBase): |
92 | 103 |
|
93 | 104 |
|
94 | 105 | class DurationTag(MutagenTagBase): |
95 | | - """Track duration in seconds""" |
| 106 | + """Track duration in ISO 8601 notation""" |
96 | 107 |
|
97 | | - tag_key = "duration" |
| 108 | + tag_key = "length" |
98 | 109 |
|
99 | 110 | def format_value(self, metadata_value: Any): |
100 | | - duration_in_seconds = float(super().format_value(metadata_value)) |
101 | | - return timedelta(seconds=duration_in_seconds) |
| 111 | + duration_seconds = float(super().format_value(metadata_value)) |
| 112 | + return isodate.duration_isoformat(timedelta(seconds=duration_seconds)) |
102 | 113 |
|
103 | 114 |
|
104 | 115 | class ChannelsTag(MutagenTagBase): |
|
0 commit comments