/// <summary> /// タグにフレームを追加します. /// </summary> /// <param name="reader"></param> /// <param name="name"></param> /// <returns></returns> protected override async Task <int> AddFrame(string name, ID3Reader reader) { // イベントタイムコードフレーム if (name == "ETCO") { // とりあえずTimeUnitを決め打ちにする。 var tag = new ID3v23EventTimeCodeFrame(name, TimeUnit.Milliseconds); await tag.Initialize(reader); return(frames.Add(tag)); } // テキストフレーム if (name[0] == 'T') { if (name != "TXXX") { var tag = new ID3v23StringFrame(name, true); await tag.Initialize(reader); return(frames.Add(tag)); } else { return(0); } } else { var tag = new ID3v23BinaryFrame(name); await tag.Initialize(reader); return(frames.Add(tag)); } }
//#endregion // 05/16/2007 by aldente #region *[static]ファイルにID3v2タグが存在するか否か(Exists) public static async Task <bool> Exists(string filename) { using (ID3Reader reader = new ID3Reader(filename)) { return(await Exists(reader)); } }
protected override async Task ReadBody(ID3Reader reader, int size) { InitializeTimeUnits(); this.TimeStampUnit = (TimeUnit)event_time_units[await reader.ReadByte()]; await event_time_collection.ReadBody(reader, size - 1); }
// 05/17/2007 by aldente #region *タグオブジェクトを生成(Generate) /// <summary> /// ヘッダのバージョン番号を読み取り,タグオブジェクトを生成します. /// </summary> /// <param name="reader"></param> /// <param name="onlyHeader"></param> /// <returns></returns> private static async Task <ID3v2Tag> Generate(ID3Reader reader, bool onlyHeader) { // readerは"ID3"まで読み取ったものとする. byte[] version = new byte[2]; await reader.ReadAsync(version, 0, 2); switch (version[0]) { case 0x02: { var tag = new ID3v22Tag(); await tag.Initialize(reader, onlyHeader); return(tag); } case 0x03: { var tag = new ID3v23Tag(); await tag.Initialize(reader, onlyHeader); return(tag); } case 0x04: throw new ApplicationException("残念ながら未対応ですm(_ _)m"); default: throw new ApplicationException("見たことないバージョンでチュね~"); } }
// 05/16/2007 by aldente #region *[static]ファイルにID3v2タグが存在するか否か(Exists) /// <summary> /// ファイルにID3v2タグが存在するか否かをチェックします. /// </summary> /// <param name="reader"></param> /// <returns></returns> protected static async Task <bool> Exists(ID3Reader reader) { // 先頭3バイトを読み込む. reader.Seek(0, SeekOrigin.Begin); byte[] buf = await reader.ReadBytes(3); return(Encoding.ASCII.GetString(buf) == "ID3"); }
//public ID3v22Frame(string name, ID3Reader reader) // : base(name) //{ // // サイズ読み込み // int size = reader.Read3ByteInteger(); // // フラグ読み込みは,フラグがないので割愛. // // 本体読み込み // ReadBody(reader, size); //} #endregion public async Task Initialize(ID3Reader reader) { // サイズ読み込み int size = await reader.Read3ByteInteger(); // フラグ読み込みは,フラグがないので割愛. // 本体読み込み await ReadBody(reader, size); }
protected async Task ReadFrames(ID3Reader reader) { while (reader.Position < size + base_header_size) { if (!await ReadFrame(reader)) { break; } } }
// 05/16/2007 by aldente : 未対応バージョンにはApplicationExceptionを発生するように変更. #region *[static]ファイルからID3v2タグを読み込む(ReadFile) /// <summary> /// 指定したファイルのID3v2タグを読み込み,ID3v2Tagオブジェクトを返します. /// ID3v2タグが見つからなければnullを返します. /// </summary> /// <param name="filename">ID3v2を読み込むファイルの名前.</param> /// <returns>ID3v2Tagオブジェクト.タグが見つからなければnull.</returns> public static async Task <ID3v2Tag> ReadFile(string filename) { using (ID3Reader reader = new ID3Reader(filename)) { if (!await Exists(reader)) { return(null); } return(await Generate(reader, false)); } }
// 09/17/2014 by aldentea #region *[static]ファイルからタグ全体のサイズを取得(GetSize) public static async Task <int> GetSize(string filename) { using (ID3Reader reader = new ID3Reader(filename)) { if (!await Exists(reader)) { return(0); } return((await Generate(reader, true)).size); } }
/* #region *コンストラクタ(ID3v23Frame:2/2) * public ID3v23Frame(string name, ID3Reader reader) * : base(name) * { * // サイズ読み込み→エンディアン変換 * int size = IPAddress.NetworkToHostOrder(reader.ReadInt32()); * // フラグ読み込み * s_flags = new BitArray(reader.ReadBytes(1)); * f_flags = new BitArray(reader.ReadBytes(1)); * // 本体読み込み * ReadBody(reader, size); * } #endregion */ // ↑のコンストラクタを廃止して、Initializeメソッドにする。 public async Task Initialize(ID3Reader reader) { // サイズ読み込み→エンディアン変換 int size = await reader.ReadInt32(true); // フラグ読み込み s_flags = new BitArray(await reader.ReadBytes(1)); f_flags = new BitArray(await reader.ReadBytes(1)); // 本体読み込み await ReadBody(reader, size); }
/* * // 05/17/2007 by aldente : only_header引数を追加. #region *コンストラクタ(ID3v2Tag) * /// <summary> * /// * /// </summary> * /// <param name="reader"></param> * /// <param name="only_header"></param> * protected ID3v2Tag(ID3Reader reader, bool only_header, int frame_name_size) * { * this.frame_name_size = frame_name_size; * ReadHeader(reader); * if (!only_header) * { * ReadFrames(reader); * } * } */ // ↑このコンストラクタを廃止して、Initializeメソッドにする? protected async Task Initialize(ID3Reader reader, bool onlyHeader) { // これはコンストラクタで行う。 //this.frame_name_size = frameNameSize; await ReadHeader(reader); if (!onlyHeader) { await ReadFrames(reader); } }
//public ID3v23Tag(ID3Reader reader, bool only_header) // : base(reader, only_header, 4) //{ // id_Title = "TIT2"; // id_Artist = "TPE1"; //} #endregion // 05/16/2007 by aldente #region *[override]ヘッダの後半を読み込み(ReadHeader) protected override async Task ReadHeader(ID3Reader reader) { await base.ReadHeader(reader); if (HaveExtendedHeader) { // ※拡張ヘッダを読み込む. int size = await reader.ReadInt32(true); extended_header = await reader.ReadBytes(size); } }
// 02/04/2013 by aldentea : 一時ファイルの名前をAPIから取得。 // 05/17/2007 by aldente #region *ファイルに書き込む(WriteTo) /// <summary> /// 指定したファイルにタグを書き込みます. /// 既存のタグは上書きされます. /// </summary> /// <param name="dstFilename">書き込み先のファイル名.</param> public async Task WriteTo(string dstFilename) { if (!File.Exists(dstFilename)) { // どうしてくれよう? } bool v1_exists = await ID3v1Tag.Exists(dstFilename); //string tempFilename = "namunamu.mp3"; string tempFilename = Path.GetTempFileName(); using (var reader = new ID3Reader(dstFilename)) { bool exists = await Exists(reader); int old_tag_size = exists ? (await Generate(reader, true)).GetTotalSize() : 0; // 11/10/2008 by aldente // FileModeをCreateNewからCreateに変更. using (var writer = new FileStream(tempFilename, FileMode.Create, FileAccess.Write)) { ID3v1Tag v1Tag = new ID3v1Tag(); // タグを書き込む. await writer.WriteAsync(this.GetBytes(this.char_code, 0x100)); // 本体を書き込む. reader.Seek(old_tag_size, SeekOrigin.Begin); if (v1_exists) { var contents = await reader.ReadBytes((int)reader.Length - old_tag_size - 128); await writer.WriteAsync(contents); await v1Tag.Initialize(reader, false); } else { var contents = await reader.ReadBytes((int)reader.Length - old_tag_size); await writer.WriteAsync(contents); } // ID3v1タグを書き込む. v1Tag.Title = this.Title; v1Tag.Artist = this.Artist; byte[] buf = v1Tag.GetBytes(); await writer.WriteAsync(buf, 0, buf.Length); } } File.Delete(dstFilename); File.Move(tempFilename, dstFilename); }
protected async Task <bool> ReadFrame(ID3Reader reader) { // フレーム名を読み込む. string name = Encoding.ASCII.GetString(await reader.ReadBytes(frame_name_size)); //string name = Encoding.ASCII.GetString(reader.ReadBytes((int)this.GetType().GetField("frame_name_size", System.Reflection.BindingFlags.FlattenHierarchy).GetValue(null))); // "The frame ID made out of the characters capital A-Z and 0-9." // なんだけど,半角空白を使う人がいるようなので,一応それにも対応しておく. string format = string.Format("[A-Z0-9 ]{{{0}}}", frame_name_size); if (!Regex.IsMatch(name, format)) { // おそらくパディング領域に踏み込んだ場合. return(false); } await AddFrame(name, reader); return(true); }
protected abstract Task ReadBody(ID3Reader reader, int size);
//public ID3v23BinaryFrame(string name, ID3Reader reader) // : base(name, reader) //{ //} #endregion #region *[override]フレームの本体を読み込み(ReadBody) protected override async Task ReadBody(ID3Reader reader, int size) { content = await reader.ReadBytes(size); }
protected abstract Task <int> AddFrame(string name, ID3Reader reader);
// 05/16/2007 by aldente : virtualに変更(拡張タグを読み込むため). #region *[virtual]ヘッダの後半を読み込み(ReadHeader) protected virtual async Task ReadHeader(ID3Reader reader) { flags = new BitArray(await reader.ReadBytes(1)); size = await reader.Read4ByteSynchsafeInteger(); }
//public ID3v23StringFrame(string name, ID3Reader reader, bool use_sjis) // : base(name, reader) //{ //} #endregion #region *[override]フレームの本体を読み込み(ReadBody) protected override async Task ReadBody(ID3Reader reader, int size) { encoder = new StringFrameEncoder(use_sjis); value = encoder.Decode(await reader.ReadBytes(size)); }