hyzp_ybqx-Commit001:代码刚转换好,编译通过
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// SPPlayCGIParser.h
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/26.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SPPlayCGIParserProtocol.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SPPlayCGIParser : NSObject
|
||||
+ (Class<SPPlayCGIParserProtocol>)parserOfVersion:(NSInteger)version;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// SPPlayCGIParser.m
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/26.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SPPlayCGIParser.h"
|
||||
#import "SPPlayCGIParser_V2.h"
|
||||
#import "SPPlayCGIParser_V4.h"
|
||||
|
||||
@implementation SPPlayCGIParser
|
||||
+ (Class<SPPlayCGIParserProtocol>)parserOfVersion:(NSInteger)version {
|
||||
if (version == 2) {
|
||||
return [SPPlayCGIParser_V2 class];
|
||||
} else if (version == 4) {
|
||||
return [SPPlayCGIParser_V4 class];
|
||||
}
|
||||
return Nil;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// PlayCGIParserProtocol.h
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/25.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SPPlayCGIParseResult.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol SPPlayCGIParserProtocol <NSObject>
|
||||
+ (SPPlayCGIParseResult *)parseResponse:(NSDictionary *)jsonResp;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// SPPlayCGIParser_V2.h
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/25.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SPPlayCGIParserProtocol.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SPPlayCGIParser_V2 : NSObject <SPPlayCGIParserProtocol>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,105 @@
|
||||
//
|
||||
// SPPlayCGIParser_V2.m
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/25.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SPPlayCGIParser_V2.h"
|
||||
#import "J2Obj.h"
|
||||
#import "SuperPlayerUrl.h"
|
||||
#import "TXBitrateItemHelper.h"
|
||||
#import "TXImageSprite.h"
|
||||
|
||||
@implementation SPPlayCGIParser_V2
|
||||
+ (SPPlayCGIParseResult *)parseResponse:(NSDictionary *)responseObject {
|
||||
SPPlayCGIParseResult *ret = [[SPPlayCGIParseResult alloc] init];
|
||||
NSString *masterUrl = J2Str([responseObject valueForKeyPath:@"videoInfo.masterPlayList.url"]);
|
||||
// masterUrl = nil;
|
||||
if (masterUrl.length > 0) {
|
||||
// 1. 如果有master url,优先用这个
|
||||
ret.url = masterUrl;
|
||||
} else {
|
||||
NSString *mainDefinition = J2Str([responseObject valueForKeyPath:@"playerInfo.defaultVideoClassification"]);
|
||||
|
||||
NSArray *videoClassification = J2Array([responseObject valueForKeyPath:@"playerInfo.videoClassification"]);
|
||||
NSArray *transcodeList = J2Array([responseObject valueForKeyPath:@"videoInfo.transcodeList"]);
|
||||
|
||||
NSMutableArray<SuperPlayerUrl *> *result = [NSMutableArray new];
|
||||
|
||||
// 2. 如果有转码的清晰度,用转码流
|
||||
for (NSDictionary *transcode in transcodeList) {
|
||||
SuperPlayerUrl *subModel = [SuperPlayerUrl new];
|
||||
subModel.url = J2Str(transcode[@"url"]);
|
||||
NSNumber *theDefinition = J2Num(transcode[@"definition"]);
|
||||
|
||||
for (NSDictionary *definition in videoClassification) {
|
||||
for (NSObject *definition2 in J2Array([definition valueForKeyPath:@"definitionList"])) {
|
||||
|
||||
if ([definition2 isEqual:theDefinition]) {
|
||||
subModel.title = J2Str([definition valueForKeyPath:@"name"]);
|
||||
NSString *definitionId = J2Str([definition valueForKeyPath:@"id"]);
|
||||
// 初始播放清晰度
|
||||
if ([definitionId isEqualToString:mainDefinition]) {
|
||||
if (![ret.url containsString:@".mp4"])
|
||||
ret.url = subModel.url;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 同一个清晰度可能存在多个转码格式,这里只保留一种格式,且优先mp4类型
|
||||
for (SuperPlayerUrl *item in result) {
|
||||
if ([item.title isEqual:subModel.title]) {
|
||||
if (![item.url containsString:@".mp4"]) {
|
||||
item.url = subModel.url;
|
||||
}
|
||||
subModel = nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (subModel) {
|
||||
[result addObject:subModel];
|
||||
}
|
||||
}
|
||||
ret.multiVideoURLs = result;
|
||||
}
|
||||
// 3. 以上都没有,用原始地址
|
||||
if (ret.url == nil) {
|
||||
NSString *source = J2Str([responseObject valueForKeyPath:@"videoInfo.sourceVideo.url"]);
|
||||
ret.url = source;
|
||||
}
|
||||
|
||||
NSArray *imageSprites = J2Array([responseObject valueForKeyPath:@"imageSpriteInfo.imageSpriteList"]);
|
||||
if (imageSprites.count > 0) {
|
||||
// id imageSpriteObj = imageSprites[0];
|
||||
id imageSpriteObj = imageSprites.lastObject;
|
||||
NSString *vtt = J2Str([imageSpriteObj valueForKeyPath:@"webVttUrl"]);
|
||||
NSArray *imgUrls = J2Array([imageSpriteObj valueForKeyPath:@"imageUrls"]);
|
||||
NSMutableArray *imgUrlArray = @[].mutableCopy;
|
||||
for (NSString *url in imgUrls) {
|
||||
NSURL *nsurl = [NSURL URLWithString:url];
|
||||
if (nsurl) {
|
||||
[imgUrlArray addObject:nsurl];
|
||||
}
|
||||
}
|
||||
|
||||
TXImageSprite *imageSprite = [[TXImageSprite alloc] init];
|
||||
[imageSprite setVTTUrl:[NSURL URLWithString:vtt] imageUrls:imgUrlArray];
|
||||
ret.imageSprite = imageSprite;
|
||||
}
|
||||
|
||||
NSArray *keyFrameDescList = J2Array([responseObject valueForKeyPath:@"keyFrameDescInfo.keyFrameDescList"]);
|
||||
if (keyFrameDescList.count > 0) {
|
||||
NSMutableArray<SPVideoFrameDescription *> *checkPoints = [[NSMutableArray alloc] initWithCapacity:keyFrameDescList.count];
|
||||
for (NSDictionary *info in keyFrameDescList) {
|
||||
SPVideoFrameDescription *checkPoint = [SPVideoFrameDescription instanceFromDictionary:info];
|
||||
[checkPoints addObject:checkPoint];
|
||||
}
|
||||
ret.keyFrameDescList = checkPoints;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// PlayCGIV4Parser.h
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/25.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SPPlayCGIParserProtocol.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface SPPlayCGIParser_V4 : NSObject <SPPlayCGIParserProtocol>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,122 @@
|
||||
//
|
||||
// PlayCGIV4Parser.m
|
||||
// SuperPlayer
|
||||
//
|
||||
// Created by cui on 2019/12/25.
|
||||
// Copyright © 2019 annidy. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SPPlayCGIParser_V4.h"
|
||||
//#import "SPResolutionDefination.h"
|
||||
#import "SPSubStreamInfo.h"
|
||||
#import "AdaptiveStream.h"
|
||||
#import "TXImageSprite.h"
|
||||
#import "J2Obj.h"
|
||||
|
||||
@implementation SPPlayCGIParser_V4
|
||||
|
||||
+ (SPPlayCGIParseResult *)parseResponse:(NSDictionary *)jsonResp {
|
||||
SPPlayCGIParseResult *ret = [[SPPlayCGIParseResult alloc] init];
|
||||
|
||||
// 获取媒体信息
|
||||
NSDictionary *media = jsonResp[@"media"];
|
||||
if ([media isKindOfClass:[NSDictionary class]]) {
|
||||
do {
|
||||
//解析视频名称
|
||||
ret.name = [media valueForKeyPath:@"basicInfo.name"];
|
||||
NSDictionary *streamInfo = [media valueForKeyPath:@"streamingInfo.plainOutput"];
|
||||
if (streamInfo == nil) {
|
||||
NSArray* drmOutputs = [media valueForKeyPath:@"streamingInfo.drmOutput"];
|
||||
for (NSDictionary *drmOutput in drmOutputs) {
|
||||
SPDrmType type = [SPPlayCGIParseResult drmTypeFromString:J2Str(drmOutput[@"type"])];
|
||||
if (type == SPDrmTypeSimpleAES) {
|
||||
streamInfo = drmOutput;
|
||||
ret.drmType = SPDrmTypeSimpleAES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret.drmToken = [media valueForKeyPath:@"streamingInfo.drmToken"];
|
||||
}
|
||||
if (streamInfo == nil) {
|
||||
return nil;
|
||||
}
|
||||
NSNumber *duration = [media valueForKeyPath:@"basicInfo.duration"];
|
||||
if ([duration isKindOfClass:[NSNumber class]]) {
|
||||
ret.originalDuration = duration.doubleValue;
|
||||
}
|
||||
// 解析分辨率名称
|
||||
NSArray *subStreamDictArray = J2Array(streamInfo[@"subStreams"]);
|
||||
NSMutableArray *subStreamInfoArray = [NSMutableArray arrayWithCapacity:subStreamDictArray.count];
|
||||
for (NSDictionary *resInfo in subStreamDictArray) {
|
||||
SuperPlayerUrl *url = [[SuperPlayerUrl alloc] init];
|
||||
url.title = J2Str(resInfo[@"resolutionName"]);
|
||||
// SPSubStreamInfo *info = [SPSubStreamInfo infoWithDictionary:resInfo];
|
||||
[subStreamInfoArray addObject:url];
|
||||
}
|
||||
ret.multiVideoURLs = subStreamInfoArray;
|
||||
|
||||
//解析视频播放url
|
||||
NSString *url = streamInfo[@"url"];
|
||||
if ([url isKindOfClass:[NSString class]] && url.length > 0) {
|
||||
//未加密直接解析出视频url
|
||||
ret.url = url;
|
||||
} else {
|
||||
//有加密,url为空,则解析drm加密的url信息
|
||||
NSArray *urlArray = streamInfo[@"drmUrls"];
|
||||
if ([urlArray isKindOfClass:[NSArray class]] &&
|
||||
urlArray.count > 0) {
|
||||
NSMutableArray *drmURLArray = [NSMutableArray arrayWithCapacity:urlArray.count];
|
||||
for (NSDictionary *dict in urlArray) {
|
||||
if ([dict isKindOfClass:[NSDictionary class]]) {
|
||||
continue;
|
||||
}
|
||||
AdaptiveStream *stream = [[AdaptiveStream alloc] init];
|
||||
stream.url = dict[@"url"];
|
||||
stream.drmType = dict[@"type"];
|
||||
[drmURLArray addObject:stream];
|
||||
}
|
||||
ret.adaptiveStreamArray = drmURLArray;
|
||||
}
|
||||
}
|
||||
|
||||
//解析略缩图信息
|
||||
NSDictionary *imageSpriteInfo = media[@"imageSpriteInfo"];
|
||||
|
||||
if ([imageSpriteInfo isKindOfClass:[NSDictionary class]]) {
|
||||
NSString *vttURLString = J2Str(imageSpriteInfo[@"webVttUrl"]);
|
||||
NSURL *vttURL = [NSURL URLWithString:vttURLString];
|
||||
NSArray *imageURLStrings = J2Array(imageSpriteInfo[@"imageUrls"]);
|
||||
NSMutableArray<NSURL *> *imageURLs = [NSMutableArray arrayWithCapacity:imageURLStrings.count];
|
||||
for (NSString *urlString in imageURLStrings) {
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
if (url) {
|
||||
[imageURLs addObject:url];
|
||||
}
|
||||
}
|
||||
TXImageSprite *sprite = [[TXImageSprite alloc] init];
|
||||
[sprite setVTTUrl:vttURL imageUrls:imageURLs];
|
||||
ret.imageSprite = sprite;
|
||||
}
|
||||
|
||||
//解析关键帧信息
|
||||
NSDictionary *keyFrameDescInfo = media[@"keyFrameDescInfo"];
|
||||
if ([keyFrameDescInfo isKindOfClass:[NSDictionary class]]) {
|
||||
NSArray *keyFrameDescList = keyFrameDescInfo[@"keyFrameDescList"];
|
||||
if ([keyFrameDescList isKindOfClass:[NSArray class]] &&
|
||||
keyFrameDescList.count > 0) {
|
||||
NSMutableArray<SPVideoFrameDescription *> *videoPoints = [NSMutableArray array];
|
||||
for (NSDictionary *jsonObject in keyFrameDescList) {
|
||||
SPVideoFrameDescription *point = [SPVideoFrameDescription instanceFromDictionary:jsonObject];
|
||||
if (point) {
|
||||
[videoPoints addObject:point];
|
||||
}
|
||||
}
|
||||
ret.keyFrameDescList = videoPoints;
|
||||
}
|
||||
}
|
||||
} while (0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user