iPhone在线音乐盒,代码开源
作者 wz88510731
原帖地址 http://www.cocoachina.com/bbs/read.php?tid-14547.html
因为被AppStore魂牵梦绕的,所以去年12月30号斥资xx大洋买了一台macbook,立刻投入到了神奇的objective-c世界中了。
在 没有任何c语言基础的情况摸索着前进,到目前已经差不多理解了一些重要概念,比如类,NSxx,内存管理,继承,间接。自认为我的学习速度还是挺快的,不 过毕竟是有object pascal的基础支撑。所以学起来并不是很吃力。
本 来是想做一个类似于酷狗的iphone平台的音乐软件的,不过在昨 天晚上正式宣布放弃了。原因是一、我的技术还不够成熟,在线播放总不够完美(也许和我的性格有关,追求完美吧)。二、最重要是我认为自己高估了这产品的市 场前景。三、我有了更好的创意。所以呢,这个半成品就开源出来了。花了5个晚上外加一个周末的时间吧。其实没什么技术含量,相对来说,有点“技术”含量的 也就是三个函数了,用来从百度的搜索引擎页面中抓取信息,和解密百度的mp3地址编码。写的仓促了,毕竟初三了不能有很多时间来编程了,家里总是有意见, 唉唉。主要也是因为我文化课上的精力放的太少了。今天刚考完期末考试,虽然自我感觉不错,但是通常情况下,就见鬼的是,结果都超出我的自我感觉的。当然是 负面超出了。
/* Function For 百度 mp3 搜索模块 */
/*
请求百度mp3搜索页面获得歌曲信息数组
by BinJian.Wong on Sleeplez.com
update on 2010.2.1
mykeyWords = 关键字
pageNavi = 歌曲条目从pageNavi起
*/
+ ( NSArray * ) KeyWordsForSongs: ( NSString * ) myKeyWords pageNavi: ( int ) myPageNavi;
/*
解密百度mp3链接加密算法
by BinJian.Wong on Sleeplez.com
update on 2010.2.1
myEncodeURL = 经过加密的链接
*/
+ ( NSString * ) decodeBaiduURL: ( NSString * ) myEncodeURL;
/*
从百度下载页面中获得经过加密的下载链接
by BinJian.Wong on Sleeplez.com
update on 2010.2.1
myDownpage = 下载页面的链接地址
*/
+ ( NSString * ) DownPageURLToMusicFileURL: ( NSString * ) myDownpage;
// .m
[/pre]+ ( NSArray * ) KeyWordsForSongs: ( NSString * ) myKeyWords pageNavi: ( int ) myPageNavi{
int pageNavi = myPageNavi; //页码
NSString * keyWords = myKeyWords; //关键字
//NSString * keyWords = @"张信哲";
//创建字符串
NSString * myURL = [ NSString stringWithFormat: @ "http://mp3.baidu.com/m?f=ms&rf=idx&tn=baidump3&ct=134217728&lf=&rn=&word=%@&lm=0&pn=%d" ,keyWords,pageNavi] ;
//UTF8 to gb2312
myURL = [ myURL stringByAddingPercentEscapesUsingEncoding: CFStringConvertEncodingToNSStringEncoding( kCFStringEncodingGB_18030_2000) ] ;
NSLog( @ "%@" ,myURL) ;
ASIHTTPRequest * myRequest = [ [ [ ASIHTTPRequest alloc] initWithURL: [ NSURL URLWithString: myURL] ] autorelease] ;
[ myRequest startSynchronous] ;
//如果发生错误,返回nil
if ( [ myRequest error] ) return nil ;
//返回数组定义
NSMutableArray * mySongs = [ NSMutableArray arrayWithCapacity: 15 ] ;
//编码转换 gb2313 to UTF
NSData * myResponseData = [ myRequest responseData] ;
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingGB_18030_2000) ;
NSString * myResponseStr = [ [ NSString alloc] initWithData: myResponseData encoding: enc] ;
//NSLog(@"html=%@",myResponseStr);
//如果百度告诉我没有找到?
NSRange myRange;
myRange = [ myResponseStr rangeOfString: @ "抱歉,没有找到与" ] ;
if ( myRange.location != NSNotFound) {
return nil ;
} ;
//将 源代码按 ” <td class=d><a href= “ 切割
NSMutableArray * myResponseArrForSinger = ( NSMutableArray * ) [ myResponseStr componentsSeparatedByString: @ "<td class=d><a href=" ] ;
//去头去尾
if ( [ myResponseArrForSinger count] >= 2 ) {
[ myResponseArrForSinger removeObjectAtIndex: 0 ] ;
[ myResponseArrForSinger removeObjectAtIndex: [ myResponseArrForSinger count] - 1 ] ;
}
//按段处理
for ( int i= 0 ; i<[ myResponseArrForSinger count] ; i++ ) {
//
@try {
//把段按 “ .html" target="_blank"> ” 切割
NSMutableArray * mySubArr = ( NSMutableArray * ) [ [ myResponseArrForSinger objectAtIndex: i] componentsSeparatedByString: @ ".html/" target=/" _blank/" >" ] ;
//处理歌曲下载页面的URL
NSArray * myURLTmpArr = [ [ mySubArr objectAtIndex: 0 ] componentsSeparatedByString: @ "/" title=/" 请点击左键!来源网址: " ] ;
myURLTmpArr = [ [ mySubArr objectAtIndex: 0 ] componentsSeparatedByString: @ "/" " ] ;
NSMutableString * SongsURL = [ myURLTmpArr objectAtIndex: 1 ] ;
//[SongsURL stringByAddingPercentEscapesUsingEncoding:enc];
//NSLog(@"url= %@",SongsURL);
for ( int j= 0 ; j<[ mySubArr count] ; j++ ) {
NSLog( @ "%d= %@" ,j,[ mySubArr objectAtIndex: j] ) ;
}
//如果只有一段,表示 无 歌手名 和 专辑名
//if ([mySubArr count]<=1) {
//NSLog()
//常量定义 段的意义
const int Const_Songs = 0 ;
const int Const_Singer = 1 ;
const int Const_Album = 4 ;
//变量定义
NSMutableString * SongsName = ( NSMutableString * ) @ "" ;
NSString * SongsSinger = @ "" ;
NSString * SongsAlbum = @ "" ;
NSString * SongsSpeed = @ "" ;
NSString * SongsSize = @ "" ;
//处理 歌曲大小
NSMutableArray * mySizeArr = ( NSMutableArray * ) [ [ mySubArr objectAtIndex: ( [ mySubArr count] - 1 ) ] componentsSeparatedByString: @ "<td>" ] ;
if ( [ mySizeArr count] >= 2 ) {
SongsSize = [ mySizeArr objectAtIndex: ( [ mySizeArr count] - 2 ) ] ;
NSLog( @ "size = %@" ,SongsSize) ;
} ;
//处理 歌曲链接速度图片
@try {
if ( [ mySubArr count] >= 3 ) {
if ( [ mySubArr objectAtIndex: ( [ mySubArr count] - 1 ) ] != nil ) {
NSMutableArray * mySpeedArr = ( NSMutableArray * ) [ [ mySubArr objectAtIndex: ( [ mySubArr count] - 1 ) ] componentsSeparatedByString: @ "<td class=spd><img src=/" http://img.baidu.com/img/mp3/" ] ;
if ( [ mySpeedArr count] >0 )
if ( [ mySpeedArr objectAtIndex: 1 ] != nil )
mySpeedArr = ( NSMutableArray * ) [ [ mySpeedArr objectAtIndex: 1 ] componentsSeparatedByString: @ "/" ></td>" ] ;
if ( [ mySpeedArr objectAtIndex: 0 ] != nil )
SongsSpeed = [ mySpeedArr objectAtIndex: 0 ] ;
NSLog( @ "test speed = %@" ,SongsSpeed) ;
}
} ;
}
@catch ( NSException * e) {
//none
}
@finally {
//none
}
//处理 歌曲名
NSMutableArray * myTmpArr = ( NSMutableArray * ) [ [ mySubArr objectAtIndex: Const_Songs] componentsSeparatedByString: @ "/" return ow(event,this)/" target=/" _blank/" >" ] ;
myTmpArr = ( NSMutableArray * ) [ [ myTmpArr objectAtIndex: 1 ] componentsSeparatedByString: @ "</a></td>" ] ;
SongsName = [ myTmpArr objectAtIndex: 0 ] ;
NSString * mySubStr;
//处理 歌手名
if ( [ mySubArr count] >1 ) {
mySubStr = [ mySubArr objectAtIndex: Const_Singer] ;
SongsSinger = mySubStr;
} ;
//处理 专辑名
if ( [ mySubArr count] >= 5 ) {
mySubStr = [ mySubArr objectAtIndex: Const_Album] ;
NSMutableArray * mySubSubArr = ( NSMutableArray * ) [ mySubStr componentsSeparatedByString: @ "</a>" ] ;
mySubStr = [ mySubSubArr objectAtIndex: 0 ] ;
SongsAlbum = mySubStr;
} else {
SongsAlbum = @ "" ;
} ;
//处理: 歌曲名中如果包含歌词
NSMutableString * tmp = [ NSMutableString stringWithString: SongsName] ;
NSRange range = [ tmp rangeOfString: @ "<br><font color=/" #999999/" class=f10>" ] ;
if ( range.location != NSNotFound) {
range.length = SongsName.length - range.location;
//NSLog(@"%d !",range.length);
[ tmp deleteCharactersInRange: range] ;
//NSLog(@"test =%@",tmp);
SongsName = tmp;
}
//[tmp release];
//NSLog(@"t= %@, %@ , %@",SongsName,SongsSinger,SongsAlbum);
//好,现在开始发春了!
NSString * FinalStr = [ [ [ NSString alloc] initWithFormat: @ "<头>%@<分割>%@<分 割>%@<分割>%@<分割>%@<分割>%@" ,
SongsName,SongsSinger,SongsAlbum,SongsURL,SongsSpeed,SongsSize] autorelease] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "<font color=/" #c60a00/" >" withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "</font>" withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "</a>" withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "<a href=/" http://mp3.baidu.com/singerlist/" withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ " " withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "'" withString: @ "'" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "<头> " withString: @ "<头>" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "<头>" withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "&" withString: @ "&" ] ;
FinalStr = [ FinalStr stringByReplacingOccurrencesOfString: @ "</td>" withString: @ "" ] ;
FinalStr = [ FinalStr stringByReplacingPercentEscapesUsingEncoding: enc] ;
//if ([SongsURL hasSuffix:@"3"]) {
[ mySongs addObject: FinalStr] ;
//};
//]
}
@catch ( NSException * e) {
// 没有错误处理, 发生错误就直接丢掉
}
@finally {
// none
}
} ;
[ myResponseStr release] ;
return ( NSArray * ) mySongs;
}
+ ( NSString * ) decodeBaiduURL: ( NSString * ) myEncodeURL{
//我没学过c,没学过c,没学过c,写的太臃肿,太sb了,别骂我呀。
NSString * returnURL = [ [ [ NSString alloc] initWithFormat: @ "" ] autorelease] ;
//char *myCEncodeURL = [myEncodeURL cStringcStringWithEncoding:NSASCIIStringEncoding];
NSLog( @ "input %@" ,myEncodeURL) ;
//字串
static NSString * myConst = @ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ;
int pyl ; // 偏移量
//NSRange myRange = [myEncodeURL rangeOfString:@":"]; //定位 协议标识符
UniChar myUniChr = [ myEncodeURL characterAtIndex: 0 ] ; //取出第一字符
//转换类型
NSString * myChrAsStr = [ [ [ NSString alloc] initWithFormat: @ "%C" ,myUniChr] autorelease] ;
//确定第一字符在字串中的位置
NSRange myRange2 = [ myConst rangeOfString: myChrAsStr] ;
int myFirstChrLocation = myRange2.location;
//计算偏移量
pyl = myFirstChrLocation - 33 ;
// 33 means "h" 's location .
NSLog( @ "len = %d" ,myEncodeURL.length) ;
//还原字串
//NSLog(@"pyl = %d",pyl);
for ( int i= 0 ; i<[ myEncodeURL length] ; i++ ) {
UniChar myTmpChr= [ myEncodeURL characterAtIndex: i] ;
NSString * myTmpChrAsStr = [ [ [ NSString alloc] initWithFormat: @ "%C" ,myTmpChr] autorelease] ;
NSRange myTmpRange = [ myConst rangeOfString: myTmpChrAsStr] ;
if ( myTmpRange.location != NSNotFound) {
int newChrAsInt = myTmpRange.location - pyl;
//NSLog(@"pyl = %d , oldchr = %C , oldcount = %d, newcount = %d",pyl,myTmpChr,
//hai myTmpRange.location,newChrAsInt);
if ( newChrAsInt<0 ) {
newChrAsInt = newChrAsInt + 62 ;
//NSLog(@"%d",newChrAsInt);
} else {
if ( newChrAsInt>62 ) {
newChrAsInt = newChrAsInt % 62 ;
} ;
}
/// NSLog(@"! pyl = %d , oldchr = %C , oldcount = %d, newcount = %d",pyl,myTmpChr,
// myTmpRange.location,newChrAsInt);
myTmpChr = [ myConst characterAtIndex: newChrAsInt] ;
} ;
//NSLog(@"%C",myTmpChr);
returnURL= [ returnURL stringByAppendingFormat: @ "%C" ,myTmpChr] ;
}
returnURL= [ returnURL stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding] ;
NSLog( @ "output %@" ,returnURL) ;
return returnURL;
}
+ ( NSString * ) DownPageURLToMusicFileURL: ( NSString * ) myDownpage{
NSURL * myURL = [ NSURL URLWithString: myDownpage] ;
ASIHTTPRequest * myRequest = [ [ [ ASIHTTPRequest alloc] initWithURL: myURL] autorelease] ;
[ myRequest startSynchronous] ;
NSData * myResponseData = [ myRequest responseData] ;
NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding ( kCFStringEncodingGB_18030_2000) ;
NSString * myResponseStr = [ [ NSString alloc] initWithData: myResponseData encoding: enc] ;
//NSLog(@"resstr= %@", myResponseStr);
NSArray * myArr = [ myResponseStr componentsSeparatedByString: @ "var encurl = /" " ] ;
myArr = [ [ myArr objectAtIndex: 1 ] componentsSeparatedByString: @ "/" , newurl = /" /" ;" ] ;
[ myResponseStr release] ;
return [ self decodeBaiduURL: [ myArr objectAtIndex: 0 ] ] ;