Skip to content

Commit

Permalink
update api
Browse files Browse the repository at this point in the history
Change-Id: I2d8c203d0c6d35401ac12e3f759adb1e1cf7dcfa
  • Loading branch information
Grayon committed Mar 1, 2019
1 parent 33d093f commit 012ce92
Show file tree
Hide file tree
Showing 11 changed files with 6,163 additions and 124 deletions.
4 changes: 4 additions & 0 deletions Douyu.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
B05DB3722170862400B640AB /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D2C083921F765BC400CF286F /* OpenGL.framework */; };
B0735FC0216DD3A90087F28E /* libmpv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B0735FBF216DD3A90087F28E /* libmpv.dylib */; };
B0735FC1216DD3E00087F28E /* libicucore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D21DB33D1F74E7B400A5E5B1 /* libicucore.tbd */; };
B08B80C62228F5BE0015860E /* crypto-js.js in Resources */ = {isa = PBXBuildFile; fileRef = B08B80C52228F5BE0015860E /* crypto-js.js */; };
D213B2761FECAA17009F5123 /* DYRoomHistoryData.m in Sources */ = {isa = PBXBuildFile; fileRef = D213B2751FECAA17009F5123 /* DYRoomHistoryData.m */; };
D213B2791FECB9A8009F5123 /* DYRoomHistoryModel.m in Sources */ = {isa = PBXBuildFile; fileRef = D213B2781FECB9A8009F5123 /* DYRoomHistoryModel.m */; };
D21DB3301F74E53D00A5E5B1 /* DYDanmuProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = D21DB31D1F74A46300A5E5B1 /* DYDanmuProvider.m */; };
Expand Down Expand Up @@ -56,6 +57,7 @@
51D249B87DE465548D9F4F6F /* Pods-Douyu.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Douyu.release.xcconfig"; path = "Pods/Target Support Files/Pods-Douyu/Pods-Douyu.release.xcconfig"; sourceTree = "<group>"; };
93F4F262717B4A242D283804 /* libPods-Douyu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Douyu.a"; sourceTree = BUILT_PRODUCTS_DIR; };
B0735FBF216DD3A90087F28E /* libmpv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libmpv.dylib; path = ../../../../usr/local/lib/libmpv.dylib; sourceTree = DEVELOPER_DIR; };
B08B80C52228F5BE0015860E /* crypto-js.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "crypto-js.js"; sourceTree = "<group>"; };
D213B2741FECAA17009F5123 /* DYRoomHistoryData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DYRoomHistoryData.h; sourceTree = "<group>"; };
D213B2751FECAA17009F5123 /* DYRoomHistoryData.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DYRoomHistoryData.m; sourceTree = "<group>"; };
D213B2771FECB9A8009F5123 /* DYRoomHistoryModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DYRoomHistoryModel.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -262,6 +264,7 @@
D2B876451F73886900AE844E /* Resources */ = {
isa = PBXGroup;
children = (
B08B80C52228F5BE0015860E /* crypto-js.js */,
D2B876461F73886900AE844E /* img */,
);
path = Resources;
Expand Down Expand Up @@ -419,6 +422,7 @@
files = (
D2B876941F7389F400AE844E /* loading.gif in Resources */,
D2B8133D1F724D1C00EF526D /* Assets.xcassets in Resources */,
B08B80C62228F5BE0015860E /* crypto-js.js in Resources */,
D2B813401F724D1C00EF526D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
18 changes: 3 additions & 15 deletions Douyu/Model/DYDanmuProvider.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

@interface DYDanmuProvider ()

@property (nonatomic, strong) AuthSocket *authSocket;
@property (nonatomic, strong) DanmuSocket *danmuSocket;

@end
Expand All @@ -22,20 +21,10 @@ @interface DYDanmuProvider ()
@implementation DYDanmuProvider

- (void)loadWithInfo:(DYRoomInfo *)roomInfo {
_authSocket = [AuthSocket sharedInstance];
_authSocket.room = roomInfo.roomId;
_authSocket.servers = roomInfo.servers;
_danmuSocket = [DanmuSocket sharedInstance];
_danmuSocket.room = _authSocket.room;
//weak处理防止block循环
__weak DanmuSocket *danmuSocket = _danmuSocket;
_authSocket.InfoBlock = ^(NSString *vistorID,NSString *groupID){
danmuSocket.vistorID = vistorID;
danmuSocket.groupID = groupID;
[danmuSocket connectSocketHost];
};
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveMessageNotification:) name:@"kReceiveDYMessageNotification" object:nil];
[_authSocket connectSocketHost];
_danmuSocket = [DanmuSocket sharedInstance];
_danmuSocket.room = roomInfo.roomId;
[_danmuSocket connectSocketHost];
}

- (void)receiveMessageNotification:(NSNotification *)notification {
Expand Down Expand Up @@ -75,7 +64,6 @@ - (void)receiveMessageNotification:(NSNotification *)notification {
}

- (void)disconnect{
[_authSocket cutOffSocket];
[_danmuSocket cutOffSocket];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Expand Down
11 changes: 5 additions & 6 deletions Douyu/Model/DYRoomInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
@property (nonatomic, copy) NSString *roomId;
@property (nonatomic, copy) NSString *roomName;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, strong) NSArray *servers;
@property (nonatomic, copy) NSString *hlsUrl;
@property (nonatomic, copy) NSString *videoUrl;
@property (nonatomic, copy) NSString *lowVideoUrl;
@property (nonatomic, copy) NSString *middleVideoUrl;
@property (nonatomic, assign) BOOL showStatus;

+ (NSString *)getRoomIdWithString:(NSString *)string;
- (BOOL)getInfoWithRoomId:(NSString *)roomId;
@property (nonatomic, copy) NSString *did;
@property (nonatomic, copy) NSString *roomJS;

- (NSString *)getRoomIdWithString:(NSString *)string;
- (BOOL)getInfoWithRoomId:(NSString *)roomId rate:(int)rate;

@end
187 changes: 129 additions & 58 deletions Douyu/Model/DYRoomInfo.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,143 @@

#import "DYRoomInfo.h"
#import "NSString+InfoGet.h"
#import <JavaScriptCore/JavaScriptCore.h>

@implementation DYRoomInfo

+ (NSString *)getRoomIdWithString:(NSString *)string {
- (NSString *)getRoomIdWithString:(NSString *)string {
NSString *roomId = string;
if (![roomId isPureInt]) {
NSString *roomInfoUrl = [@"http://open.douyucdn.cn/api/RoomApi/room/" stringByAppendingString:roomId];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:roomInfoUrl]];
request.timeoutInterval = 5.0f;

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

__block NSData *roomData = nil;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
roomData = data;
}
dispatch_semaphore_signal(semaphore);
}];
[task resume];

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

if (!roomData) {
return nil;
}
NSDictionary *respDic = [NSJSONSerialization JSONObjectWithData:roomData options:0 error:nil];
if (!respDic || [respDic[@"error"] intValue] != 0) {
return nil;
NSString *roomInfoUrl = [@"http://open.douyucdn.cn/api/RoomApi/room/" stringByAppendingString:roomId];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:roomInfoUrl]];
request.timeoutInterval = 5.0f;

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

__block NSData *roomData = nil;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
roomData = data;
}
roomId = respDic[@"data"][@"room_id"];
dispatch_semaphore_signal(semaphore);
}];
[task resume];

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);

if (!roomData) {
return nil;
}
NSDictionary *respDic = [NSJSONSerialization JSONObjectWithData:roomData options:0 error:nil];
if (!respDic || ![respDic isKindOfClass:[NSDictionary class]] || [respDic[@"error"] intValue] != 0) {
return nil;
}
NSDictionary *roomDic = respDic[@"data"];
NSString *nickName = roomDic[@"owner_name"];
NSString *roomName = roomDic[@"room_name"];
roomId = roomDic[@"room_id"];
self.roomId = roomId;
self.roomName = roomName;
self.nickName = nickName;
self.showStatus = [roomDic[@"room_status"] intValue] == 1;
return roomId;
}

- (BOOL)getInfoWithRoomId:(NSString *)roomId {
NSString *API_SECRET = @"zNzMV1y4EMxOHS6I5WKm";
NSArray *cdns = @[@"ws", @"tct", @"ws2", @"dl"];
NSString *aid = @"wp";
int ts = [NSDate date].timeIntervalSince1970;
NSString *suffix = [NSString stringWithFormat:@"room/%@?aid=%@&cdn=%@&client_sys=%@&time=%d",roomId,aid,cdns[0],aid,ts];
NSString *sign = [[suffix stringByAppendingString:API_SECRET] getMd5_32Bit];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://capi.douyucdn.cn/api/v1/%@&auth=%@",suffix,sign]];
- (BOOL)getDouyuDid {
int random = arc4random() % 1000000;
NSString *callback = [NSString stringWithFormat:@"jsonp_%d", random];
NSString *didUrl = [NSString stringWithFormat:@"https://passport.douyu.com/lapi/did/api/get?client_id=1&callback=%@", callback];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:didUrl]];
request.timeoutInterval = 5.0f;
[request setValue:@"https://www.douyu.com" forHTTPHeaderField:@"Referer"];

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

__block NSData *respData = nil;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
respData = data;
}
dispatch_semaphore_signal(semaphore);
}];
[task resume];

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
NSString *resp = [[NSString alloc] initWithData:respData encoding:NSUTF8StringEncoding];
NSString *json = [[resp stringByReplacingOccurrencesOfString:callback withString:@""] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\n ()"]];
NSDictionary *respDic = [NSJSONSerialization JSONObjectWithData:[json dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
if (!respDic || ![respDic isKindOfClass:[NSDictionary class]] || [respDic[@"error"] intValue] != 0) {
return NO;
}
self.did = [respDic valueForKeyPath:@"data.did"];
return self.did == nil;
}

- (BOOL)getRoomJS:(NSString *)roomId {
NSString *roomJSURL = [NSString stringWithFormat:@"https://www.douyu.com/swf_api/homeH5Enc?rids=%@",roomId];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:roomJSURL]];
request.timeoutInterval = 5.0f;

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

__block NSData *roomData = nil;
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
roomData = data;
}
dispatch_semaphore_signal(semaphore);
}];
[task resume];

dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
NSDictionary *respDic = [NSJSONSerialization JSONObjectWithData:roomData options:0 error:nil];
if (!respDic || ![respDic isKindOfClass:[NSDictionary class]] || [respDic[@"error"] intValue] != 0) {
return NO;
}
self.roomJS = [respDic valueForKeyPath:[NSString stringWithFormat:@"data.room%@", roomId]];
return self.roomJS == nil;
}

- (BOOL)getInfoWithRoomId:(NSString *)roomId rate:(int)rate {
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[self getDouyuDid];
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[self getRoomJS:roomId];
});

dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

if (!self.did || !self.roomJS) {
return NO;
}

int time = NSDate.date.timeIntervalSince1970;
NSURL *cryptoJsFileURL = [[NSBundle mainBundle] URLForResource:@"crypto-js" withExtension:@"js"];
NSError *error;
NSString *cryptoJS = [NSString stringWithContentsOfURL:cryptoJsFileURL encoding:NSUTF8StringEncoding error:&error];
if (error) {
return NO;
}
JSContext *jsContext = [JSContext new];
[jsContext evaluateScript:cryptoJS];
[jsContext evaluateScript:@"var CryptoJS = require('crypto-js');"];
[jsContext evaluateScript:self.roomJS];

NSString *result = [jsContext evaluateScript:[NSString stringWithFormat:@"ub98484234(%@, '%@', %d)", roomId, self.did, time]].toString;
NSString *postString = [NSString stringWithFormat:@"%@&cdn=&rate=%d&ver=Douyu_219021902&iar=1&ive=0", result, rate];

NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://www.douyu.com/lapi/live/getH5Play/%@", roomId]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
request.timeoutInterval = 5.0f;

[request setValue:@"Mozilla/5.0 (iPad; CPU OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4" forHTTPHeaderField:@"User-Agent"];


request.HTTPMethod = @"POST";
request.HTTPBody = [postString dataUsingEncoding:NSUTF8StringEncoding];

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

__block NSData *roomData = nil;
Expand All @@ -74,33 +162,16 @@ - (BOOL)getInfoWithRoomId:(NSString *)roomId {
return NO;
}
NSDictionary *respDic = [NSJSONSerialization JSONObjectWithData:roomData options:0 error:nil];
if (!respDic || [respDic[@"error"] intValue] != 0) {
if (!respDic || ![respDic isKindOfClass:[NSDictionary class]] || [respDic[@"error"] intValue] != 0) {
return NO;
}
NSDictionary *roomDic = respDic[@"data"];
self.showStatus = YES;
if ([roomDic[@"show_status"] intValue] != 1) {
self.showStatus = NO;
// return YES;
}
NSString *nickName = roomDic[@"nickname"];
NSString *roomName = roomDic[@"room_name"];
NSArray *servers = roomDic[@"servers"];
NSDictionary *roomDic = respDic[@"data"];

NSString *rtmpPrefix = roomDic[@"rtmp_url"];
NSString *rtmpSuffix = roomDic[@"rtmp_live"];
NSString *videoUrl = [NSString stringWithFormat:@"%@/%@",rtmpPrefix,rtmpSuffix];
NSString *hlsUrl = roomDic[@"hls_url"];
if ([roomDic[@"rtmp_multi_bitrate"] isKindOfClass:[NSDictionary class]]) {
NSString *lowVideoUrl = [NSString stringWithFormat:@"%@/%@",rtmpPrefix,roomDic[@"rtmp_multi_bitrate"][@"middle"]];
NSString *middleVideoUrl = [NSString stringWithFormat:@"%@/%@",rtmpPrefix,roomDic[@"rtmp_multi_bitrate"][@"middle2"]];
self.lowVideoUrl = lowVideoUrl;
self.middleVideoUrl = middleVideoUrl;
}
self.roomId = roomId;
self.roomName = roomName;
self.nickName = nickName;
self.servers = servers;
self.hlsUrl = hlsUrl;

self.videoUrl = videoUrl;
return YES;
}
Expand Down
12 changes: 4 additions & 8 deletions Douyu/Model/socket/AuthSocket.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,10 @@ + (id)sharedInstance{

- (void)setServerConfig{
//转换成model,添加到属性
self.server = @[].mutableCopy;
for (int i = 0; i < _servers.count; i++) {
ServerModel *model = [ServerModel new];
NSDictionary *sevCfg = _servers[i];
model.ip = sevCfg[@"ip"];
model.port = [sevCfg[@"port"] intValue];
[self.server addObject:model];
}
ServerModel *model = [ServerModel new];
model.ip = @"openbarrage.douyutv.com";
model.port = 8601;
[self.server addObject:model];
}

#pragma marl --回调方法
Expand Down
7 changes: 3 additions & 4 deletions Douyu/Model/socket/DanmuSocket.m
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,10 @@ - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UIn
加入弹幕组
type@=joingroup/rid@=213116/gid@=1/
*/
NSString *danmuLogin = [NSString stringWithFormat:@"type@=loginreq/username@=%@/password@=1234567890123456/roomid@=%@/",self.vistorID,self.room];
NSData *postLoginData = [self packToData:danmuLogin];
NSString *loginreq = [NSString stringWithFormat:@"type@=loginreq/roomid@=%@/", self.room];
self.isFirstDate = YES;
[self.socket writeData:postLoginData withTimeout:30 tag:1];
[self.socket writeData:[self packToData:loginreq] withTimeout:30 tag:1];

}
//断开链接
- (void)onSocketDidDisconnect:(AsyncSocket *)sock{
Expand Down
2 changes: 1 addition & 1 deletion Douyu/Model/socket/SocketData.m
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ + (void)readDanmuMsg:(NSArray *)array{
if (!danmuSocket.connectTimer.isValid) {
if ([msg rangeOfString:@"type@=login"].location != NSNotFound) {
//加入弹幕组
NSString *jionGroup = [NSString stringWithFormat:@"type@=joingroup/rid@=%@/gid@=%@/",danmuSocket.room,@"-9999"];//danmuSocket.groupID
NSString *jionGroup = [NSString stringWithFormat:@"type@=joingroup/rid@=%@/gid@=%@/", danmuSocket.room, @"-9999"];//danmuSocket.groupID
NSData *jGroupData = [danmuSocket packToData:jionGroup];
[danmuSocket.socket writeData:jGroupData withTimeout:30 tag:1];
//开始发送心跳包
Expand Down
2 changes: 1 addition & 1 deletion Douyu/PlayerViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
@property (weak, nonatomic) IBOutlet MpvClientOGLView *glView;
@property (strong, nonatomic) BarrageRenderer *barrageRenderer;

- (void)loadPlayerWithInfo:(DYRoomInfo *)info withVideoQuality:(NSInteger)quality;
- (void)loadPlayerWithInfo:(DYRoomInfo *)info;
- (void)destroyPlayer;
@end
24 changes: 2 additions & 22 deletions Douyu/PlayerViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,34 +77,14 @@ void check_error(int status) {
}
}

- (void)loadPlayerWithInfo:(DYRoomInfo *)info withVideoQuality:(NSInteger)quality {
- (void)loadPlayerWithInfo:(DYRoomInfo *)info {
[self.loadingView setWantsLayer:YES];
[self.loadingView.layer setBackgroundColor:ColorFromRGBHex(0xecebeb, 1).CGColor];
self.roomInfo = info;
[self setTitle:[NSString stringWithFormat:@"%@%@)】%@",self.roomInfo.nickName,self.roomInfo.roomId,self.roomInfo.roomName]];
[self.view.window setTitle:self.title];
dispatch_async(dispatch_get_main_queue(), ^{
switch (quality) {
case 2:{
if (self.roomInfo.lowVideoUrl.length > 0) {
[self playVideo:self.roomInfo.lowVideoUrl];
break;
}
}
case 1:{
if (self.roomInfo.middleVideoUrl.length > 0) {
[self playVideo:self.roomInfo.middleVideoUrl];
break;
}
}
case 0:{
[self playVideo:self.roomInfo.videoUrl];
break;
}
default:
[self playVideo:self.roomInfo.videoUrl];
break;
}
[self playVideo:self.roomInfo.videoUrl];
[self loadDanmu];
});
}
Expand Down
Loading

0 comments on commit 012ce92

Please sign in to comment.