using System;
|
using System.IO;
|
using System.Net;
|
using System.Security.Cryptography;
|
using System.Text;
|
using Shared.Net;
|
using Shared.SimpleControl.R;
|
using SmartHome.UI.SimpleControl.Phone.Music;
|
|
namespace Shared.SimpleControl.Phone.Music
|
{
|
|
[System.Serializable]
|
public class TidalConfig
|
{
|
public readonly static string FileName = "TidalConfig";
|
/// <summary>
|
/// 用户名
|
/// </summary>
|
public string UserName;
|
/// <summary>
|
/// 密码
|
/// </summary>
|
public string Passwrod;
|
}
|
|
[System.Serializable]
|
public class Tidal
|
{
|
public static string fileName = "Tidal";
|
#region
|
public static readonly System.Collections.Generic.List<MusicInfo> TempMusicInfoList = new System.Collections.Generic.List<MusicInfo> ();
|
#endregion
|
//保存当前信息
|
public void Save ()
|
{
|
Shared.IO.FileUtils.WriteFileByBytes (fileName, System.Text.Encoding.UTF8.GetBytes (Newtonsoft.Json.JsonConvert.SerializeObject (CurrentTidal)));
|
}
|
|
public static string GetResult (string url)
|
{
|
var datetTime = DateTime.Now;
|
var webclient = new MyWebClient ();
|
webclient.Proxy = null;
|
webclient.Headers.Add ("Authorization", "Basic " + Authorization);
|
var resut = webclient.DownloadString (url);
|
System.Console.WriteLine (url + "获取数据时长:" + (DateTime.Now - datetTime).TotalMilliseconds);
|
return resut;
|
//var datetTime = DateTime.Now;
|
//var result = httpRequest.HTTPRequest.HTTPRequestA (url, "Authorization", "Basic " + Authorization, 10);
|
//System.Console.WriteLine (url + "获取数据时长:" + (DateTime.Now - datetTime).TotalMilliseconds);
|
//if (result == null) {
|
// return null;
|
//} else {
|
// return System.Text.Encoding.UTF8.GetString (result.ToArray ());
|
//}
|
}
|
|
public static void InitTokenTime ()
|
{
|
Shared.IO.FileUtils.DeleteFile (fileName);
|
CurrentTidal = null;
|
//尝试获取多次,有可能有的时候网络有问题获取不成功
|
int count = 2;
|
while (0 < count) {
|
count--;
|
if (initTokenTime ()) {
|
//如果获取到时间,就马上退出
|
break;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 获取真实播放地址
|
/// </summary>
|
/// <param name="musicInfo">Music info.</param>
|
public static void ReadRealUrl (MusicInfo musicInfo)
|
{
|
try {
|
if (musicInfo.URL.StartsWith ("https://meta.airable.io")) {
|
var result = GetResult (musicInfo.URL);
|
if (!string.IsNullOrEmpty (result)) {
|
var airable = Newtonsoft.Json.JsonConvert.DeserializeObject<Airable> (result);
|
if (airable != null && airable.url != null)
|
musicInfo.URL = airable.url;
|
}
|
}
|
} catch { }
|
}
|
|
static Tidal ()
|
{
|
new Tidal { IsLogin = false, id = new string [0], time = 0, token = "" };
|
if (Shared.IO.FileUtils.Exists (fileName)) {
|
CurrentTidal = Newtonsoft.Json.JsonConvert.DeserializeObject<Tidal> (System.Text.Encoding.UTF8.GetString (Shared.IO.FileUtils.ReadFile (fileName)));
|
}
|
}
|
//是否已经登录了
|
public bool IsLogin;
|
/// <summary>
|
/// 当前Token
|
/// </summary>
|
public string token;
|
/// <summary>
|
/// 服务器记录时间
|
/// </summary>
|
public long time;
|
public string [] id;
|
// "{\"id\":[\"airable\",\"accesstoken\",\"authentication\"],\"token\":\"6ALMArG5kLS6kciUvYuiBhaeXO1JQMGBk8qXEslY9tvSghVIpdwggVRZ1QDsLR3i\",\"time\":1512032632}"
|
public static Tidal CurrentTidal {
|
internal set;
|
get;
|
}
|
|
//ECJUFDFLAIA
|
static string secret = "PJFKwfIWH7LIoaYGqlEOe5x2QzLCzcVN";
|
static string @name = "audiocast";
|
static string version = "1.0";
|
static string locale = "en-US";
|
|
public static string Authorization {
|
get {
|
if (CurrentTidal == null) {
|
return null;
|
}
|
var ts = (DateTime.UtcNow - new DateTime (1970, 1, 1, 0, 0, 0, 0));
|
var time = Convert.ToInt64 (ts.TotalSeconds).ToString ();
|
var result = Encoding.ASCII.GetBytes (CurrentTidal.token + secret + time);
|
var output = new MD5CryptoServiceProvider ().ComputeHash (result);
|
var password = BitConverter.ToString (output).Replace ("-", "").ToLower ();
|
return Convert.ToBase64String (System.Text.Encoding.ASCII.GetBytes (CurrentTidal.token + ":" + password));
|
}
|
}
|
|
static bool initTokenTime ()
|
{
|
try {
|
string salt = "345548ab";
|
var deviceUniqueId = DateTime.Now.Ticks.ToString();
|
string ss = string.Format ("{0}{1}{2}{3}",deviceUniqueId , locale, salt, secret);
|
|
var result = Encoding.ASCII.GetBytes (ss);
|
var output = new MD5CryptoServiceProvider ().ComputeHash (result);
|
var password = BitConverter.ToString (output).Replace ("-", "").ToLower ();
|
|
string url = string.Format ("https://meta.airable.io/authentication?device={0}&name={1}&version={2}&locale={3}&salt={4}&signature={5}",
|
deviceUniqueId,
|
name,
|
version,
|
locale,
|
salt,
|
password
|
);
|
var dateTime = DateTime.Now;
|
|
CurrentTidal = Newtonsoft.Json.JsonConvert.DeserializeObject<Tidal> (GetResult (url));
|
System.Console.WriteLine ("获取Token时间时长:" + (DateTime.Now - dateTime).TotalMilliseconds);
|
//如果获取到时候及Token,马上保存
|
CurrentTidal.Save ();
|
|
return true;
|
} catch {
|
return false;
|
}
|
}
|
|
|
public static bool Login ()
|
{
|
InitTokenTime ();
|
|
try {
|
//可能网络或者其它原因,时间获取不到,下面代码不能执行
|
if (CurrentTidal == null) {
|
return false;
|
}
|
|
var tidal = Newtonsoft.Json.JsonConvert.DeserializeObject<TidalConfig> (Encoding.UTF8.GetString (Shared.IO.FileUtils.ReadFile (TidalConfig.FileName)));
|
if (tidal != null) {
|
var result = GetResult ("https://meta.airable.io/tidal/login?username=" + tidal.UserName + "&password=" + tidal.Passwrod);
|
var musics = Newtonsoft.Json.JsonConvert.DeserializeObject<Airable> (result);
|
if (musics.title != "TIDAL") {
|
return false;
|
}
|
CurrentTidal.IsLogin = true;
|
CurrentTidal.Save ();
|
return true;
|
}
|
|
} catch { }
|
|
return false;
|
}
|
|
public static void ReadPlayList (string path, Action gotoLoginActon, Action<string> gotoPageAction)
|
{
|
MainPage.Loading.Start (Language.StringByID (MyInternationalizationString.load));
|
System.Threading.Tasks.Task.Run (() => {
|
try {
|
var list = TempMusicInfoList.FindAll ((obj) => obj.Tag.ToString() == path);
|
if (list.Count != 0) {
|
return;
|
}
|
var result = GetResult ("https://meta.airable.io/"+path);
|
if (result == null) {
|
result = GetResult ("https://meta.airable.io/"+path);
|
if (result == null) {
|
return;
|
}
|
}
|
var tracks = Newtonsoft.Json.JsonConvert.DeserializeObject<Airable> (result);
|
//token过期,需要重新登录.
|
|
if (tracks.id != null) {
|
if (tracks.id [2].ToString () == "authorization") {
|
if (!Login ()) {
|
return;
|
}
|
}
|
}
|
|
foreach (var v in tracks.content.entries) {
|
var tidalMusicInfo = new MusicInfo () { Tag = path };
|
|
if (v.title != null) {
|
tidalMusicInfo.Title = v.title.Replace ("&", "");
|
}
|
|
if (v.url != null) {
|
tidalMusicInfo.ID = v.url.Replace ("https://meta.airable.io/", "");
|
}
|
if (v.id != null) {
|
tidalMusicInfo.IsDirectory = v.id [1].ToString () != "track";
|
}
|
|
if (v.album != null) {
|
tidalMusicInfo.Album = v.album.title.Replace ("&", "");
|
}
|
|
if (v.artist != null) {
|
tidalMusicInfo.Artist = v.artist.title.Replace ("&", "");
|
}
|
if (v.streams != null && 0 < v.streams.Length) {
|
tidalMusicInfo.URL = v.streams [0].url;
|
}
|
|
if (v.images != null) {
|
#region 初始化网络图片路径
|
string pathIm = "";
|
if (Shared.Application.IsPad) {
|
pathIm = "";
|
} else {
|
pathIm = "Phone/" + "MusicImage/";
|
}
|
pathIm = System.IO.Path.Combine (Shared.IO.FileUtils.RootPath, pathIm + v.images [0].url.Replace ('/', '_').Replace ('\\', '_').Replace (':', '_').Replace ('*', '_').Replace ('?', '_').Replace ('"', '_').Replace ('<', '_').Replace ('>', '_').Replace ('|', '_'));
|
tidalMusicInfo.Image = pathIm;
|
#endregion
|
Shared.IO.FileUtils.DownLoadImage (tidalMusicInfo.Image, v.images [0].url);
|
}
|
if (!tidalMusicInfo.IsDirectory && tidalMusicInfo.URL == null) {
|
} else {
|
TempMusicInfoList.Add (tidalMusicInfo);
|
}
|
}
|
|
} catch { } finally {
|
if (gotoPageAction != null) {
|
gotoPageAction (path);
|
}
|
}
|
});
|
}
|
|
}
|
}
|