Skip to content

Commit 8417f76

Browse files
authored
Merge branch 'master' into feature/support-ETCO-frames
2 parents c9d79d5 + bdbae35 commit 8417f76

File tree

19 files changed

+98255
-55
lines changed

19 files changed

+98255
-55
lines changed

README.md

+102-17
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,116 @@
66
[![Windows Build status](https://ci.appveyor.com/api/projects/status/v7vwgphs239i14ya?svg=true)](https://ci.appveyor.com/project/decriptor/taglib-sharp)
77

88

9-
(aka taglib-sharp) is a library for reading and writing
10-
metadata in media files, including video, audio, and photo formats.
9+
(aka *Taglib-sharp*) is a .NET platform-independent library (tested on Windows/Linux) for reading and writing
10+
metadata in media files, including video, audio, and photo formats.
11+
This is a convenient one-stop-shop to present or tag all your media collection, regardless of which format/container
12+
these might use. You can read/write the standard or more common tags/properties of a media, or you can also create and
13+
retrieve your own custom tags.
14+
15+
It supports the following formats (by file-extensions):
16+
* **Video:** mkv, ogv, avi, wmv, asf, mp4 (m4p, m4v), mpeg (mpg, mpe, mpv, mpg, m2v)
17+
* **Audio:** aa, aax, aac, aiff, ape, dsf, flac, m4a, m4b, m4p, mp3, mpc, mpp, ogg, oga, wav, wma, wv, webm
18+
* **Images:** bmp, gif, jpeg, pbm, pgm, ppm, pnm, pcx, png, tiff, dng, svg
1119

1220
It is API stable, with only API additions (not changes or removals)
1321
occuring in the 2.0 series.
1422

15-
* Bugs: <https://bugzilla.gnome.org/page.cgi?id=browse.html&product=taglib-sharp>
16-
* Tarballs: <http://banshee.fm/download/>
17-
* IRC: Several TagLib# developers are often in #banshee on irc.gnome.org
18-
* Git: <https://github.com/mono/taglib-sharp> or <git://github.com/mono/taglib-sharp.git>
1923

20-
TagLib# is free/open source software, released under the LGPL.
21-
We welcome contributions! Please try to match our coding style,
22-
and include unit tests with any patches. Patches can be submitted
23-
by filing a bug and attaching the diff to it.
24+
## Examples
25+
26+
### Read/write metadata from a video
27+
```C#
28+
var tfile = TagLib.File.Create(@"C:\My video.avi");
29+
string title = tfile.Tag.Title;
30+
TimeSpan duration = tfile.Properties.Duration;
31+
Console.WriteLine("Title: {0}, duration: {1}", title, duration);
32+
33+
// change title in the file
34+
tfile.Tag.Title = "my new title";
35+
tfile.Save();
36+
```
37+
38+
### Read/write metadata from a Audio file
39+
```C#
40+
var tfile = TagLib.File.Create(@"C:\My audio.mp3");
41+
string title = tfile.Tag.Title;
42+
TimeSpan duration = tfile.Properties.Duration;
43+
Console.WriteLine("Title: {0}, duration: {1}", title, duration);
44+
45+
// change title in the file
46+
tfile.Tag.Title = "my new title";
47+
tfile.Save();
48+
```
49+
50+
### Read/write metadata from an Image
51+
```C#
52+
var tfile = TagLib.File.Create(@"C:\My picture.jpg");
53+
string title = tfile.Tag.Title;
54+
var tag = tfile.Tag as TagLib.Image.CombinedImageTag;
55+
DateTime? snapshot = tag.DateTime;
56+
Console.WriteLine("Title: {0}, snapshot taken on {1}", title, snapshot);
57+
58+
// change title in the file
59+
tfile.Tag.Title = "my new title";
60+
tfile.Save();
61+
```
62+
63+
### Read/write custom tags from a specific format
64+
```C#
65+
var tfile = TagLib.File.Create(@"C:\My song.flac");
66+
var custom = (TagLib.Ogg.XiphComment) tfile.GetTag(TagLib.TagTypes.Xiph);
67+
68+
// Read
69+
string [] myfields = custom.GetField("MY_TAG");
70+
Console.WriteLine("First MY_TAG entry: {0}", myfields[0]);
71+
72+
// Write
73+
custom.SetField("MY_TAG", new string[] { "value1", "value2" });
74+
custom.RemoveField("OTHER_FIELD");
75+
rgFile.Save();
76+
```
77+
78+
79+
## Website
80+
TagLib# is available on GitHub: <https://github.com/mono/taglib-sharp>
81+
* **Bugs:** Create an [issue](https://github.com/mono/taglib-sharp/issues)
82+
* **Chat:** Join us at [Gitter](https://gitter.im/mono/taglib-sharp)
83+
* **Git:** Get the source at <git://github.com/mono/taglib-sharp.git>
84+
2485

2586
## Building and Running
2687

27-
### To Build From Git:
88+
### Command Line (Linux)
89+
90+
#### To Build From Git:
2891

2992
```sh
3093
git clone https://github.com/mono/taglib-sharp.git
3194
cd taglib-sharp
3295
./autogen.sh && make
3396
```
3497

35-
### To Build From Tarball:
98+
#### To Build From Tarball:
3699

37100
```
38101
./configure && make
39102
```
40103

41-
### To Test:
104+
#### To Test:
42105

43106
```
44107
make test
45108
```
46109

47-
You can also build from MonoDevelop or Visual Studio using taglib-sharp.sln
110+
### Mono Develop (Linux)
48111

49-
### To Test/Run from Visual Studio (Windows):
112+
You can build from MonoDevelop using taglib-sharp.sln
50113

51-
Running regression by using Nunit 3 Test Adapter:
114+
### Visual Studio (Windows):
115+
116+
You can open it in Visual Studio by using taglib-sharp.sln
117+
118+
#### Running regression by using Nunit 3 Test Adapter:
52119

53120
1. Ensure NuGet packages have been restored
54121
1. See: <https://docs.microsoft.com/en-us/nuget/consume-packages/package-restore>
@@ -61,9 +128,27 @@ Running regression by using Nunit 3 Test Adapter:
61128
1. Double click on a test. Set some breakpoints in the test in the editor panel.
62129
2. right-click on the same test, select "Debug Selected tests".
63130

64-
To test some scenarios and take advantage of the debugger:
131+
#### To test some scenarios and take advantage of the debugger:
65132

66133
1. Make the "debug" project the Startup project
67134
(Right-click on the project, select: "Set as StartUp Project")
68135
2. Just modify the "Program.cs"
69136
3. Set some breakpoints and hit the "Start" button
137+
138+
139+
140+
## They also use TagLib#
141+
Non exhaustive list of projects that use TagLib#:
142+
* [Lidarr](https://lidarr.audio/)
143+
* [MediaPortal 2](https://www.team-mediaportal.com/wiki/display/MediaPortal2/MediaPortal+2)
144+
* [F-Spot](https://en.wikipedia.org/wiki/F-Spot)
145+
146+
And you, what do you use TagLib# for ? Reply [here](https://github.com/mono/taglib-sharp/issues/120)
147+
148+
## Contributions
149+
150+
TagLib# is free/open source software, released under the LGPL.
151+
We welcome contributions! Please try to match our coding style,
152+
and include unit tests with any patches. Patches can be submitted
153+
by issuing a Pull Request (Git).
154+

src/TagLib/CombinedTag.cs

+174-2
Original file line numberDiff line numberDiff line change
@@ -1838,8 +1838,180 @@ public override double ReplayGainAlbumPeak {
18381838
if (tag != null)
18391839
tag.ReplayGainAlbumPeak = value;
18401840
}
1841-
}
1842-
1841+
}
1842+
1843+
/// <summary>
1844+
/// Gets and sets the initial key of the media
1845+
/// represented by the current instance.
1846+
/// </summary>
1847+
/// <value>
1848+
/// A <see cref="string" /> object containing the initial
1849+
/// key of the media represented by the current
1850+
/// instance or <see langword="null" /> if no value present.
1851+
/// </value>
1852+
/// <remarks>
1853+
/// <para>When getting the value, the child tags are looped
1854+
/// through in order and the first non-<see langword="null" />
1855+
/// value is returned.</para>
1856+
/// <para>When setting the value, it is stored in each child
1857+
/// tag.</para>
1858+
/// </remarks>
1859+
/// <seealso cref="Tag.InitialKey" />
1860+
public override string InitialKey
1861+
{
1862+
get
1863+
{
1864+
foreach (Tag tag in tags)
1865+
{
1866+
if (tag == null)
1867+
continue;
1868+
1869+
string value = tag.InitialKey;
1870+
1871+
if (value != null)
1872+
return value;
1873+
}
1874+
1875+
return null;
1876+
}
1877+
1878+
set
1879+
{
1880+
foreach (Tag tag in tags)
1881+
if (tag != null)
1882+
tag.InitialKey = value;
1883+
}
1884+
}
1885+
1886+
/// <summary>
1887+
/// Gets and sets the remixer of the media
1888+
/// represented by the current instance.
1889+
/// </summary>
1890+
/// <value>
1891+
/// A <see cref="string" /> object containing the remixer
1892+
/// of the media represented by the current
1893+
/// instance or <see langword="null" /> if no value present.
1894+
/// </value>
1895+
/// <remarks>
1896+
/// <para>When getting the value, the child tags are looped
1897+
/// through in order and the first non-<see langword="null" />
1898+
/// value is returned.</para>
1899+
/// <para>When setting the value, it is stored in each child
1900+
/// tag.</para>
1901+
/// </remarks>
1902+
/// <seealso cref="Tag.RemixedBy" />
1903+
public override string RemixedBy
1904+
{
1905+
get
1906+
{
1907+
foreach (Tag tag in tags)
1908+
{
1909+
if (tag == null)
1910+
continue;
1911+
1912+
string value = tag.RemixedBy;
1913+
1914+
if (value != null)
1915+
return value;
1916+
}
1917+
1918+
return null;
1919+
}
1920+
1921+
set
1922+
{
1923+
foreach (Tag tag in tags)
1924+
if (tag != null)
1925+
tag.RemixedBy = value;
1926+
}
1927+
}
1928+
1929+
/// <summary>
1930+
/// Gets and sets the publisher of the media
1931+
/// represented by the current instance.
1932+
/// </summary>
1933+
/// <value>
1934+
/// A <see cref="string" /> object containing the
1935+
/// publisher of the media represented by the current
1936+
/// instance or <see langword="null" /> if no value present.
1937+
/// </value>
1938+
/// <remarks>
1939+
/// <para>When getting the value, the child tags are looped
1940+
/// through in order and the first non-<see langword="null" />
1941+
/// value is returned.</para>
1942+
/// <para>When setting the value, it is stored in each child
1943+
/// tag.</para>
1944+
/// </remarks>
1945+
/// <seealso cref="Tag.Publisher" />
1946+
public override string Publisher
1947+
{
1948+
get
1949+
{
1950+
foreach (Tag tag in tags)
1951+
{
1952+
if (tag == null)
1953+
continue;
1954+
1955+
string value = tag.Publisher;
1956+
1957+
if (value != null)
1958+
return value;
1959+
}
1960+
1961+
return null;
1962+
}
1963+
1964+
set
1965+
{
1966+
foreach (Tag tag in tags)
1967+
if (tag != null)
1968+
tag.Publisher = value;
1969+
}
1970+
}
1971+
1972+
/// <summary>
1973+
/// Gets and sets the ISRC (International Standard Recording Code)
1974+
/// of the song represented by the current instance.
1975+
/// </summary>
1976+
/// <value>
1977+
/// A <see cref="string" /> object containing the ISRC
1978+
/// of the media represented by the current
1979+
/// instance or <see langword="null" /> if no value present.
1980+
/// </value>
1981+
/// <remarks>
1982+
/// <para>When getting the value, the child tags are looped
1983+
/// through in order and the first non-<see langword="null" />
1984+
/// value is returned.</para>
1985+
/// <para>When setting the value, it is stored in each child
1986+
/// tag.</para>
1987+
/// </remarks>
1988+
/// <seealso cref="Tag.ISRC" />
1989+
public override string ISRC
1990+
{
1991+
get
1992+
{
1993+
foreach (Tag tag in tags)
1994+
{
1995+
if (tag == null)
1996+
continue;
1997+
1998+
string value = tag.ISRC;
1999+
2000+
if (value != null)
2001+
return value;
2002+
}
2003+
2004+
return null;
2005+
}
2006+
2007+
set
2008+
{
2009+
foreach (Tag tag in tags)
2010+
if (tag != null)
2011+
tag.ISRC = value;
2012+
}
2013+
}
2014+
18432015
/// <summary>
18442016
/// Gets whether or not the current instance is empty.
18452017
/// </summary>

src/TagLib/Id3v2/FrameTypes.cs

+3
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ internal static class FrameType {
6363
public static readonly ReadOnlyByteVector TIT2 = "TIT2";
6464
public static readonly ReadOnlyByteVector TIT3 = "TIT3";
6565
public static readonly ReadOnlyByteVector TIME = "TIME";
66+
public static readonly ReadOnlyByteVector TKEY = "TKEY";
6667
public static readonly ReadOnlyByteVector TMCL = "TMCL";
6768
public static readonly ReadOnlyByteVector TOLY = "TOLY";
6869
public static readonly ReadOnlyByteVector TOPE = "TOPE";
@@ -71,6 +72,7 @@ internal static class FrameType {
7172
public static readonly ReadOnlyByteVector TPE3 = "TPE3";
7273
public static readonly ReadOnlyByteVector TPE4 = "TPE4";
7374
public static readonly ReadOnlyByteVector TPOS = "TPOS";
75+
public static readonly ReadOnlyByteVector TPUB = "TPUB";
7476
public static readonly ReadOnlyByteVector TRCK = "TRCK";
7577
public static readonly ReadOnlyByteVector TRDA = "TRDA";
7678
public static readonly ReadOnlyByteVector TSIZ = "TSIZ";
@@ -79,6 +81,7 @@ internal static class FrameType {
7981
public static readonly ReadOnlyByteVector TSOC = "TSOC"; // Composer Sort Frame
8082
public static readonly ReadOnlyByteVector TSOP = "TSOP"; // Performer Sort Frame
8183
public static readonly ReadOnlyByteVector TSOT = "TSOT"; // Track Title Sort Frame
84+
public static readonly ReadOnlyByteVector TSRC = "TSRC";
8285
public static readonly ReadOnlyByteVector TXXX = "TXXX";
8386
public static readonly ReadOnlyByteVector TYER = "TYER";
8487
public static readonly ReadOnlyByteVector UFID = "UFID";

src/TagLib/Id3v2/Frames/AttachmentFrame.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ public void Load()
739739
finally
740740
{
741741
// Free the resources
742-
if (stream != null)
742+
if (stream != null && file != null)
743743
{
744744
file.CloseStream(stream);
745745
}

0 commit comments

Comments
 (0)