Objective c 检测到UIWebView完成在iPad上播放youtube视频

Objective c 检测到UIWebView完成在iPad上播放youtube视频,objective-c,ipad,youtube,uiwebview,Objective C,Ipad,Youtube,Uiwebview,我正在使用UIWebView在iPad上播放YouTube视频 如何检测YouTube视频何时结束播放? 我在状态栏中看到播放图标,并尝试使用MPMusicLayerController通知检测playbackStateDidChange,但它不起作用 你知道如何检测这个事件吗?再说一遍,我说的是iPad,不是iPhone 提前谢谢 更新: 如果您使用zero solution检测播放结束并希望Youtube视频自动启动,请将UIWebView设置为: self.webView.mediaPla

我正在使用
UIWebView
在iPad上播放YouTube视频

如何检测YouTube视频何时结束播放? 我在状态栏中看到播放图标,并尝试使用
MPMusicLayerController
通知检测
playbackStateDidChange
,但它不起作用

你知道如何检测这个事件吗?再说一遍,我说的是iPad,不是iPhone

提前谢谢

更新:

如果您使用zero solution检测播放结束并希望Youtube视频自动启动,请将
UIWebView
设置为:

self.webView.mediaPlaybackRequiresUserAction = NO ;
我只想澄清一下YouTube框架API:

重要提示:这是一个实验特性,这意味着它可能 意外更改”(08/05/2012)


不,无法直接从
UIWebView
获取网页事件。但我们可以通过使用Javascript来实现这一点

  • 首先,在自定义HTML中使用嵌入Javascript来检测视频结束播放事件
  • 然后尝试使用JavaScript加载scheme自定义请求,UIWebView可以捕获该请求
这些链接可能有助于:

  • 更新了一个示例:

    在UIWebView的委托中,我将:

    #pragma - mark WebView Delegate
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    
    
    if ( [[[request URL] scheme] isEqualToString:@"callback"] ) {
    
        NSLog(@"get callback");
    
        return NO;
    }
    
    return YES;
    
    }

    viewDidLoad
    时,网页被加载:

    [self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle       mainBundle] pathForResource:@"youtube" ofType:@"html" ]]]];
    
    在youtube.html中,我放了:

    到YouTube的iFrame API演示,它捕获播放器端播放事件并尝试使用“回调”模式加载请求,然后UIWebView委托可以捕获它


    您可以使用此方法使用JavaScript触发任何事件

    以下是@zero作为一个成熟的职业的绝妙答案供您使用:

    @interface YouTubeWebView () <UIWebViewDelegate>
    
    @end
    
    
    @implementation YouTubeWebView 
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self == nil) return nil;
    
        self.mediaPlaybackRequiresUserAction = NO;
        self.delegate = self;
        self.alpha = 0;
    
        return self;
    }
    
    - (void)loadVideo:(NSString *)videoId
    {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"youtube" ofType:@"html"];
        //    if (filePath == nil)
    
        NSError *error;
        NSString *string = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
        // TODO: error check
    
        string = [NSString stringWithFormat:string, videoId];
    
        NSData *htmlData = [string dataUsingEncoding:NSUTF8StringEncoding];
        //    if (htmlData == nil)
    
        NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
        NSString *targetPath = [documentsDirectoryPath stringByAppendingPathComponent:@"youtube.html"];
        [htmlData writeToFile:targetPath atomically:YES];
    
        [self loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:targetPath]]];
    }
    
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        if ([[[request URL] scheme] isEqualToString:@"callback"]) {
            [self removeFromSuperview];
    
            NSString *documentsDirectoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
            NSString *targetPath = [documentsDirectoryPath stringByAppendingPathComponent:@"youtube.html"];
            NSError *error;
            [[NSFileManager defaultManager] removeItemAtPath:targetPath error:&error];
    //        TODO: error check
        }
    
        return YES;
    }
    
    要实现这一点,我必须克服的唯一主要障碍是将文件作为字符串加载以进行替换。不幸的是,它必须以文件的形式再次写入,以便autoplay工作。如果您的用例不需要这样做,可以直接将HTML作为字符串加载到web视图中。

    请参考:

    iOS 4.0提供了一个通知,您可以使用它来检测youtube视频是否已完成播放

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubePlayed:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    

    这里有一个快速的答案

       NotificationCenter.default.addObserver(
        self,
        selector: #selector(self.videoEnded),
        name: .AVPlayerItemDidPlayToEndTime,
        object: nil)
    
    
    }
    
    func videoEnded(){
        print("video ended")
    }
    

    但这取决于youtube播放器是否支持此类活动,不是吗?你成功做到了吗?@user1105951是的,youtube播放器支持名为“onStateChange”的结束事件,你应该按照youtube JavaScript API@Zero添加一个侦听器,我检查了你的链接,我记得我一直在测试它。尝试在IPAD-safari网络浏览器上运行此演示,您将看到:“您需要启用flash player 9+和javascript才能查看此视频”。@user1105951 iOS设备上的safari不支持flash,因此您需要按照YouTube的iFrame API加载HTML5播放器。很抱歉误导,所以我更新了我的答案,给出了一个我编写和测试的简单示例。它工作得很好。希望这会有帮助。@Zero,像个符咒一样工作!我还了解了酷酷乐队:D(金属规则)谢谢!视频结束后,最好重新加载youtube页面,否则,它将显示youtube提供的相关视频,而不要浪费时间尝试其他解决方案。这一个像魅力一样工作,它只是一行代码。无论如何,这是正在调用的观察者,仅供参考-(void)youTubePlayed:(id)sender只有当用户将视频播放到最后,然后按下“完成”按钮时,此选项才有效。如果他们还没有播放完视频,将不会调用此通知。非常有帮助!!!UIWebView甚至没有为嵌入式视频提供回放按钮。唯一(简单)的解决方案是通过在youTubePlayed:(id)中重新加载视频来避免最后的“相关视频”;为什么不将视频id作为参数传递给javascript函数并调用该函数来加载视频?
    <html>
    <head><style>body{margin:0px 0px 0px 44px;}</style></head>
    <body>
    <!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
    <div id="player"></div>
    
    <script>
      // 2. This code loads the IFrame Player API code asynchronously.
      var tag = document.createElement('script');
      tag.src = "http://www.youtube.com/player_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
      // 3. This function creates an <iframe> (and YouTube player)
      //    after the API code downloads.
      var player;
      function onYouTubePlayerAPIReady() {
        player = new YT.Player('player', {
          height: '320',
          width: '480',
          videoId: '%@',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });
      }
    
      // 4. The API will call this function when the video player is ready.
      function onPlayerReady(event) {
        event.target.playVideo();
      }
    
      // 5. The API calls this function when the player's state changes.
      //    The function indicates that when playing a video (state=1),
      //    the player should play for six seconds and then stop.
      var done = false;
      function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING && !done) {
          setTimeout(stopVideo, 6000);
          done = true;
        }
        if (event.data == YT.PlayerState.ENDED) {
          window.location = "callback:anything"; 
        };
      }
      function stopVideo() {
        player.stopVideo();
      }
    </script>
    </body>
    </html>
    
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubePlayed:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    
       NotificationCenter.default.addObserver(
        self,
        selector: #selector(self.videoEnded),
        name: .AVPlayerItemDidPlayToEndTime,
        object: nil)
    
    
    }
    
    func videoEnded(){
        print("video ended")
    }