Rust MP4元数据处理库mp4ameta_proc的使用:高效解析和操作MP4音频文件元数据
Rust MP4元数据处理库mp4ameta_proc的使用:高效解析和操作MP4音频文件元数据
安装
在项目目录中运行以下Cargo命令:
cargo add mp4ameta_proc
或者在Cargo.toml中添加以下行:
mp4ameta_proc = "0.6.0"
使用示例
以下是使用mp4ameta_proc库解析和操作MP4音频文件元数据的完整示例:
use mp4ameta_proc::{Tag, Data};
use std::fs::File;
use std::io::BufReader;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 打开MP4文件
let file = File::open("audio.mp4")?;
let mut reader = BufReader::new(file);
// 读取元数据标签
let tag = Tag::read_from(&mut reader)?;
// 打印所有元数据
println!("MP4文件元数据:");
for data in tag.data() {
match data {
Data::Album(album) => println!("专辑: {}", album),
Data::Artist(artist) => println!("艺术家: {}", artist),
Data::Title(title) => println!("标题: {}", title),
Data::Genre(genre) => println!("流派: {}", genre),
Data::TrackNumber(track) => println!("音轨号: {}", track),
Data::DiscNumber(disc) => println!("光盘号: {}", disc),
Data::Year(year) => println!("年份: {}", year),
Data::Comment(comment) => println!("注释: {}", comment),
Data::CoverArt { data, format } => {
println!("封面艺术: {}格式, {}字节", format, data.len())
}
_ => {} // 其他元数据类型
}
}
// 修改元数据
let mut tag = tag;
tag.set_title("新标题");
tag.set_artist("新艺术家");
tag.set_album("新专辑");
// 将修改后的元数据写回文件
let file = File::create("audio_modified.mp4")?;
let mut writer = BufReader::new(file);
tag.write_to(&mut writer)?;
Ok(())
}
完整示例代码
以下是一个更完整的示例,展示了如何批量处理MP4文件的元数据:
use mp4ameta_proc::{Tag, Data};
use std::fs::{self, File};
use std::io::{BufReader, BufWriter};
use std::path::Path;
// 处理单个MP4文件的元数据
fn process_mp4_metadata(file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
// 打开文件
let file = File::open(file_path)?;
let mut reader = BufReader::new(file);
// 读取元数据
let tag = Tag::read_from(&mut reader)?;
// 打印文件基本信息
println!("\n处理文件: {}", file_path);
println!("包含的元数据类型:");
// 统计各类元数据的数量
let mut metadata_count = 0;
for data in tag.data() {
match data {
Data::Album(_) => println!("- 专辑信息"),
Data::Artist(_) => println!("- 艺术家信息"),
Data::Title(_) => println!("- 标题信息"),
Data::Genre(_) => println!("- 流派信息"),
Data::TrackNumber(_) => println!("- 音轨号"),
Data::DiscNumber(_) => println!("- 光盘号"),
Data::Year(_) => println!("- 年份信息"),
Data::Comment(_) => println!("- 注释信息"),
Data::CoverArt { .. } => println!("- 封面图片"),
_ => println!("- 其他元数据类型"),
}
metadata_count += 1;
}
println!("共找到 {} 个元数据项", metadata_count);
// 创建修改后的文件
let modified_path = Path::new(file_path)
.with_file_name("modified_audio.mp4");
// 修改并写入元数据
let mut tag = tag;
tag.set_title("修改后的标题");
tag.set_artist("修改后的艺术家");
let output_file = File::create(modified_path)?;
let mut writer = BufWriter::new(output_file);
tag.write_to(&mut writer)?;
println!("已创建修改后的文件: {:?}", modified_path);
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 示例:处理当前目录下的MP4文件
let dir_entries = fs::read_dir(".")?;
for entry in dir_entries {
let entry = entry?;
let path = entry.path();
if path.extension().map_or(false, |ext| ext == "mp4") {
if let Some(file_name) = path.to_str() {
process_mp4_metadata(file_name)?;
}
}
}
Ok(())
}
功能说明
- 读取MP4元数据:
Tag::read_from
方法可以从MP4文件中读取所有元数据 - 访问元数据:通过
tag.data()
可以遍历所有元数据项 - 修改元数据:提供
set_*
系列方法来修改各种元数据 - 写入元数据:
write_to
方法将修改后的元数据写回文件
支持的元数据类型
- 标题(title)
- 艺术家(artist)
- 专辑(album)
- 流派(genre)
- 音轨号(track number)
- 光盘号(disc number)
- 年份(year)
- 注释(comment)
- 封面艺术(cover art)
许可证
该库采用MIT或Apache-2.0双重许可证。
1 回复
Rust MP4元数据处理库mp4ameta_proc的使用指南
mp4ameta_proc
是一个用于高效解析和操作MP4音频文件元数据的Rust库。它专注于处理MP4容器格式(如.m4a文件)中的元数据信息,提供了一套简洁的API来读取和修改这些数据。
安装
在Cargo.toml
中添加依赖:
[dependencies]
mp4ameta_proc = "0.1"
基本使用方法
读取MP4文件元数据
use mp4ameta_proc::{Tag, Data};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 从文件加载元数据
let tag = Tag::read_from_path("audio.m4a")?;
// 获取常用元数据字段
if let Some(title) = tag.title() {
println!("标题: {}", title);
}
if let Some(artist) = tag.artist() {
println!("艺术家: {}", artist);
}
if let Some(album) = tag.album() {
println!("专辑: {}", album);
}
Ok(())
}
写入元数据
use mp4ameta_proc::{Tag, Data};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建新标签或加载现有标签
let mut tag = Tag::read_from_path("audio.m4a").unwrap_or_default();
// 设置元数据字段
tag.set_title("新歌曲名称");
tag.set_artist("艺术家名称");
tag.set_album("专辑名称");
tag.set_track_number(1);
tag.set_total_tracks(10);
// 保存回文件
tag.write_to_path("audio.m4a")?;
Ok(())
}
高级功能
处理封面艺术
use mp4ameta_proc::{Tag, Data, ImgFmt};
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut tag = Tag::read_from_path("audio.m4a")?;
// 读取封面
if let Some(artwork) = tag.artwork() {
fs::write("cover.jpg", artwork.data)?;
println!("封面格式: {:?}", artwork.format);
}
// 添加新封面
let cover_data = fs::read("new_cover.jpg")?;
tag.set_artwork(ImgFmt::Jpeg, cover_data);
tag.write_to_path("audio.m4a")?;
Ok(())
}
处理自定义元数据
use mp4ameta_proc::{Tag, Data, Freeform};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut tag = Tag::read_from_path("audio.m4a")?;
// 添加自定义元数据
tag.insert(Freeform::new("com.myapp.custom", "自定义值").into());
// 读取自定义元数据
if let Some(custom) = tag.get("com.myapp.custom") {
println!("自定义字段值: {}", custom);
}
tag.write_to_path("audio.m4a")?;
Ok(())
}
性能提示
mp4ameta_proc
在设计上考虑了性能:
- 它只解析和修改元数据部分,不会处理音频数据本身
- 提供了流式API,可以高效处理大文件
- 修改元数据时会尽量保留文件原有结构,减少重写量
错误处理
大多数操作返回Result
类型,建议使用?
操作符或适当处理错误:
match Tag::read_from_path("audio.m4a") {
Ok(tag) => {
// 处理标签
},
Err(e) => eprintln!("读取元数据失败: {}", e),
}
完整示例代码
下面是一个综合使用mp4ameta_proc库的完整示例:
use mp4ameta_proc::{Tag, Data, ImgFmt, Freeform};
use std::fs;
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 读取MP4文件元数据
let file_path = "song.m4a";
let mut tag = match Tag::read_from_path(file_path) {
Ok(t) => t,
Err(_) => {
println!("文件不存在或无法读取,创建新标签");
Tag::default()
}
};
// 2. 打印现有元数据
println!("=== 当前元数据 ===");
println!("标题: {:?}", tag.title());
println!("艺术家: {:?}", tag.artist());
println!("专辑: {:?}", tag.album());
println!("音轨号: {:?}", tag.track_number());
println!("总音轨数: {:?}", tag.total_tracks());
// 3. 更新元数据
println!("\n=== 更新元数据 ===");
tag.set_title("Rust编程之歌");
tag.set_artist("Rust开发者");
tag.set_album("Rust音频合集");
tag.set_track_number(3);
tag.set_total_tracks(12);
// 4. 处理封面图片
if Path::new("cover.jpg").exists() {
println!("\n=== 处理封面 ===");
let cover_data = fs::read("cover.jpg")?;
tag.set_artwork(ImgFmt::Jpeg, cover_data);
println!("已添加封面图片");
}
// 5. 添加自定义元数据
println!("\n=== 添加自定义数据 ===");
tag.insert(Freeform::new("com.example.rating", "5").into());
if let Some(rating) = tag.get("com.example.rating") {
println!("自定义评分: {}", rating);
}
// 6. 保存修改
tag.write_to_path(file_path)?;
println!("\n元数据已保存到文件");
Ok(())
}
这个完整示例展示了:
- 读取现有MP4文件元数据或创建新标签
- 打印当前元数据信息
- 更新基本元数据字段
- 添加或更新封面图片
- 处理自定义元数据字段
- 将修改保存回文件
使用前请确保:
- 已添加mp4ameta_proc依赖
- 有可操作的.m4a文件
- 如需处理封面,准备cover.jpg文件