2021-04-23 22:12:55 +00:00
|
|
|
|
//! [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/Serial-ATA/lofty-rs/CI?style=for-the-badge&logo=github)](https://github.com/Serial-ATA/lofty-rs/actions/workflows/ci.yml)
|
|
|
|
|
//! [![Downloads](https://img.shields.io/crates/d/lofty?style=for-the-badge&logo=rust)](https://crates.io/crates/lofty)
|
|
|
|
|
//! [![Version](https://img.shields.io/crates/v/lofty?style=for-the-badge&logo=rust)](https://crates.io/crates/lofty)
|
2020-10-27 02:08:05 +00:00
|
|
|
|
//!
|
2021-04-04 03:32:54 +00:00
|
|
|
|
//! This is a fork of [Audiotags](https://github.com/TianyiShi2001/audiotags), adding support for more file types and (optionally) duration.
|
|
|
|
|
//!
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! Parse, convert, and write metadata to audio files of different file types.
|
2020-10-27 02:08:05 +00:00
|
|
|
|
//!
|
2020-10-27 14:38:31 +00:00
|
|
|
|
//! This crate aims to provide a unified trait for parsers and writers of different audio file formats.
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! Without this crate, you would otherwise need to learn the different APIs in **id3**, **mp4ameta**, etc.
|
|
|
|
|
//! in order to parse metadata in different file formats.
|
2020-10-27 02:08:05 +00:00
|
|
|
|
//!
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! # Supported Formats
|
|
|
|
|
//!
|
2021-05-16 05:32:25 +00:00
|
|
|
|
//! | File Format | Extensions | Read | Write | Duration | Metadata Format(s) |
|
|
|
|
|
//! |-------------|-------------------------------------------|------|-------|----------|----------------------|
|
|
|
|
|
//! | Ape | `ape` |**X** |**X** | | `APEv2` |
|
|
|
|
|
//! | AIFF | `aiff`, `aif` |**X** |**X** | | `ID3v2` |
|
|
|
|
|
//! | FLAC | `flac` |**X** |**X** | | `Vorbis Comments` |
|
|
|
|
|
//! | MP3 | `mp3` |**X** |**X** |**X** | `ID3v2` |
|
|
|
|
|
//! | MP4 | `mp4`, `m4a`, `m4b`, `m4p`, `m4v`, `isom` |**X** |**X** | | `Vorbis Comments` |
|
|
|
|
|
//! | Opus | `opus` |**X** |**X** | | `Vorbis Comments` |
|
|
|
|
|
//! | Ogg | `ogg`, `oga` |**X** |**X** | | `Vorbis Comments` |
|
|
|
|
|
//! | WAV | `wav`, `wave` |**X** |**X** | | `RIFF INFO`, `ID3v2` |
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//!
|
|
|
|
|
//! # Examples
|
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! ## Guessing from extension
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! ```
|
2021-04-22 22:01:09 +00:00
|
|
|
|
//! use lofty::{Tag, TagType};
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//!
|
2021-04-22 22:01:09 +00:00
|
|
|
|
//! let mut tag = Tag::new().read_from_path("tests/assets/a.mp3").unwrap();
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! tag.set_title("Foo");
|
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! assert_eq!(tag.title(), Some("Foo"));
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! ## Guessing from file signature
|
|
|
|
|
//! ```
|
|
|
|
|
//! use lofty::Tag;
|
|
|
|
|
//!
|
2021-04-22 22:01:09 +00:00
|
|
|
|
//! let mut tag_sig = Tag::new().read_from_path_signature("tests/assets/a.wav").unwrap();
|
|
|
|
|
//! tag_sig.set_artist("Foo artist");
|
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! assert_eq!(tag_sig.artist_str(), Some("Foo artist"));
|
|
|
|
|
//! ```
|
2020-10-27 02:08:05 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! ## Specifying a TagType
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! ```
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! use lofty::{Tag, TagType};
|
2020-10-27 02:08:05 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! let mut tag = Tag::new().with_tag_type(TagType::Mp4).read_from_path("tests/assets/a.m4a").unwrap();
|
|
|
|
|
//! tag.set_album_title("Foo album title");
|
2021-04-03 17:03:40 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! assert_eq!(tag.album_title(), Some("Foo album title"));
|
|
|
|
|
//! ```
|
2021-04-03 17:03:40 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! ## Converting between TagTypes
|
|
|
|
|
//! ```
|
|
|
|
|
//! use lofty::{Tag, TagType};
|
2021-04-03 17:03:40 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! let mut tag = Tag::new().read_from_path("tests/assets/a.mp3").unwrap();
|
|
|
|
|
//! tag.set_title("Foo");
|
2021-04-03 17:03:40 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! // You can convert the tag type and save the metadata to another file.
|
|
|
|
|
//! tag.to_dyn_tag(TagType::Mp4).write_to_path("tests/assets/a.m4a");
|
|
|
|
|
//! assert_eq!(tag.title(), Some("Foo"));
|
|
|
|
|
//! ```
|
|
|
|
|
//!
|
|
|
|
|
//! # Features
|
2021-04-03 17:03:40 +00:00
|
|
|
|
//!
|
2021-05-19 19:25:09 +00:00
|
|
|
|
//! ## Applies to all
|
|
|
|
|
//! * `full` - Combines both `all_tags` and `duration` (*default*)
|
|
|
|
|
//! * `all_tags` - Enables all formats
|
|
|
|
|
//! * `duration` - Provides the `duration` field in each tag
|
|
|
|
|
//!
|
|
|
|
|
//! ## Individual formats
|
|
|
|
|
//! These features are available if you have a specific usecase, or just don't want certain formats.
|
|
|
|
|
//!
|
|
|
|
|
//! All format features a prefixed with `format-`
|
|
|
|
|
//! * `format-ape`
|
|
|
|
|
//! * `format-flac`
|
|
|
|
|
//! * `format-id3`
|
|
|
|
|
//! * `format-mp4`
|
|
|
|
|
//! * `format-opus`
|
|
|
|
|
//! * `format-vorbis`
|
|
|
|
|
//! * `format-riff`
|
2021-04-07 00:57:30 +00:00
|
|
|
|
//!
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! ## Performance
|
|
|
|
|
//!
|
|
|
|
|
//! Using lofty incurs a little overhead due to vtables if you want to guess the metadata format (from file extension).
|
|
|
|
|
//! Apart from this, the performance is almost the same as directly calling the function provided from those ‘specialized’ crates.
|
2020-10-27 02:08:05 +00:00
|
|
|
|
//!
|
2021-04-03 15:44:33 +00:00
|
|
|
|
//! No copies will be made if you only need to read and write metadata of one format. If you want to convert between tags, copying is
|
|
|
|
|
//! unavoidable, no matter if you use lofty or use getters and setters provided by specialized libraries. Lofty is not making additional
|
|
|
|
|
//! unnecessary copies.
|
2020-10-25 14:58:50 +00:00
|
|
|
|
|
2021-04-03 00:47:44 +00:00
|
|
|
|
#![warn(clippy::pedantic)]
|
2021-05-16 04:39:19 +00:00
|
|
|
|
#![warn(missing_docs)]
|
2021-04-03 00:47:44 +00:00
|
|
|
|
#![allow(
|
|
|
|
|
clippy::too_many_lines,
|
|
|
|
|
clippy::cast_precision_loss,
|
|
|
|
|
clippy::cast_sign_loss,
|
|
|
|
|
clippy::cast_possible_wrap,
|
2021-05-17 01:12:38 +00:00
|
|
|
|
clippy::cast_possible_truncation,
|
2021-04-14 16:17:38 +00:00
|
|
|
|
clippy::module_name_repetitions,
|
|
|
|
|
clippy::must_use_candidate,
|
|
|
|
|
clippy::doc_markdown,
|
2021-04-15 15:53:10 +00:00
|
|
|
|
clippy::let_underscore_drop,
|
|
|
|
|
clippy::match_wildcard_for_single_variants
|
2021-04-03 00:47:44 +00:00
|
|
|
|
)]
|
|
|
|
|
|
2021-04-03 16:19:21 +00:00
|
|
|
|
mod types;
|
2021-04-03 16:29:51 +00:00
|
|
|
|
pub use crate::types::{
|
|
|
|
|
album::Album,
|
|
|
|
|
anytag::AnyTag,
|
2021-05-16 03:43:31 +00:00
|
|
|
|
picture::{MimeType, Picture, PictureType},
|
2021-04-03 16:29:51 +00:00
|
|
|
|
};
|
2020-10-26 02:14:28 +00:00
|
|
|
|
|
2021-04-03 16:19:21 +00:00
|
|
|
|
mod tag;
|
2021-04-23 02:50:13 +00:00
|
|
|
|
pub use crate::tag::{Id3Format, Tag, TagType, VorbisFormat};
|
2021-04-03 00:47:44 +00:00
|
|
|
|
|
2021-04-03 16:19:21 +00:00
|
|
|
|
mod error;
|
|
|
|
|
pub use crate::error::{Error, Result};
|
2020-10-29 18:01:21 +00:00
|
|
|
|
|
2021-04-03 16:19:21 +00:00
|
|
|
|
mod components;
|
2021-04-14 03:29:13 +00:00
|
|
|
|
pub use crate::components::tags::*;
|
2020-10-29 18:01:21 +00:00
|
|
|
|
|
2021-04-03 16:19:21 +00:00
|
|
|
|
mod traits;
|
|
|
|
|
pub use crate::traits::{AudioTag, AudioTagEdit, AudioTagWrite, ToAny, ToAnyTag};
|