// // RAYTPlayer.m // iSales-UWAVER // // Created by Rui Zhang on 11/26/19. // Copyright © 2019 United Software Applications, Inc. All rights reserved. // #import "RAYTPlayer.h" #import "const.h" #import "RAUtils.h" @interface RAYTPlayer () @end @implementation RAYTPlayer - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { [self initWKWebView]; [self initMessageHandler]; } return self; } - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self initWKWebView]; [self initMessageHandler]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; self.wkwebView.frame = self.bounds; } -(void) initWKWebView { WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; WKPreferences *preferences = [WKPreferences new]; preferences.javaScriptCanOpenWindowsAutomatically = false; // preferences.minimumFontSize = 40.0; configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll; configuration.allowsInlineMediaPlayback = true; configuration.allowsPictureInPictureMediaPlayback=false; configuration.preferences = preferences; _wkwebView = [[WKWebView alloc] initWithFrame:self.bounds configuration:configuration]; self.wkwebView.hidden=YES; // self.wkwebView.UIDelegate = self; self.wkwebView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); self.wkwebView.navigationDelegate = self; self.wkwebView.scrollView.bounces = false; [self addSubview:self.wkwebView]; // __weak typeof(self) weakSelf = self; // [self.wkwebView.scrollView setEmptyContentViewBackgroupColor:UIColor.whiteColor]; // self.wkwebView.scrollView.emptyView = [RAEmptyView emptyViewWithTitle:@"can not reach the server.\ntap to reload" clickHandler:^(id sender) { // [weakSelf LoadFromURL:weakSelf.url]; // }]; // self.firstLoad = YES; } -(void)LoadWithVid:(NSString *)vid { if(self.wkwebView==nil) return; NSString * replacement = [NSString stringWithFormat:@"src=\"https://www.youtube.com/embed/%@\"",vid]; NSError *error; NSString *htmlStr = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"ytplayer" ofType:@"html"]encoding:NSUTF8StringEncoding error: & error]; htmlStr=[htmlStr stringByReplacingOccurrencesOfString:@"src=replacement" withString:replacement]; // NSString *htmlStr1=@"abc def ggg"; // [htmlStr stringByReplacingOccurrencesOfString:@"src=replacement" withString:replacement]; // NSString* new_url = [NSString stringWithFormat:@"https://www.youtube.com/embed/%@?playsinline=1",vid]; // [self.wkwebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:new_url]]]; [self.wkwebView loadHTMLString:htmlStr baseURL:nil]; self.wkwebView.hidden=NO; } -(void)LoadFromURL:(NSString *)vid { if(self.wkwebView==nil) return; NSString* url = [NSString stringWithFormat:@"https://www.youtube.com/embed/%@?playsinline=1",vid]; NSURL* U=[NSURL URLWithString:url]; NSURLRequest* request=[[NSURLRequest alloc]initWithURL:U cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30.0f]; [self.wkwebView loadRequest:request]; } -(void) initMessageHandler { } -(void)destroyMessageHandler { } - (void)dealloc { [self destroyMessageHandler]; } #pragma mark - Setter - (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)contentInsetAdjustmentBehavior { self.wkwebView.scrollView.contentInsetAdjustmentBehavior = contentInsetAdjustmentBehavior; } #pragma mark - player //- (void)stringFromEvaluatingJavaScript:(NSString *)jsToExecute { // // return [self.wkwebView stringByEvaluatingJavaScriptFromString:jsToExecute]; // // //[self.wkwebView evaluateJavaScript:jsToExecute completionHandler:^(id _Nullable result, NSError * _Nullable error) { // DebugLog(@"%@----%@",result, error); // }]; // //} - (void)stopVideo { [self.wkwebView reload]; } #pragma mark - Utils - (NSString *)adjustNilString:(NSString *)str { if (str) { return str; } return @""; } //-(UIViewController*) getViewController //{ // for (UIView* next = [self superview]; next; next = next.superview) { // UIResponder* nextResponder = [next nextResponder]; // if ([nextResponder isKindOfClass:[UIViewController class]]) { // return (UIViewController*)nextResponder; // } // } // return nil; //} #pragma mark - WKNavigationDelegate - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation { DebugLog(@"%s",__func__); } - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { DebugLog(@"%s",__func__); //1)获取trust object SecTrustRef trust = challenge.protectionSpace.serverTrust; // SecTrustResultType result; //2)SecTrustEvaluate对trust进行验证 // OSStatus status = SecTrustEvaluate(trust, &result); // CFArrayRef defaultPolicies = NULL; // SecTrustCopyPolicies(trust, &defaultPolicies); // DebugLog(@"default policies: %@",(__bridge id)defaultPolicies); dispatch_async(dispatch_get_global_queue(0, 0), ^{ CFErrorRef cfError = nil; bool btrust = SecTrustEvaluateWithError(trust, &cfError); NSMutableArray *policies = [NSMutableArray array]; [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; SecTrustSetPolicies(trust, (__bridge CFArrayRef)policies); // if (status == errSecSuccess && (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified)) if(btrust&&cfError == nil) { //3)验证成功,生成NSURLCredential凭证cred,告知challenge的sender使用这个凭证来继续连接 NSURLCredential *cred = [NSURLCredential credentialForTrust:trust]; [challenge.sender useCredential:cred forAuthenticationChallenge:challenge]; if (completionHandler) { completionHandler(NSURLSessionAuthChallengeUseCredential,cred); // 使用证书 } } else { [challenge.sender cancelAuthenticationChallenge:challenge]; //4)验证失败,取消这次验证流程 if (completionHandler) { completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge,nil); // 忽略证书 } } }); } - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { DebugLog(@"%@",error); } //禁止链接跳转 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { DebugLog(@"%s",__func__); DebugLog(@"navigationAction = %@, \r!!!!!!!!!!!!!!!!!!!!!!\n request = %@",navigationAction,navigationAction.request.URL); // NSURLRequest * request = navigationAction.request; return decisionHandler(WKNavigationActionPolicyAllow); // if ([request.URL.host isEqual: self.originURL.host]) { // return decisionHandler(WKNavigationActionPolicyAllow); // } else if ([request.URL.scheme isEqual:@"ytplayer"]) { // [self notifyDelegateOfYouTubeCallbackUrl:request.URL]; // return decisionHandler(WKNavigationActionPolicyCancel); // } else if ([request.URL.scheme isEqual: @"http"] || [request.URL.scheme isEqual:@"https"]) { // if( [self handleHttpNavigationToUrl:request.URL]) // return decisionHandler(WKNavigationActionPolicyAllow); // else // return decisionHandler(WKNavigationActionPolicyCancel); // } // return decisionHandler(WKNavigationActionPolicyAllow); } @end