如何在 C# 的 mp3 文件中嵌入章节元数据?

Posted

技术标签:

【中文标题】如何在 C# 的 mp3 文件中嵌入章节元数据?【英文标题】:How do I embed chapter metadata in mp3 files in C#? 【发布时间】:2017-04-24 13:46:56 【问题描述】:

我正在尝试制作一个工具来通过this 规范在 mp3 文件(用于播客)中编辑和嵌入章节标记。

到目前为止,我发现的所有库都不支持 CHAP 或 CTOC 框架,我也想不出办法让它们与自定义框架一起工作。到目前为止,NTagLite 似乎是我最喜欢的,但是我在 VS2017 上构建源代码以尝试在我自己的方法中拼接不同的帧类型时遇到了麻烦,归根结底,我不是一个非常高级的程序员,所以使用 ByteStream手动有点过头了。

有谁知道实现这一目标的方法吗?这里有经验的人吗?我只是错过了这些库中的调用,而这些功能都已经存在了吗?

【问题讨论】:

【参考方案1】:

最新版本的 .NET 音频工具库 (https://github.com/Zeugma440/atldotnet) 支持 ID3v2 章节(CTOC / CHAP 帧)读写。

来自以下 wiki 的示例代码:

using System;
using ATL.AudioData;
using System.Collections.Generic;

AudioDataManager theFile = new AudioDataManager(AudioData.AudioDataIOFactory.GetInstance().GetDataReader(<fileLocation>));

Dictionary<uint, ChapterInfo> expectedChaps = new Dictionary<uint, ChapterInfo>();
TagData theTag = new TagData();
theTag.Chapters = new List<ChapterInfo>();
expectedChaps.Clear();

ChapterInfo ch = new ChapterInfo();
ch.StartTime = 123;
ch.StartOffset = 456;
ch.EndTime = 789;
ch.EndOffset = 101112;
ch.UniqueID = "";
ch.Title = "aaa";
ch.Subtitle = "bbb";
ch.Url = "ccc\0ddd";

theTag.Chapters.Add(ch);
expectedChaps.Add(ch.StartTime, ch);

ch = new ChapterInfo();
ch.StartTime = 1230;
ch.StartOffset = 4560;
ch.EndTime = 7890;
ch.EndOffset = 1011120;
ch.UniqueID = "002";
ch.Title = "aaa0";
ch.Subtitle = "bbb0";
ch.Url = "ccc\0ddd0";

theTag.Chapters.Add(ch);
expectedChaps.Add(ch.StartTime, ch);

// Persists the chapters
theFile.UpdateTagInFile(theTag, MetaDataIOFactory.TAG_ID3V2);

// Reads them
theFile.ReadFromFile(null, true);

foreach (ChapterInfo chap in theFile.ID3v2.Chapters)

    System.Console.WriteLine(chap.Title + "(" + chap.StartTime + ")");

【讨论】:

只有在我在新的 mp3 文件上添加了 theTag.Title 时才起作用。不添加会导致章节不被添加!【参考方案2】:

如果您找不到可以为您执行此操作的库,您也许可以自己完成。首先,定义一些封装 ID3 标签的章节相关元数据/帧的对象:

public class ChapterFrame : Frame

    private Header Header  get; set; 
    private string ElementId  get; set; 
    private TimeSpan StartTime  get; set; 
    private TimeSpan EndTime  get; set; 
    private TimeSpan StartOffset  get; set; 
    private TimeSpan EndOffset  get; set; 
    private List<ChapterFrame> Subframes = new List<ChapterFrame>();

然后写一些方法(比如ChapterFrame.ToByteArray()):

public byte[] ToByteArray(ChapterFrame frame) 
    return new byte[]; 

...获取ChapterFrame 的每个字段并将它们展平为序列化的字节数组,符合 ID3 v2.3/2.4 章节框架附录标准:

现在您已经有了一个新框架,您可以扫描 ID3 标签以找出插入新框架的位置。

请注意,我绝对不是这里的专家 - 这只是猜测。

【讨论】:

以上是关于如何在 C# 的 mp3 文件中嵌入章节元数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中从 MP3 文件中读取元数据属性?

如何从 .mp3 文件中获取元数据并使用 FFmpeg 将其作为文本放入视频中?

如何更改 mp3 中的元数据 [关闭]

mp3 文件元数据中的自定义键

使用 html5 文件系统 api 获取本地 mp3 文件的元数据

使用 ffmpeg 将 .flac 转换为 .mp3,保留所有元数据