Last active
August 29, 2015 14:15
-
-
Save edward-hsu-1994/148bc35d52c45059fde7 to your computer and use it in GitHub Desktop.
取得Xuite隨意窩影音的真實位址與其他資訊
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Date:20141207 | |
BY XPY | |
程式碼僅供參考,引用請標示本頁網址 | |
*/ | |
using System; | |
using System.Linq; | |
using System.Text; | |
using System.Xml; | |
using System.Collections; | |
using System.Collections.Generic; | |
using Alex.Syntax;//額外的擴充,簡化寫法(String.InnerString、ArrayList.ToArray<Type>()) | |
using Alex.Data;//KeyValueCollection(可用Dictionary替代) | |
namespace Alex.Social.MediaGet.Parsers { | |
public class XuiteParser : Parser {//中華電信隨意窩影音剖析器 | |
public override MediaInfo[] GetMediaInfos(Uri Uri) { | |
if(!IsMatch(Uri))//檢查網址是否符合規範 | |
throw new UriNotMatchException(Uri);//如果不符合網址規範返回例外 | |
string ApiUrlString | |
= string.Format("http://vlog.xuite.net/flash/player?media={0}" | |
,Uri.EscapeDataString(GetMediaId(Uri)));//將ID帶入API網址且將ID轉換為百分比編碼 | |
KeyValueCollection Data = GetApiData(ApiUrlString);//取得媒體資料 | |
ArrayList result = new ArrayList();//結果回傳集合 | |
MediaType Type = ((string)Data["type"])=="audio" ? | |
MediaType.Audio : MediaType.Video;//判別型別是否為影片或音樂檔 | |
//建立屬性樣板 | |
KeyValueCollection Attributes = new KeyValueCollection();//其餘的媒體屬性資料集合 | |
Attributes.Add(Data.GetWithKey("author_name")); | |
Attributes.Add(Data.GetWithKey("thumb")); | |
Attributes.Add(Data.GetWithKey("category")); | |
Attributes.Add(Data.GetWithKey("duration")); | |
Attributes.Add(Data.GetWithKey("description")); | |
Attributes.AddWithValue("type",Type == MediaType.Video ? "mp4" : "mp3"); | |
if(Type == MediaType.Video) | |
Attributes.Add(Data.GetWithKey("size"));//如果為影片則有SIZE屬性 | |
if(Data.HasKey("src")) { | |
KeyValueCollection ItemAttr = Attributes.Clone();//複製屬性集合 | |
ItemAttr.AddWithValue("quality" ,"default");//SRC為預設品質 | |
MediaInfo Item = new MediaInfo() { | |
Name = Data["title"] as string , | |
Parser = ParserEnum.Xuite , | |
SourceUrl = Uri , | |
Type = Type , | |
RealUrl = new Uri[] { new Uri((string)Data["src"]) } , | |
Attributes = ItemAttr | |
}; | |
result.Add(Item);//加入結果 | |
} | |
if(Data.HasKey("hq_src")) {//有HQ | |
KeyValueCollection ItemAttr = Attributes.Clone();//複製屬性集合 | |
ItemAttr.AddWithValue("quality" ,"hq");//品質 | |
MediaInfo Item = new MediaInfo() { | |
Name = Data["title"] as string , | |
Parser = ParserEnum.Xuite , | |
SourceUrl = Uri , | |
Type = Type , | |
RealUrl = new Uri[] { new Uri((string)Data["hq_src"]) } , | |
Attributes = ItemAttr | |
}; | |
result.Add(Item);//加入結果 | |
} | |
if(Data.HasKey("hd1080_src")) {//有HD | |
KeyValueCollection ItemAttr = Attributes.Clone();//複製屬性集合 | |
ItemAttr.AddWithValue("quality" ,"hd1080");//品質 | |
MediaInfo Item = new MediaInfo() { | |
Name = Data["title"] as string , | |
Parser = ParserEnum.Xuite , | |
SourceUrl = Uri , | |
Type = Type , | |
RealUrl = new Uri[] { new Uri((string)Data["hd1080_src"]) } , | |
Attributes = ItemAttr | |
}; | |
result.Add(Item);//加入結果 | |
} | |
if(result.Count == 0) | |
throw new ParserException();//剖析失敗 | |
return result.ToArray<MediaInfo>();//轉回MediaInfo[] | |
} | |
//由網址取得媒體ID | |
private string GetMediaId(Uri Uri) { | |
string UndecodingId = Uri.Segments.Last<string>();//最後一個網址區間為XuiteID的BASE64型態 | |
try { | |
string DecodingId = DecodingStringFromBase64(UndecodingId);//呼叫解碼方法 | |
DecodingId = DecodingId.InnerString("-",".");//-與.之間才是媒體ID(數字碼) | |
DecodingId = EncodingBase64FromString(DecodingId);//將ID數字轉換為BASE64 | |
return DecodingId; | |
} catch { | |
throw new UriNotMatchException(Uri);//如果不能做Base64解碼,表示網址有問題 | |
} | |
} | |
//將BASE64的字串還原回普通字串資料 | |
private string DecodingStringFromBase64(string Data) { | |
byte[] Base64ByteArray = Convert.FromBase64String(Data);//將BASE64字串轉換為Byte陣列 | |
return Encoding.UTF8.GetString(Base64ByteArray);//預設使用UTF8 | |
} | |
//將字串轉為BASE64字串 | |
private string EncodingBase64FromString(string Data) { | |
byte[] ByteArray = Encoding.UTF8.GetBytes(Data);//將字串轉換為Byte陣列 | |
return Convert.ToBase64String(ByteArray);//轉換為BASE64字串 | |
} | |
private KeyValueCollection GetApiData(string ApiUrlString) { | |
XmlDocument ApiResult = new XmlDocument(); | |
ApiResult.Load(ApiUrlString);//讀取API回傳結果 | |
XmlNodeList Properties = ApiResult.SelectNodes("//property");//取得屬性節點集合 | |
KeyValueCollection Data = new KeyValueCollection(); | |
foreach(XmlNode Property in Properties) {//迴圈讀取所有屬性節點資料 | |
string PropertyName = DecodingStringFromBase64(Property.Attributes["id"].Value); | |
//取得屬性的名稱 | |
string PropertyValue = Uri.UnescapeDataString(DecodingStringFromBase64(Property.InnerText)); | |
//取得屬性的值 | |
if(string.IsNullOrWhiteSpace(PropertyValue)) | |
continue; | |
//如果為空字串則該屬性不用加入值組物件中 | |
Data.AddWithValue(PropertyName ,PropertyValue);//加入值組物件 | |
} | |
return Data;//回傳 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment