Skip to content

Instantly share code, notes, and snippets.

@edward-hsu-1994
Last active August 29, 2015 14:15
Show Gist options
  • Save edward-hsu-1994/148bc35d52c45059fde7 to your computer and use it in GitHub Desktop.
Save edward-hsu-1994/148bc35d52c45059fde7 to your computer and use it in GitHub Desktop.
取得Xuite隨意窩影音的真實位址與其他資訊
/*
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