Initial commit
This commit is contained in:
commit
262601edb8
2025 files changed
+218754
No files matched your search
@@ -0,0 +1,262 @@
|
||||
//
|
||||
// File.cs:
|
||||
//
|
||||
// Author:
|
||||
// Guy Taylor (s0700260@sms.ed.ac.uk) (thebigguy.co.uk@gmail.com)
|
||||
//
|
||||
// Original Source:
|
||||
// Ogg/File.cs from TagLib-sharp
|
||||
//
|
||||
// Copyright (C) 2009 Guy Taylor (Original Implementation)
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License version
|
||||
// 2.1 as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
//
|
||||
using System;
|
||||
|
||||
namespace TagLib.Audible
|
||||
{
|
||||
/// <summary>
|
||||
/// This class extends <see cref="TagLib.File" /> to provide tagging
|
||||
/// and properties support for Audible inc's aa file format.
|
||||
/// </summary>
|
||||
[SupportedMimeType ("audio/x-audible")]
|
||||
[SupportedMimeType ("taglib/aa", "aa")]
|
||||
[SupportedMimeType ("taglib/aax", "aax")]
|
||||
public class File : TagLib.File
|
||||
{
|
||||
|
||||
#region Private Fields
|
||||
|
||||
/// <summary>
|
||||
/// Contains the tags for the file.
|
||||
/// </summary>
|
||||
readonly TagLib.Tag tag;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Static Fields
|
||||
|
||||
/// <summary>
|
||||
/// The offset to the tag block.
|
||||
/// </summary>
|
||||
public const short TagBlockOffset = 0xBD;
|
||||
|
||||
/// <summary>
|
||||
/// The offset to the end of tag pointer.
|
||||
/// </summary>
|
||||
public const short OffsetToEndTagPointer = 0x38;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified path in the local file
|
||||
/// system and specified read style.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// A <see cref="string" /> object containing the path of the
|
||||
/// file to use in the new instance.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="path" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
public File (string path, ReadStyle propertiesStyle)
|
||||
: this (new LocalFileAbstraction (path), propertiesStyle)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified path in the local file
|
||||
/// system with an average read style.
|
||||
/// </summary>
|
||||
/// <param name="path">
|
||||
/// A <see cref="string" /> object containing the path of the
|
||||
/// file to use in the new instance.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="path" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
public File (string path)
|
||||
: this (path, ReadStyle.Average)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified file abstraction and
|
||||
/// specified read style.
|
||||
/// </summary>
|
||||
/// <param name="abstraction">
|
||||
/// A <see cref="TagLib.File.IFileAbstraction" /> object to use when
|
||||
/// reading from and writing to the file.
|
||||
/// </param>
|
||||
/// <param name="propertiesStyle">
|
||||
/// A <see cref="ReadStyle" /> value specifying at what level
|
||||
/// of accuracy to read the media properties, or <see
|
||||
/// cref="ReadStyle.None" /> to ignore the properties.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="abstraction" /> is <see langword="null"
|
||||
/// />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// The file is not the write length.
|
||||
/// </exception>
|
||||
public File (IFileAbstraction abstraction, ReadStyle propertiesStyle)
|
||||
: base (abstraction)
|
||||
{
|
||||
|
||||
Mode = AccessMode.Read;
|
||||
|
||||
try {
|
||||
// get the pointer to the end of the tag block
|
||||
// and calculate the tag block length
|
||||
Seek (OffsetToEndTagPointer);
|
||||
int tagLen = ((int)ReadBlock (4).ToUInt (true)) - TagBlockOffset;
|
||||
|
||||
// read the whole tag and send to Tag class
|
||||
Seek (TagBlockOffset);
|
||||
ByteVector bv = ReadBlock (tagLen);
|
||||
|
||||
tag = new Tag (bv);
|
||||
|
||||
} finally {
|
||||
Mode = AccessMode.Closed;
|
||||
}
|
||||
|
||||
// ??
|
||||
TagTypesOnDisk = TagTypes;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="File" /> for a specified file abstraction with an
|
||||
/// average read style.
|
||||
/// </summary>
|
||||
/// <param name="abstraction">
|
||||
/// A <see cref="TagLib.File.IFileAbstraction" /> object to use when
|
||||
/// reading from and writing to the file.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="abstraction" /> is <see langword="null"
|
||||
/// />.
|
||||
/// </exception>
|
||||
public File (IFileAbstraction abstraction)
|
||||
: this (abstraction, ReadStyle.Average)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Saves the changes made in the current instance to the
|
||||
/// file it represents.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently this does not work as there is not enough
|
||||
/// information about the file format
|
||||
/// </remarks>
|
||||
public override void Save ()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a set of tag types from the current instance.
|
||||
/// </summary>
|
||||
/// <param name="types">
|
||||
/// A bitwise combined <see cref="TagLib.TagTypes" /> value
|
||||
/// containing tag types to be removed from the file.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// In order to remove all tags from a file, pass <see
|
||||
/// cref="TagTypes.AllTags" /> as <paramref name="types" />.
|
||||
/// </remarks>
|
||||
/// <remarks>
|
||||
/// Currently this does not work as there is not enough
|
||||
/// information about the file format
|
||||
/// </remarks>
|
||||
public override void RemoveTags (TagTypes types)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a tag of a specified type from the current instance,
|
||||
/// optionally creating a new tag if possible.
|
||||
/// </summary>
|
||||
/// <param name="type">
|
||||
/// A <see cref="TagLib.TagTypes" /> value indicating the
|
||||
/// type of tag to read.
|
||||
/// </param>
|
||||
/// <param name="create">
|
||||
/// A <see cref="bool" /> value specifying whether or not to
|
||||
/// try and create the tag if one is not found.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A <see cref="Tag" /> object containing the tag that was
|
||||
/// found in or added to the current instance. If no
|
||||
/// matching tag was found and none was created, <see
|
||||
/// langword="null" /> is returned.
|
||||
/// </returns>
|
||||
public override TagLib.Tag GetTag (TagTypes type, bool create)
|
||||
{
|
||||
if (type == TagTypes.AudibleMetadata)
|
||||
return tag;
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Gets a abstract representation of all tags stored in the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="TagLib.Tag" /> object representing all tags
|
||||
/// stored in the current instance.
|
||||
/// </value>
|
||||
public override TagLib.Tag Tag {
|
||||
get { return tag; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the media properties of the file represented by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="TagLib.Properties" /> object containing the
|
||||
/// media properties of the file represented by the current
|
||||
/// instance.
|
||||
/// </value>
|
||||
public override Properties Properties { get; } = new Properties ();
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 006f7fb1983a3a1a89f28703d552cbc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,320 @@
|
||||
//
|
||||
// Tag.cs:
|
||||
//
|
||||
// Author:
|
||||
// Guy Taylor (s0700260@sms.ed.ac.uk) (thebigguy.co.uk@gmail.com)
|
||||
//
|
||||
// Original Source:
|
||||
// Id3v1/Tag.cs from TagLib-sharp
|
||||
//
|
||||
// Copyright (C) 2009 Guy Taylor (Original Implementation)
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License version
|
||||
// 2.1 as published by the Free Software Foundation.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
// USA
|
||||
//
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TagLib.Audible
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// This class extends <see cref="Tag" /> to provide support for
|
||||
/// reading tags stored in the Audible Metadata format.
|
||||
/// </summary>
|
||||
public class Tag : TagLib.Tag
|
||||
{
|
||||
#region Private Fields
|
||||
|
||||
List<KeyValuePair<string, string>> tags;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="Tag" /> with no contents.
|
||||
/// </summary>
|
||||
public Tag ()
|
||||
{
|
||||
Clear ();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="Tag" /> by reading the contents from a specified
|
||||
/// position in a specified file.
|
||||
/// </summary>
|
||||
/// <param name="file">
|
||||
/// A <see cref="File" /> object containing the file from
|
||||
/// which the contents of the new instance is to be read.
|
||||
/// </param>
|
||||
/// <param name="position">
|
||||
/// A <see cref="long" /> value specify at what position to
|
||||
/// read the tag.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="file" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">
|
||||
/// <paramref name="position" /> is less than zero or greater
|
||||
/// than the size of the file.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// The file does not contain FileIdentifier
|
||||
/// at the given position.
|
||||
/// </exception>
|
||||
public Tag (File file, long position)
|
||||
{
|
||||
// TODO: can we read from file
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs and initializes a new instance of <see
|
||||
/// cref="Tag" /> by reading the contents from a specified
|
||||
/// <see cref="ByteVector" /> object.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object to read the tag from.
|
||||
/// </param>
|
||||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="data" /> is <see langword="null" />.
|
||||
/// </exception>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> is less than 128 bytes or does
|
||||
/// not start with FileIdentifier.
|
||||
/// </exception>
|
||||
public Tag (ByteVector data)
|
||||
{
|
||||
|
||||
if (data == null)
|
||||
throw new ArgumentNullException (nameof (data));
|
||||
|
||||
Clear ();
|
||||
Parse (data);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Populates the current instance by parsing the contents of
|
||||
/// a raw AudibleMetadata tag.
|
||||
/// </summary>
|
||||
/// <param name="data">
|
||||
/// A <see cref="ByteVector" /> object containing the whole tag
|
||||
/// object
|
||||
/// </param>
|
||||
/// <exception cref="CorruptFileException">
|
||||
/// <paramref name="data" /> is less than 128 bytes or does
|
||||
/// not start with FileIdentifier.
|
||||
/// </exception>
|
||||
void Parse (ByteVector data)
|
||||
{
|
||||
string currentKey, currentValue;
|
||||
int keyLen, valueLen;
|
||||
|
||||
try {
|
||||
do {
|
||||
keyLen = (int)data.ToUInt (true);
|
||||
data.RemoveRange (0, 4);
|
||||
valueLen = (int)data.ToUInt (true);
|
||||
data.RemoveRange (0, 4);
|
||||
currentKey = data.ToString (StringType.UTF8, 0, keyLen);
|
||||
data.RemoveRange (0, keyLen);
|
||||
currentValue = data.ToString (StringType.UTF8, 0, valueLen);
|
||||
data.RemoveRange (0, valueLen);
|
||||
|
||||
tags.Add (new KeyValuePair<string, string> (currentKey, currentValue));
|
||||
|
||||
//StringHandle (currentKey, currentValue);
|
||||
|
||||
// if it is not the last item remove the end byte (null terminated)
|
||||
if (data.Count != 0)
|
||||
data.RemoveRange (0, 1);
|
||||
}
|
||||
while (data.Count >= 4);
|
||||
} catch (Exception) {
|
||||
//
|
||||
}
|
||||
|
||||
if (data.Count != 0)
|
||||
throw new CorruptFileException ();
|
||||
}
|
||||
|
||||
void setTag (string tagName, string value)
|
||||
{
|
||||
for (int i = 0; i < tags.Count; i++) {
|
||||
if (tags[i].Key == tagName)
|
||||
tags[i] = new KeyValuePair<string, string> (tags[i].Key, value);
|
||||
}
|
||||
}
|
||||
|
||||
string getTag (string tagName)
|
||||
{
|
||||
foreach (KeyValuePair<string, string> tag in tags) {
|
||||
if (tag.Key == tagName)
|
||||
return tag.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
/// Given a key and value pair it will update the
|
||||
/// present metadata.
|
||||
/// </summary>
|
||||
/// <param name="key">
|
||||
/// A <see cref="String" /> containing the key.
|
||||
/// </param>
|
||||
/// <param name="strValue">
|
||||
/// A <see cref="String" /> containing the value.
|
||||
/// </param>
|
||||
private void StringHandle (String key, String strValue)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case "title":
|
||||
title = strValue;
|
||||
break;
|
||||
case "author":
|
||||
artist = strValue;
|
||||
break;
|
||||
case "provider":
|
||||
album = strValue;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region TagLib.Tag
|
||||
|
||||
/// <summary>
|
||||
/// Gets the tag types contained in the current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// Always <see cref="TagTypes.AudibleMetadata" />.
|
||||
/// </value>
|
||||
public override TagTypes TagTypes {
|
||||
get { return TagTypes.AudibleMetadata; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or Set the Author Tag
|
||||
/// </summary>
|
||||
|
||||
public string Author {
|
||||
get {
|
||||
return getTag ("author");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or Set the Copyright Tag
|
||||
/// </summary>
|
||||
|
||||
public override string Copyright {
|
||||
get {
|
||||
return getTag ("copyright");
|
||||
}
|
||||
set {
|
||||
setTag ("copyright", value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or Set the Description Tag
|
||||
/// </summary>
|
||||
|
||||
public override string Description {
|
||||
get { return getTag ("description"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get or Set the Narrator Tag
|
||||
/// </summary>
|
||||
public string Narrator {
|
||||
get {
|
||||
return getTag ("narrator");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the title for the media described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the title for
|
||||
/// the media described by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
public override string Title {
|
||||
get {
|
||||
return getTag ("title");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the album for the media described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="string" /> object containing the album for
|
||||
/// the media described by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
public override string Album {
|
||||
get {
|
||||
return getTag ("provider");
|
||||
//return string.IsNullOrEmpty (album) ?
|
||||
// null : album;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the album artist for the media described by the
|
||||
/// current instance.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// A <see cref="T:string[]" /> object containing a single
|
||||
/// artist described by the current instance or <see
|
||||
/// langword="null" /> if no value is present.
|
||||
/// </value>
|
||||
public override string[] AlbumArtists {
|
||||
get {
|
||||
var artist = getTag ("provider");
|
||||
|
||||
return string.IsNullOrEmpty (artist) ?
|
||||
null : new [] { artist };
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the values stored in the current instance.
|
||||
/// </summary>
|
||||
public override void Clear ()
|
||||
{
|
||||
tags = new List<KeyValuePair<string, string>> ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c399f58c554dc5479a139a58c8a72b80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in new issue
Block a user