发布一个开源小工具,支持将酷狗和网易云音乐的缓存文件转码为MP3文件。

以前写过kgtemp文件转mp3工具,正好当前又有网易云音乐缓存文件需求,因此就在原来小工具的基础上做了一点修改,增加了对网易云音乐的支持,并简单调整了下代码结构,方便后续增加其他音乐软件的支持。

工具使用介绍

下载程序(点击下载),然后启动程序,

  • 首先,设置输入目录,也就是解密后的文件存放在哪里
  • 然后将酷狗或者网易的缓存文件 or 整个文件夹,拖入到程序即可

打开转码结果目录,可以看到转码后的结果

缓存目录如何找

网易云音乐的缓存目录

打开设置 -- 下载设置 - 缓存目录就是了

酷狗缓存目录

如图,在设置--下载设置里

工具代码简要说明

类图

ICacheDecrypt

我们定义一个解码接口ICacheDecrypt,实现将缓存文件字节流转换为mp3字节流。

 /// <summary>
/// 解密接口
/// </summary>
public interface ICacheDecrypt
{ string AcceptableExtension
{
get;
} bool isAcceptable(string cacheFile); /// <summary>
/// 解密文件
/// </summary>
/// <param name="cacheFile">缓存文件</param>
/// <returns>解密后二进制数据</returns>
byte[] Decrypt(string cacheFile); /// <summary>
/// 解密文件
/// </summary>
/// <param name="cacheFileData">缓存文件数据</param>
/// <returns></returns>
byte[] Decrypt(byte[] cacheFileData); /// <summary>
/// 解密文件
/// </summary>
/// <param name="cacheFile">cache文件</param>
/// <param name="decodedFile">解密后文件</param>
void Decrypt(string cacheFile,string decodedFile); }

BaseCacheDecrypt

然后,实现一个默认的抽象类BaseCacheDecrypt,实现一些公共的东西,具体的转码工作让子类去实现,比如网易和酷狗可以分别建一个子类。

public abstract class BaseCacheDecrypt : ICacheDecrypt
{ protected string currentCacheFile; public abstract string AcceptableExtension
{
get;
} public abstract byte[] Decrypt(byte[] cacheFileData); public byte[] Decrypt(string cacheFile)
{
currentCacheFile = cacheFile;
return Decrypt(File.ReadAllBytes(cacheFile));
} public void Decrypt(string cacheFile, string decodedFile)
{
File.WriteAllBytes(decodedFile, Decrypt(cacheFile));
} public bool isAcceptable(string cacheFile)
{
return cacheFile.EndsWith(AcceptableExtension);
}
}

NetMusicCacheDecrypt

然后,分别实现酷狗和网易云音乐的解码工作,酷狗的上次已经写了如何解码,这里只贴网易的,解码很简单,异或0xa3就可以了。网易音乐在测试时发现好多mp3没有ID3信息,经过观察发现缓存文件名里包含歌曲的id信息,因此可以根据这个id信息去抓取歌曲网页,解析出歌手和歌曲名称,然后写入到ID3里,这里ID3的读写采用了GitHub上的一个开源库


/// <summary>
/// 网易云缓存解密
/// </summary>
public class NetMusicCacheDecrypt : BaseCacheDecrypt
{
public override string AcceptableExtension
{
get
{
return ".uc";
}
} string cut(string str,string start,string end)
{
var startIndex = str.IndexOf(start);
if (startIndex == -1)
{
return "";
}
startIndex += start.Length;
var endIndex = str.IndexOf(end, startIndex);
if (endIndex == -1)
{
return "";
}
return str.Substring(startIndex, endIndex - startIndex);
} public override byte[] Decrypt(byte[] cacheFileData)
{
for (var i = 0; i < cacheFileData.Length; i++)
{
// 异或0xa3
cacheFileData[i] ^= 0xa3;
} var fileName = new FileInfo(currentCacheFile).Name;
var songId = fileName.Substring(0, fileName.IndexOf("-"));
var html = HttpHelper.SendGet("http://music.163.com/song?id=" + songId);
if (html.Length > 0)
{
var title = cut(html, "<title>", "</title>").Trim();
var tempFile = currentCacheFile+ Guid.NewGuid().ToString();
File.WriteAllBytes(tempFile, cacheFileData);
Track theTrack = new Track(tempFile);
// 父亲写的散文诗(时光版) - 许飞 - 单曲 - 网易云音乐
theTrack.Artist = cut(title, "-", "-").Trim();
theTrack.Title = title.Substring(0, title.IndexOf("-")).Trim();
// Save modifications on the disc
theTrack.Save();
cacheFileData = File.ReadAllBytes(tempFile);
File.Delete(tempFile); } return cacheFileData;
} }

接着介绍核心的Decryptor,实现转码的调度,这里的思路就是将所有的解码器放到一个list里,当一个文件过来的时候,遍历所有解码器,如果accetbale,就处理,否则跳过。

两个主要工作:

  • 加载所有的BaseCacheDecrypt
  • 进行解码工作

加载所有的BaseCacheDecrypt

两种方法,一是自己实例化,一是使用反射,这里当然用反射了:)


private Decryptor()
{ } public static Decryptor Instance
{
get
{
return Holder.decryptor;
}
}
static class Holder
{
public static Decryptor decryptor = Load(); /// <summary>
/// 从当前Assembly加载
/// </summary>
/// <returns></returns>
private static Decryptor Load()
{
Assembly assembly = Assembly.GetExecutingAssembly();
List<Type> hostTypes = new List<Type>(); foreach (var type in assembly.GetExportedTypes())
{
//确定type为类并且继承自(实现)IMyInstance
if (type.IsClass && typeof(BaseCacheDecrypt).IsAssignableFrom(type) && !type.IsAbstract)
hostTypes.Add(type);
} Decryptor decryptor = new Decryptor();
foreach (var type in hostTypes)
{
ICacheDecrypt instance = (ICacheDecrypt)Activator.CreateInstance(type);
decryptor.cacheDecryptors.Add(instance);
} return decryptor;
}
}

Decryptor通过单例模式对外提供调用。

进行解码

判断拖入的是文件夹还是文件,文件夹的话遍历子文件,依次处理。解码方式就是钢说的,遍历decryptors,如果支持就解码。

解码完后,读取ID3信息,对文件进行重命名。

 public int Process(string path)
{
int success = 0; if (Directory.Exists(path))//如果是文件夹
{
DirectoryInfo dinfo = new DirectoryInfo(path);//实例化一个DirectoryInfo对象
foreach (FileInfo fs in dinfo.GetFiles()) //查找.kgtemp文件
{
ProcessFile(fs.FullName);
success++;
}
}
else
{
ProcessFile(path);
success = 1;
} return success;
} private string GetCleanFileName(string fileName)
{
StringBuilder rBuilder = new StringBuilder(fileName);
foreach (char rInvalidChar in Path.GetInvalidFileNameChars())
rBuilder.Replace(rInvalidChar.ToString(), string.Empty);
return rBuilder.ToString();
} private string GetTargetFileName(string fileName)
{
var fileinfo = new FileInfo(fileName);
var rawName = fileinfo.Name.Substring(0, fileinfo.Name.IndexOf("."));
return TargetDirectory + Path.DirectorySeparatorChar + rawName + ".mp3";
} void ProcessFile(string fileName)
{
_logger.Info("开始处理" + fileName);
try
{
foreach (var decryptor in cacheDecryptors)
{
if (decryptor.isAcceptable(fileName))
{
var targetName = TargetDirectory + Path.DirectorySeparatorChar + new FileInfo(fileName).Name + ".mp3"; decryptor.Decrypt(fileName, targetName); // 重命名
if (AutoRename)
{
var mp3 = ID3Helper.ReadMp3(targetName); if (mp3.Title.Length > 0)
{
string realFileName = GetTargetFileName(GetCleanFileName(mp3.Title + "-" + mp3.Artist + ".mp3")); _logger.Info("重命名" + realFileName);
if (File.Exists(realFileName))
{
File.Delete(realFileName);
} File.Move(targetName, realFileName);
}
}
}
}
_logger.Info(fileName + "处理完成");
}
catch(Exception ex)
{
_logger.Error(fileName + "出现异常" + ex.Message);
} }

开源地址

代码托管到了GitHub,musicDecryptor, 感兴趣的可以访问进行


作者:Jadepeng

出处:jqpeng的技术记事本--http://www.cnblogs.com/xiaoqi

您的支持是对博主最大的鼓励,感谢您的认真阅读。

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

开源小工具 酷狗、网易音乐缓存文件转mp3工具的更多相关文章

  1. 酷狗歌曲缓存kgtemp转mp3工具

    一直用网易音乐听歌,不过网易的歌曲版权确实是少了一些,在酷狗上可以找到,但收费歌曲只能试听不能下载. 寻找方案 从设置里可以看出,酷狗会设置缓存目录,试听的歌曲存放到这个缓存里. 打开缓存目录: 可以 ...

  2. Python解密网易云音乐缓存文件获取MP3

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:GeneralMonkey Python解密网易云音乐缓存文件获取MP3 ...

  3. 酷狗mac版如何新建歌单?酷狗mac版收藏歌单方法

    很多朋友们都喜欢使用酷狗音乐听音乐,不过最近有使用酷狗mac音乐播放器的Mac新用户,想要新建歌单收藏歌单,但有不知道如何操作,那么苹果电脑酷狗mac版如何新建歌单收藏歌单呢?针对此问题,本文给大家介 ...

  4. Python爬虫:通过做项目,小编了解了酷狗音乐的加密过程

    1.前言 小编在这里讲一下,下面的内容仅供学习参考,切莫用于商业活动,一经被相关人员发现,本小编概不负责!读者切记切记. 2.获取音乐播放列表 其实,这就是小编要讲的重点,因为就是这部分用到了加密. ...

  5. 记一次酷狗音乐API的获取,感兴趣的可以自己封装开发自己的音乐播放器

    1.本教程仅供个人学习用,禁止用于任何的商业和非法用途,如涉及版权问题请联系笔者删除. 2.随笔系作者原创文档,转载请注明文档来源:http://www.cnblogs.com/apresunday/ ...

  6. 酷狗音乐快速转换MP3格式的方法

    喜欢听音乐的朋友们,散步跑步的时候都是随身听,音乐可以给人带来力量,让人心情愉悦,有时候甚至还可以让我们忘记烦恼和忧愁,是一种不错的解压方式,所以热爱运动的宝宝们是离不来音乐的陪伴的,这样说来随身听的 ...

  7. Redrain仿酷狗音乐播放器开发完毕,发布测试程序

    转载请说明原出处,谢谢~~ 从暑假到现在中秋刚过,我用duilib开发仿酷狗播放器大概经历了50天.做仿酷狗的意图只是看原酷狗的界面比较漂亮,想做个完整一些的工程来练习一下duilib.今天把写好的程 ...

  8. 在线音乐播放器-----酷狗音乐api接口抓取

    首先身为一个在线音乐播放器,需要前端和数据库的搭配使用. 在数据库方面,我们没有办法制作,首先是版权问题,再加上数据量.所以我们需要借用其他网络播放器的数据库. 但是这些在线播放器,如百度,酷狗,酷我 ...

  9. 闲来无事研究一下酷狗缓存文件kgtemp的加密方式

    此贴为本人原创,转载请注明出处 序 前几天更新了被打入冷宫很久的酷狗,等进入之后就感觉菊花一紧----试 听 居 然 都 要 开 通 音 乐 包(高品和无损)才行了,WTF! 这意味着以前缓存的都听不 ...

随机推荐

  1. SCRIPT5007:无法获取属性“show”的值,对象为null或未定义

    1.错误描述 SCRIPT5007:无法获取属性"show"的值,对象为null或未定义            dojo.js,行15.字符11808 2.错误原因    requ ...

  2. TypeError: Error #1009: 无法访问空对象引用的属性或方法

    1.错误描述 TypeError: Error #1009: 无法访问空对象引用的属性或方法. at FirstMap/search_clickHandler()[E:\Flash Builder\M ...

  3. 芝麻HTTP: Python爬虫利器之Requests库的用法

    前言 之前我们用了 urllib 库,这个作为入门的工具还是不错的,对了解一些爬虫的基本理念,掌握爬虫爬取的流程有所帮助.入门之后,我们就需要学习一些更加高级的内容和工具来方便我们的爬取.那么这一节来 ...

  4. 网络协议笔记-网络层-ARP协议

    [2-地址解析协议ARP] [2.1-基本概念] 地址解析协议ARP的作用是根据主机的IP地址,找出该主机的硬件地址. [2.2-为什么要使用ARP] 在数据传输过程中,网络层使用的IP地址,但是在实 ...

  5. css样式--表格

    1.示例源码 <!DOCTYPE html><html><head><meta charset="utf-8"> <title ...

  6. [BZOJ1003] [ZJOI2006] 物流运输trans (最短路 & dp)

    Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格 ...

  7. xctf的一道题目(77777)

    这次比赛我没有参加,这是结束之后才做的题目 题目链接http://47.97.168.223:23333 根据题目信息,我们要update那个points值,那就是有很大可能这道题目是一个sql注入的 ...

  8. jxl 导出数据到excel

    优点: Jxl对中文支持非常好,操作简单,方法看名知意. Jxl是纯javaAPI,在跨平台上表现的非常完美,代码可以再windows或者Linux上运行而无需重新编写 支持Excel 95-2000 ...

  9. css块级元素和内联元素

    左边的是块级元素block,右边内联inline. 修改方法 display: inline;

  10. Java注解学习

    一.注解定义 JVM5.0定义了4个标准的元注解: @Target, @Retention, @Documented @Inherited 1. @Target 作用:用于描述注解的使用范围 取值El ...