4

I'm trying to make a tool to edit and embed chapter markings in mp3 files (for podcasting) through this spec.

All of the libraries I've found so far do not support the CHAP or CTOC frames, nor can I figure out a way to make them work with custom frames. NTagLite seems to be my favorite so far, but I am having trouble building the source on VS2017 to try splicing in my own methods for different frame types, and at the end of the day I'm not a very advanced programmer so using a ByteStream manually is a bit over my head.

Does anyone know a way to achieve this? Anyone with experience here? Am I just missing the calls in these libraries and that functionality is all already there?

iehrlich
  • 3,572
  • 4
  • 34
  • 43
Snivets
  • 43
  • 4

2 Answers2

2

The latest version of Audio Tools Library for .NET (https://github.com/Zeugma440/atldotnet) supports ID3v2 chapters (CTOC / CHAP frames) reading and writing.

Sample code from the wiki below :

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 + ")");
}
Paul W
  • 149
  • 1
  • 6
  • It worked -only- when, on a fresh mp3 file, i added the theTag.Title. Not adding it resulted in chapters not being added! – Kendar Jun 14 '18 at 11:01
0

If you can't find a library that will do this for you, you might be able to do it yourself. First, define some object which encapsulates the ID3 tag's chapter-related metadata/frames:

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>();
}

Then write some method (something like ChapterFrame.ToByteArray()):

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

... that takes each of the ChapterFrame's fields and flattens them out into a serialized array of bytes, conformant with the ID3 v2.3/2.4 Chapter Frame Addendum standards:

from "ID3v2 Chapter Frame Addendum", C. Newell, 2 December 2005

Now that you've got a new frame, you can scan through the ID3 tag to figure out where to insert the new frame.

Please note that I'm definitely not an expert here - this is just a guess.

alex
  • 6,818
  • 9
  • 52
  • 103