Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 32 additions & 22 deletions src/id3v2/frames/commentsFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,6 @@ export default class CommentsFrame extends Frame {
super(frameHeader);
}

/**
* Constructs and initializes a new CommentsFrame from a description
* @param description Description of the new frame
* @param language Optional, ISO-639-2 language code for the new frame
* @param encoding Optional, text encoding to use when rendering the new frame
*/
public static fromDescription(
description: string,
language?: string,
encoding: StringType = Id3v2Settings.defaultEncoding
): CommentsFrame {
const frame = new CommentsFrame(new Id3v2FrameHeader(FrameIdentifiers.COMM));
frame.textEncoding = encoding;
frame._language = language;
frame._description = description;

return frame;
}

/**
* Constructs and initializes a new instance by parsing the fields from the field bytes.
* @param header Header of the frame
Expand Down Expand Up @@ -85,6 +66,31 @@ export default class CommentsFrame extends Frame {
return frame;
}

/**
* Constructs and initializes a new CommentsFrame from a description
* @param description Optional, description of the comment being created. If omitted, defaults
* to `""`.
* @param text Optional, text of the comment being created. If omitted, defaults to `""`.
* @param language Optional, ISO-639-2 language code for the new frame. If omitted, defaults to
* `XXX`. @TODO: Should this default to unk?
* @param encoding Optional, text encoding to use when rendering the new frame. If omitted,
* defaults to {@link Id3v2Settings.defaultEncoding}.
*/
public static fromFields(
description?: string,
text?: string,
language?: string,
encoding?: StringType
): CommentsFrame {
const frame = new CommentsFrame(new Id3v2FrameHeader(FrameIdentifiers.COMM));
frame._description = description ?? "";
frame._language = language ?? "XXX";
frame._text = text ?? "";
frame._textEncoding = encoding ?? Id3v2Settings.defaultEncoding;

return frame;
}

// #endregion

// #region Public Properties
Expand Down Expand Up @@ -145,9 +151,13 @@ export default class CommentsFrame extends Frame {

/** @inheritDoc */
public clone(): Frame {
const frame = CommentsFrame.fromDescription(this._description, this._language, this._textEncoding);
frame._text = this._text;
return frame;
const clone = new CommentsFrame(new Id3v2FrameHeader(FrameIdentifiers.COMM));
clone._description = this._description;
clone._language = this._language;
clone._text = this._text;
clone._textEncoding = this._textEncoding;

return clone;
}

/**
Expand Down
33 changes: 15 additions & 18 deletions src/id3v2/frames/eventTimeCodeFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,6 @@ export class EventTimeCodeFrame extends Frame {
super(header);
}

/**
* Constructs and initializes a new instance without contents
*/
public static fromEmpty(): EventTimeCodeFrame {
// @TODO: Should we be mucking around with the flags like this?
const frame = new EventTimeCodeFrame(new Id3v2FrameHeader(FrameIdentifiers.ETCO));
frame.flags = Id3v2FrameFlags.FileAlterPreservation;
return frame;
}

/**
* Constructs and initializes a new instance by parsing the fields from the field bytes.
* @param header Header of the frame
Expand Down Expand Up @@ -153,12 +143,18 @@ export class EventTimeCodeFrame extends Frame {

/**
* Constructs and initializes a timestamp format set
* @param timestampFormat Timestamp format for the event codes stored in this frame
* @param timestampFormat Optional, timestamp format for the event codes stored in this frame.
* If omitted, defaults to {@link TimestampFormat.Unknown}.
* @param events Optional, list of events to store in the current frame. If omitted, defaults
* to `[]`.
*/
public static fromTimestampFormat(timestampFormat: TimestampFormat): EventTimeCodeFrame {
public static fromFields(timestampFormat?: TimestampFormat, events?: EventTimeCode[]): EventTimeCodeFrame {
const frame = new EventTimeCodeFrame(new Id3v2FrameHeader(FrameIdentifiers.ETCO));
frame.flags = Id3v2FrameFlags.FileAlterPreservation;
frame.timestampFormat = timestampFormat;
frame.flags = Id3v2FrameFlags.FileAlterPreservation; // @TODO: Should we be mucking around with flags like this?

frame._timestampFormat = timestampFormat ?? TimestampFormat.Unknown;
frame._events = events ?? [];

return frame;
}

Expand All @@ -170,7 +166,7 @@ export class EventTimeCodeFrame extends Frame {
* Gets the event this frame contains. Each {@link EventTimeCode} represents a single event at a
* certain point in time.
*/
public get events(): EventTimeCode[] { return this._events || []; }
public get events(): EventTimeCode[] { return this._events ?? []; }
/**
* Sets the event this frame contains
*/
Expand All @@ -196,9 +192,10 @@ export class EventTimeCodeFrame extends Frame {

/** @inheritDoc */
public clone(): Frame {
const frame = new EventTimeCodeFrame(this.header);
frame.timestampFormat = this.timestampFormat;
frame.events = this.events.map((i) => i.clone());
const frame = new EventTimeCodeFrame(new Id3v2FrameHeader(this.frameId, this.flags));
frame._events = this._events.map(i => i.clone());
frame._timestampFormat = this._timestampFormat;

return frame;
}

Expand Down
42 changes: 20 additions & 22 deletions src/id3v2/frames/genreFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import Frame from "./frame";
import Genres from "../../genres";
import Id3v2Settings from "../id3v2Settings";
import {ByteVector, StringType} from "../../byteVector";
import {CorruptFileError} from "../../errors";
import {Id3v2FrameHeader} from "./frameHeader";
import {FrameIdentifiers} from "../frameIdentifiers";
import {ArrayUtils, Guards, StringUtils} from "../../utils";
import {CorruptFileError} from "../../errors";

/**
* This class provides support for ID3v2 TCON content type frames.
Expand All @@ -17,27 +17,14 @@ export default class GenreFrame extends Frame {
private static readonly REMIX_STRING = "Remix";

private _encoding: StringType = Id3v2Settings.defaultEncoding;
private _textFields: string[] = [];
private _textFields: string[];

// #region Constructors

private constructor(header: Id3v2FrameHeader) {
super(header);
}

/**
* Constructs and initializes a new instance.
* @param encoding Optionally, the encoding to use for the new instance. If omitted, defaults
* to {@link Id3v2Settings.defaultEncoding}
*/
public static fromEncoding(
encoding: StringType = Id3v2Settings.defaultEncoding
): GenreFrame {
const frame = new GenreFrame(new Id3v2FrameHeader(FrameIdentifiers.TCON));
frame._encoding = encoding;
return frame;
}

/**
* Constructs and initializes a new instance by parsing the fields from the field bytes.
* @param header Header of the frame
Expand Down Expand Up @@ -131,20 +118,33 @@ export default class GenreFrame extends Frame {
return frame;
}

/**
* Constructs and initializes a new instance.
* @param text Optional, the genres to store in the new instance. If omitted, defaults to an
* empty array.
* @param encoding Optional, the encoding to use for the new instance. If omitted, defaults to
* {@link Id3v2Settings.defaultEncoding}.
*/
public static fromFields(text?: string[], encoding?: StringType): GenreFrame {
const frame = new GenreFrame(new Id3v2FrameHeader(FrameIdentifiers.TCON));
frame._textFields = text ?? [];
frame._encoding = encoding ?? Id3v2Settings.defaultEncoding;

return frame;
}

// #endregion

// #region Properties

/**
* Gets the genres contained in the current instance.
* Note: Modifying the contents of the returned value will not modify the contents of the
* current instance. The value must be reassigned for the value to change.
*/
public get text(): string[] { return this._textFields.slice(); }
public get text(): string[] { return this._textFields; }
/**
* Sets the genres contained in the current instance.
*/
public set text(value: string[]) { this._textFields = value ? value.slice() : []; }
public set text(value: string[]) { this._textFields = value ?? []; }

/**
* Gets the text encoding to use when rendering the current instance.
Expand All @@ -167,9 +167,7 @@ export default class GenreFrame extends Frame {

/** @inheritDoc */
public clone(): Frame {
const frame = GenreFrame.fromEncoding(this._encoding);
frame._textFields = this._textFields.slice();
return frame;
return GenreFrame.fromFields(this._textFields.slice(), this._encoding);
}

/**
Expand Down
26 changes: 13 additions & 13 deletions src/id3v2/frames/musicCdIdentifierFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,6 @@ export default class MusicCdIdentifierFrame extends Frame {
super(header);
}

/**
* Constructs and initializes a new instance with a specified bytes.
* @param data Contents of the frame
*/
public static fromData(data: ByteVector): MusicCdIdentifierFrame {
const frame = new MusicCdIdentifierFrame(new Id3v2FrameHeader(FrameIdentifiers.MCDI));
frame._data = data.toByteVector();
return frame;
}

/**
* Constructs and initialized a new instance by storing the bytes of the frame.
* @param header Header of the frame
Expand All @@ -47,6 +37,18 @@ export default class MusicCdIdentifierFrame extends Frame {
return frame;
}

/**
* Constructs and initializes a new instance with the specified bytes.
* @param data Optional, contents of the frame. If omitted, defaults to an empty
* {@link ByteVector}.
*/
public static fromFields(data?: ByteVector): MusicCdIdentifierFrame {
const frame = new MusicCdIdentifierFrame(new Id3v2FrameHeader(FrameIdentifiers.MCDI));
frame._data = data ?? ByteVector.empty();

return frame;
}

/**
* Gets the identifier data stored in the current instance
*/
Expand All @@ -64,9 +66,7 @@ export default class MusicCdIdentifierFrame extends Frame {

/** @inheritDoc */
public clone(): MusicCdIdentifierFrame {
const frame = new MusicCdIdentifierFrame(new Id3v2FrameHeader(FrameIdentifiers.MCDI));
frame.data = this._data.toByteVector();
return frame;
return MusicCdIdentifierFrame.fromFields(this._data.toByteVector());
}

/** @inheritDoc */
Expand Down
23 changes: 15 additions & 8 deletions src/id3v2/frames/playCountFrame.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Frame from "./frame";
import {ByteVector} from "../../byteVector";
import {CorruptFileError, NotSupportedError} from "../../errors";
import {Id3v2FrameHeader} from "./frameHeader";
import {FrameIdentifiers} from "../frameIdentifiers";
import {ArrayUtils, Guards} from "../../utils";
import {CorruptFileError, NotSupportedError} from "../../errors";

/**
* This class extends {@link Frame} implementing support for ID3v2 play count (PCNT) frames.
Expand All @@ -18,13 +18,6 @@ export default class PlayCountFrame extends Frame {

// #region Constructors

/**
* Constructs and initializes a new instance with a count of zero
*/
public static fromEmpty(): PlayCountFrame {
return new PlayCountFrame(new Id3v2FrameHeader(FrameIdentifiers.PCNT));
}

/**
* Constructs and initialized a new instance by parsing values from the field data.
* @param header Header of the frame
Expand All @@ -50,6 +43,20 @@ export default class PlayCountFrame extends Frame {
return frame;
}

/**
* Constructs and initializes a new instance with a play count.
* @param playCount Optional, number of times the track has been played. If omitted, defaults
* to `0`.
*/
public static fromFields(playCount: bigint = BigInt(0)): PlayCountFrame {
Guards.ulong(playCount, "playCount");

const frame = new PlayCountFrame(new Id3v2FrameHeader(FrameIdentifiers.PCNT));
frame._playCount = playCount;

return frame;
}
Comment on lines +51 to +58

// #endregion

// #region Public Properties
Expand Down
21 changes: 13 additions & 8 deletions src/id3v2/frames/popularimeterFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {ArrayUtils, Guards} from "../../utils";
export default class PopularimeterFrame extends Frame {
private _playCount: bigint;
private _rating: number;
private _user: string = "";
private _user: string;

// #region Constructors

Expand Down Expand Up @@ -70,11 +70,19 @@ export default class PopularimeterFrame extends Frame {
/**
* Constructs and initializes a new instance for a specified user with a rating and play count
* of zero.
* @param user Email of the user that gave the rating
* @param user Optional, email of the user that gave the rating. If omitted, defaults to `""`.
* @param rating Optional, rating of the track. If omitted, defaults to 0.
* @param playCount Optional, number of times the track has been played.
*/
public static fromUser(user: string): PopularimeterFrame {
public static fromFields(user?: string, rating?: number, playCount?: bigint): PopularimeterFrame {
Guards.byteOptional(rating, "rating");
Guards.ulongOptional(playCount, "playCount");

const frame = new PopularimeterFrame(new Id3v2FrameHeader(FrameIdentifiers.POPM));
frame._user = user;
frame._playCount = playCount;
frame._rating = rating ?? 0;
frame._user = user ?? "";

return frame;
}

Expand Down Expand Up @@ -127,10 +135,7 @@ export default class PopularimeterFrame extends Frame {

/** @inheritDoc */
public clone(): Frame {
const frame = PopularimeterFrame.fromUser(this.user);
frame.playCount = this.playCount;
frame.rating = this.rating;
return frame;
return PopularimeterFrame.fromFields(this._user, this._rating, this._playCount);
}

/** @inheritDoc */
Expand Down
15 changes: 8 additions & 7 deletions src/id3v2/frames/privateFrame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@ export default class PrivateFrame extends Frame {

/**
* Constructs and initializes a new instance with the provided owner
* @param owner Owner of the private frame
* @param owner Optional, owner of the private frame. If omitted, defaults to `""`.
* @param privateData Optional, private data contained in the frame. If omitted, defaults to
* an empty {@link ByteVector}.
*/
public static fromOwner(owner: string): PrivateFrame {
public static fromFields(owner?: string, privateData?: ByteVector): PrivateFrame {
const frame = new PrivateFrame(new Id3v2FrameHeader(FrameIdentifiers.PRIV));
frame._owner = owner;
frame._privateData = ByteVector.empty();
frame._owner = owner ?? "";
frame._privateData = privateData ?? ByteVector.empty();
Comment thread
benrr101 marked this conversation as resolved.

return frame;
}

Expand Down Expand Up @@ -88,9 +91,7 @@ export default class PrivateFrame extends Frame {

/** @inheritDoc */
public clone(): Frame {
const frame = PrivateFrame.fromOwner(this._owner);
frame._privateData = this._privateData.toByteVector();
return frame;
return PrivateFrame.fromFields(this._owner, this._privateData.toByteVector());
}

/** @inheritDoc */
Expand Down
Loading