朋友由于抠门 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);
}
}
完成效果,剩下批量转换就可以了