123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- //
- // videoPlayViewController.m
- // 双子星云手机
- //
- // Created by xd h on 2024/5/21.
- //
- #import "videoPlayViewController.h"
- #import <WebKit/WebKit.h>
- #import <AVFoundation/AVFoundation.h>
- @interface videoPlayViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler>
- @property (nonatomic, strong) WKWebView *curWKWebView;
- @property (nonatomic, strong)AVPlayer*player;
- @end
- @implementation videoPlayViewController
- - (void)viewDidLoad {
- [super viewDidLoad];
- // Do any additional setup after loading the view.
-
- [self.toolBar setHidden:YES];
- [self.navigationBar setHidden:YES];
- [self.navBarBGView setHidden:NO];
- //self.navBarBGView.backgroundColor = [UIColor whiteColor];
- [self.view setBackgroundColor:[UIColor whiteColor]];
-
- //[self setUpVideoPlayer];
-
-
- }
- #pragma mark ---播放器
- - (void)setUpVideoPlayer {
- //创建网页配置对象
- WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
-
- // 是使用h5的视频播放器在线播放, 还是使用原生播放器全屏播放
- //config.allowsInlineMediaPlayback = YES;
- //设置视频是否需要用户手动播放 设置为NO则会允许自动播放
- config.mediaTypesRequiringUserActionForPlayback = NO;
- //设置是否允许画中画技术 在特定设备上有效
- config.allowsPictureInPictureMediaPlayback = NO;
-
- //设置请求的User-Agent信息中应用程序名称 iOS9后可用
- //config.applicationNameForUserAgent = @"ChinaDailyForiPad";
- //自定义的WKScriptMessageHandler 是为了解决内存不释放的问题
- // WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self];
-
-
- //这个类主要用来做native与JavaScript的交互管理
- // 注入js 解决进入播放就横屏问题
- WKUserContentController *content = [[WKUserContentController alloc]init];
- //1解决解决进入播放就横屏问题
- NSString *jSString = @"document.getElementsByTagName('video')[0].setAttribute('playsinline','playsinline');";
- WKUserScript *wkUserScript = [[WKUserScript alloc] initWithSource:jSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
- [content addUserScript:wkUserScript];
-
-
- //2,暂停播放监听
- NSString *PausePlayListenerjSString = @"document.getElementsByTagName('video')[0].addEventListener('pause', function(e) {window.webkit.messageHandlers.pause.postMessage(\"pause\");})";
- WKUserScript *PausePlayListenerwkUScript = [[WKUserScript alloc] initWithSource:PausePlayListenerjSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
- [content addUserScript:PausePlayListenerwkUScript];
-
- //3,继续播放监听
- NSString *ContinuePlayingListenerjSString = @"document.getElementsByTagName('video')[0].addEventListener('play', function(e) {window.webkit.messageHandlers.play.postMessage(\"play\");})";
- WKUserScript *ContinuePlayingListenerwkUScript = [[WKUserScript alloc] initWithSource:ContinuePlayingListenerjSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
- [content addUserScript:ContinuePlayingListenerwkUScript];
-
- //4,播放结束监听
- NSString *EndOfPlayListenerjSString = @"document.getElementsByTagName('video')[0].addEventListener('ended', function(e) {window.webkit.messageHandlers.ended.postMessage(\"ended\");})";
- WKUserScript *EndOfPlayListenerwkUScript = [[WKUserScript alloc] initWithSource:EndOfPlayListenerjSString injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
- [content addUserScript:EndOfPlayListenerwkUScript];
- //添加一个协议
- [content addScriptMessageHandler:self name:@"play"];
- [content addScriptMessageHandler:self name:@"pause"];
- [content addScriptMessageHandler:self name:@"ended"];
- //5,暂停播放播放
- NSString *pauseJS = @"var videos = document.getElementsByTagName(\"video\");\
- function pauseVideo(){videos[0].pause();}\
- function playVideo(){videos[0].play();}";
-
- WKUserScript *PausePlaywkUScript = [[WKUserScript alloc] initWithSource:pauseJS injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:YES];
- [content addUserScript:PausePlaywkUScript];
-
-
- config.userContentController= content;
-
- _curWKWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H) configuration:config];
- // UI代理
- _curWKWebView.UIDelegate = self;
- // 导航代理
- _curWKWebView.navigationDelegate = self;
- [self.view addSubview:_curWKWebView];
-
- }
- - (void)viewWillAppear:(BOOL)animated
- {
- [super viewWillAppear:animated];
-
- [self beginPlayVideoFun];
- }
- - (void)beginPlayVideoFun
- {
- NSString *filePath = _VideoDataMode.path;
-
- NSString *urlStr = ksharedAppDelegate.NASFileByBoxService;
- NSString *fileUrl = [[NSString alloc] initWithFormat:@"%@getFile?path=%@",urlStr,filePath];
- fileUrl = [fileUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-
- //fileUrl = @"http://transfer.armclouding.com:10010/getFile?path=/storage/006A-A69C/bf0308/Screenrecording_20231101_163026.mp4";
- fileUrl = @"http://transfertest.armclouding.com:10010/getFile?path=/sdcard/bb.mp4";
- NSURL * sourceMovieURL= [NSURL URLWithString:fileUrl];
-
- // 根据URL创建请求
- // NSURLRequest *request = [NSURLRequest requestWithURL:sourceMovieURL];
- // [_curWKWebView loadRequest:request];
-
- //111111111
- NSURL *videoUrl = sourceMovieURL;
- AVAsset *asset = [AVAsset assetWithURL:videoUrl];
- AVPlayerItem*videoItem = [AVPlayerItem playerItemWithAsset:asset]; // 视频资源信息 M
- _player = [AVPlayer playerWithPlayerItem:videoItem]; // 视频控制播放层 C
- AVPlayerLayer*playerLayer = [[AVPlayerLayer alloc]init]; // 视频展示层 V
- playerLayer.player = _player;
- playerLayer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
- [self.view.layer addSublayer:playerLayer]; // 添加到父视图的layer层
- // 监听视频状态
- [videoItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:@"item.status"];
- // 监听缓冲进度
- [videoItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:@"item.loaded"];
- //获取播放进度
- [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
- float startSeconds = CMTimeGetSeconds(time); // 已经播放的秒数
- HLog(@"22222 %f",startSeconds);
- }];
-
- // 接收播放完成通知
- //[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePlayEnd) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
- }
- #pragma mark 事件代理
- // 页面开始加载时调用
- -(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
-
- }
- // 当内容开始返回时调用
- - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
-
- }
- // 页面加载完成之后调用
- - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{//这里修改导航栏的标题,动态改变
-
-
-
- }
- // 页面加载失败时调用
- - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
-
- }
- // 接收到服务器跳转请求之后再执行
- - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
-
- }
- // 在收到响应后,决定是否跳转
- - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
-
- HLog(@"%@",webView);
- HLog(@"%@",navigationResponse);
-
- WKNavigationResponsePolicy actionPolicy = WKNavigationResponsePolicyAllow;
- //这句是必须加上的,不然会异常
- decisionHandler(actionPolicy);
-
- }
- // 在发送请求之前,决定是否跳转
- - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
-
- HLog(@"URL=======%@", navigationAction.request.URL);
- HLog(@"URL.scheme=======%@", navigationAction.request.URL.scheme);
-
-
- WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow;
-
- if (navigationAction.targetFrame == nil) {
- [webView loadRequest:navigationAction.request];
- }
- if (navigationAction.navigationType==WKNavigationTypeBackForward) {//判断是返回类型
-
-
- }
- //这句是必须加上的,不然会异常
- decisionHandler(actionPolicy);
-
- //NSString *url = navigationAction.request.URL.absoluteString;
- }
- #pragma mark - WKScriptMessageHandler
- - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
- HLog(@"%@",NSStringFromSelector(_cmd));
- HLog(@"%@",message);
- HLog(@"%@",message.body);
- HLog(@"%@",message.name);
- NSString *jsonStr = message.body; //
- HLog(@"%@",jsonStr);
-
-
- KWeakSelf
- if ([message.name caseInsensitiveCompare:@"play"] == NSOrderedSame) {
- NSLog(@"video is play");
- }
- else if ([message.name caseInsensitiveCompare:@"pause"] == NSOrderedSame) {
- NSLog(@"video is pause");
- }
- else if ([message.name caseInsensitiveCompare:@"ended"] == NSOrderedSame) {
- NSLog(@"video is ended");
- [weakSelf playVideo];
- }
-
- }
- #pragma mark 原生调用JS暂停
- - (void)pausePlay
- {
- [_curWKWebView evaluateJavaScript:@"pauseVideo()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
- NSLog(@"response:%@,error:%@",response,error);
- }];
- }
- - (void)playVideo
- {
- [_curWKWebView evaluateJavaScript:@"playVideo()" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
- NSLog(@"response:%@,error:%@",response,error);
- }];
- }
- //通过KVO来观察status属性的变化,来获得播放之前的错误信息
-
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
- {
- if ([keyPath isEqualToString:@"status"]) {
- AVPlayerStatus status = [change[NSKeyValueChangeNewKey] intValue];
- switch (status) {
- case AVPlayerStatusFailed:
- {
- NSError *error = self.player.currentItem.error;
- NSLog(@"url有误:%@",error);
- }
- break;
- case AVPlayerStatusReadyToPlay:
- {
- NSLog(@"准备好播放了");
- }
- break;
- case AVPlayerStatusUnknown:
- {
- NSLog(@"视频资源出现未知错误");
- }
- break;
- default:
- break;
- }
- }
- }
- @end
|