利用WindowsAPICodePack修改音乐的ID3信息

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

朋友由于抠门 SD 卡买小了,结果音乐太多放不下,又不舍得再买新卡,不得已决定重新转码,把音乐码率压低一点,牺牲点音质来换空间(用某些人的话说,反正不是搞音乐的,听不出差别)…

结果千千静听(百度音乐)转码后会把音乐 ID3 信息里的标题当文件名…(PS:怀念当年的 千千静听…)

结果成了这个模样:

由于数量较多,收工改会死人的..

所以只好想办法用程序来批量改

找到了园友的老文章:http://www.cnblogs.com/TianFang/archive/2009/09/27/1574722.html

于是决定用 Windows API Code Pack

不过 MS 网站已经木有 Windows API Code Pack 的链接了

不过找起来也不麻烦

找到后新建工程,添加引用这两个 dll 就可以了

然后在工程里新建类 MediaTags,写入内容如下 :

classMediaTags

{

#regionMp3文件属性

/// <summary>

/// 标题

/// </summary>

[MediaPRoperty("Title")]

publicstringTitle { get; set; }

/// <summary>

/// 子标题

/// </summary>

[MediaProperty("Media.SubTitle")]

publicstringSubTitle { get; set; }

/// <summary>

/// 星级

/// </summary>

[MediaProperty("Rating")]

publicuint? Rating { get; set; }

/// <summary>

/// 备注

/// </summary>

[MediaProperty("Comment")]

publicstringComment { get; set; }

/// <summary>

/// 艺术家

/// </summary>

[MediaProperty("Author")]

publicstringAuthor { get; set; }

/// <summary>

/// 唱片集

/// </summary>

[MediaProperty("Music.AlbumTitle")]

publicstringAlbumTitle { get; set; }

/// <summary>

/// 唱片集艺术家

/// </summary>

[MediaProperty("Music.AlbumArtist")]

publicstringAlbumArtist { get; set; }

/// <summary>

/// 年

/// </summary>

[MediaProperty("Media.Year")]

publicuint? Year { get; set; }

/// <summary>

/// 流派

/// </summary>

[MediaProperty("Music.Genre")]

publicstringGenre { get; set; }

/// <summary>

/// #

/// </summary>

[MediaProperty("Music.TrackNumber")]

publicuint? TrackNumber { get; set; }

/// <summary>

/// 播放时间

/// </summary>

[MediaProperty("Media.Duration")]

publicstringDuration { get;privateset; }

/// <summary>

/// 比特率

/// </summary>

[MediaProperty("Audio.EncodingBitrate")]

publicstringBitRate { get;privateset; }

#endregion

publicMediaTags(stringmediaPath)

{

//var obj = ShellObject.FromParsingName(mp3Path); //缩略图,只读

//obj.Thumbnail.Bitmap.Save(@"R:\2.jpg");

Init(mediaPath);

}

voidInit(stringmediaPath)

{

using(var obj = ShellObject.FromParsingName(mediaPath))

{

var mediaInfo = obj.Properties;

foreach(var properIteminthis.GetType().GetProperties())

{

var mp3Att = properItem.GetCustomAttributes(typeof(MediaPropertyAttribute),false).FirstOrDefault();

var shellProper = mediaInfo.GetProperty("System."+ mp3Att);

varvalue= shellProper ==null?null: shellProper.ValueAsObject;

if(value==null)

{

continue;

}

if(shellProper.ValueType ==typeof(string[]))//艺术家,流派等多值属性

{

properItem.SetValue(this,string.Join(";",valueasstring[]),null);

}

elseif(properItem.PropertyType != shellProper.ValueType)//一些只读属性,类型不是string,但作为string输出,避免转换 如播放时间,比特率等

{

properItem.SetValue(this,value==null?"": shellProper.FormatForDisplay(PropertyDescriptionFormatOptions.None),null);

}

else

{

properItem.SetValue(this,value,null);

}

}

}

}

publicvoidCommit(stringmp3Path)

{

var old =newMediaTags(mp3Path);

using(var obj = ShellObject.FromParsingName(mp3Path))

{

var mediaInfo = obj.Properties;

foreach(var properinthis.GetType().GetProperties())

{

var oldValue = proper.GetValue(old,null);

var newValue = proper.GetValue(this,null);

if(oldValue ==null&& newValue ==null)

{

continue;

}

if(oldValue ==null|| !oldValue.Equals(newValue))

{

var mp3Att = proper.GetCustomAttributes(typeof(MediaPropertyAttribute),false).FirstOrDefault();

var shellProper = mediaInfo.GetProperty("System."+ mp3Att);

Console.WriteLine(mp3Att);

SetPropertyValue(shellProper, newValue);

}

}

}

}

#regionSetPropertyValue

staticvoidSetPropertyValue(IShellProperty prop,objectvalue)

{

if(prop.ValueType ==typeof(string[]))//只读属性不会改变,故与实际类型不符的只有string[]这一种

{

string[] values = (valueasstring).Split(newchar[] {';'}, StringSplitOptions.RemoveEmptyEntries);

(propasShellProperty<string[]>).Value = values;

}

if(prop.ValueType ==typeof(string))

{

(propasShellProperty<string>).Value =valueasstring;

}

elseif(prop.ValueType ==typeof(ushort?))

{

(propasShellProperty<ushort?>).Value =valueasushort?;

}

elseif(prop.ValueType ==typeof(short?))

{

(propasShellProperty<short?>).Value =valueasshort?;

}

elseif(prop.ValueType ==typeof(uint?))

{

(propasShellProperty<uint?>).Value =valueasuint?;

}

elseif(prop.ValueType ==typeof(int?))

{

(propasShellProperty<int?>).Value =valueasint?;

}

elseif(prop.ValueType ==typeof(ulong?))

{

(propasShellProperty<ulong?>).Value =valueasulong?;

}

elseif(prop.ValueType ==typeof(long?))

{

(propasShellProperty<long?>).Value =valueaslong?;

}

elseif(prop.ValueType ==typeof(DateTime?))

{

(propasShellProperty<DateTime?>).Value =valueasDateTime?;

}

elseif(prop.ValueType ==typeof(double?))

{

(propasShellProperty<double?>).Value =valueasdouble?;

}

}

#endregion

#regionMediaPropertyAttribute

[AttributeUsage(AttributeTargets.Property, Inherited =false, AllowMultiple =true)]

sealedclassMediaPropertyAttribute : Attribute

{

publicstringPropertyKey { get;privateset; }

publicMediaPropertyAttribute(stringpropertyKey)

{

this.PropertyKey = propertyKey;

}

publicoverridestringToString()

{

returnPropertyKey;

}

}

#endregion

}

剩下的就很简单了

读取当前文件夹下的所有mp3,批量替换标题

staticvoidMain(string[] args)

{stringfileDirectory = System.IO.Directory.GetCurrentDirectory();

DirectoryInfo folder =newDirectoryInfo(fileDirectory);foreach(FileInfo fileinfolder.GetFiles("*.mp3"))

{

MediaTags mt =newMediaTags(file.FullName);

mt.Title = file.FullName.Replace(fileDirectory +"\\", "").Replace(".mp3", "");

mt.Commit(file.FullName);

}

}

完成效果,剩下批量转换就可以了

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航