1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! M4A (MPEG-4 Audio) format compatibility module.
//!
//! This module provides a compatibility layer for code that specifically works with M4A files.
//! It re-exports all MP4 and EasyMP4 structs and functions with M4A-specific type aliases.
//!
//! # M4A vs MP4
//!
//! M4A is a naming convention for MP4 containers that are typically used for audio files.
//! Internally, this module uses the exact same implementation as the [`mp4`](crate::mp4) module.
//! The file format, structure, and metadata handling are identical.
//!
//! **File Extensions:**
//! - `.m4a` - MPEG-4 Audio (typically AAC or ALAC codec)
//! - `.m4b` - MPEG-4 Audiobook (includes chapter markers)
//! - `.m4p` - MPEG-4 Protected (DRM-protected audio)
//! - `.mp4` - Generic MPEG-4 container (may contain audio and/or video)
//!
//! # When to Use This Module
//!
//! Use this module if:
//! - Your code specifically targets M4A files
//! - You want type names that match the file extension (M4A vs MP4)
//! - You're porting code from other libraries that use "M4A" terminology
//!
//! Otherwise, the [`mp4`](crate::mp4) module works identically for all MPEG-4 audio files.
//!
//! # Examples
//!
//! ## Basic M4A File Loading
//!
//! ```no_run
//! use audex::m4a::M4A;
//! use audex::FileType;
//! use audex::Tags;
//!
//! # fn main() -> Result<(), audex::AudexError> {
//! let audio = M4A::load("song.m4a")?;
//!
//! // Access audio stream information
//! println!("Duration: {:?}", audio.info().length);
//! println!("Bitrate: {:?} kbps", audio.info().bitrate.map(|b| b / 1000));
//! println!("Codec: {}", audio.info().codec);
//!
//! // Access iTunes-style metadata
//! if let Some(ref tags) = audio.tags {
//! if let Some(title) = tags.get("©nam") {
//! println!("Title: {:?}", title);
//! }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Clearing All Metadata
//!
//! ```no_run
//! use audex::m4a;
//!
//! # fn main() -> Result<(), audex::AudexError> {
//! // Remove all iTunes metadata from an M4A file
//! m4a::clear("song.m4a")?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Simplified Metadata Access with EasyM4A
//!
//! Use `EasyM4A` for a simplified key-value interface:
//!
//! ```no_run
//! use audex::m4a::EasyM4A;
//! use audex::FileType;
//!
//! # fn main() -> Result<(), audex::AudexError> {
//! let mut tags = EasyM4A::load("song.m4a")?;
//!
//! // Read standard tags using simple field names
//! if let Some(title) = tags.get("title") {
//! println!("Title: {:?}", title);
//! }
//!
//! if let Some(artist) = tags.get("artist") {
//! println!("Artist: {:?}", artist);
//! }
//!
//! // Modify tags
//! tags.set("album", vec!["Greatest Hits".to_string()])?;
//! tags.set("date", vec!["2024".to_string()])?;
//!
//! // Save changes (saves to original file)
//! tags.save()?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Working with Cover Art
//!
//! ```no_run
//! use audex::m4a::{M4A, MP4Cover};
//! use audex::FileType;
//!
//! # fn main() -> Result<(), audex::AudexError> {
//! let mut audio = M4A::load("song.m4a")?;
//!
//! // Read existing cover art
//! if let Some(ref tags) = audio.tags {
//! if let Some(covers) = tags.covers.first() {
//! println!("Cover art: {} bytes, format: {:?}",
//! covers.data.len(), covers.imageformat);
//! }
//! }
//!
//! // Add new cover art
//! let cover_data = std::fs::read("album_art.jpg")?;
//! let cover = MP4Cover::new_jpeg(cover_data);
//!
//! if let Some(ref mut tags) = audio.tags {
//! tags.covers.clear();
//! tags.covers.push(cover);
//! }
//!
//! // Save changes to the original file
//! audio.save()?;
//! # Ok(())
//! # }
//! ```
//!
//! # Re-exported Types
//!
//! All types from the [`mp4`](crate::mp4) and [`easymp4`](crate::easymp4) modules are
//! re-exported here. Key aliases:
//!
//! - `M4A` = `MP4`
//! - `EasyM4A` = `EasyMP4`
//! - `EasyM4ATags` = `EasyMP4Tags`
//!
//! All other types (errors, atoms, chapters, etc.) are identical to the MP4 module.
pub use crate;
pub use crateclear_async;
pub use crate;
/// Alias for MP4 (compatibility name)
pub use crateMP4 as M4A;
/// Alias for EasyMP4 (compatibility name)
pub use crateEasyMP4 as EasyM4A;
/// Alias for EasyMP4Tags (compatibility name)
pub use crateEasyMP4Tags as EasyM4ATags;