如何从UIWebView嵌入式YouTube视频播放中接收NSNotifications [英] How to receive NSNotifications from UIWebView embedded YouTube video playback

查看:121
本文介绍了如何从UIWebView嵌入式YouTube视频播放中接收NSNotifications的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我没有收到任何关于 MPMoviePlayerController 的通知。我做错了什么?

I didn't received any notifications for MPMoviePlayerController. What am I doing wrong?

我使用以下逻辑。

我开始播放youtube视频的UIWebView UIWebView 调用标准 MPMoviePlayerController 。我不控制 MPMoviePlayerController 因为我没有实例化 MPMoviePlayerController

I'm begining to play youtube video in UIWebView. UIWebView calls a standard MPMoviePlayerController. I don't control MPMoviePlayerController because I didn't instantiate MPMoviePlayerController.

我使用自动播放运行youtube的剪辑(延迟1秒):

I run youtube's clip with autoplay (1 second delay):

[self performSelector:@selector(touchInView:) withObject:b afterDelay:1];

我的代码是:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadStateDidChange:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidFinish:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];

    [self embedYouTube];
}

- (void)loadStateDidChange:(NSNotification*)notification
{
    NSLog(@"________loadStateDidChange");
}

- (void)playbackDidFinish:(NSNotification*)notification
{
    NSLog(@"________DidExitFullscreenNotification");
}

- (void)embedYouTube
{
    CGRect frame = CGRectMake(25, 89, 161, 121);
    NSString *urlString = [NSString stringWithString:@"http://www.youtube.com/watch?v=sh29Pm1Rrc0"];

    NSString *embedHTML = @"<html><head>\
    <body style=\"margin:0\">\
    <embed id=\"yt\" src=\"%@\" type=\"application/x-shockwave-flash\" \
    width=\"%0.0f\" height=\"%0.0f\"></embed>\
    </body></html>";
    NSString *html = [NSString stringWithFormat:embedHTML, urlString, frame.size.width, frame.size.height];
    UIWebView *videoView = [[UIWebView alloc] initWithFrame:frame];
    videoView.delegate = self;

    for (id subview in videoView.subviews)
        if ([[subview class] isSubclassOfClass: [UIScrollView class]])
            ((UIScrollView *)subview).bounces = NO;

            [videoView loadHTMLString:html baseURL:nil];
    [self.view addSubview:videoView];
    [videoView release];
}

- (void)webViewDidFinishLoad:(UIWebView *)_webView 
{
    UIButton *b = [self findButtonInView:_webView];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(touchInView:) object:b];
    [self performSelector:@selector(touchInView:) withObject:b afterDelay:1];
}

- (UIButton *)findButtonInView:(UIView *)view 
{
    UIButton *button = nil;

    if ([view isMemberOfClass:[UIButton class]]) {
        return (UIButton *)view;
    }

    if (view.subviews && [view.subviews count] > 0) 
    {
        for (UIView *subview in view.subviews) 
        {
            button = [self findButtonInView:subview];
            if (button) return button;
        }
    }
    return button;
}

- (void)touchInView:(UIButton*)b
{
    [b sendActionsForControlEvents:UIControlEventTouchUpInside];
}

更新:我正在创建播放的应用程序youtube的视频。您可以运行播放列表,您将看到第一个视频。当第一个视频结束时,第二个视频会自动开始播放,依此类推。

UPDATE: I'm creating application that plays youtube's video. You can run playlist and you will see first video. When first video has ended, second video begins play automatically and so on.

我需要支持ios 4.1及以上版本。

I need to support ios 4.1 and above.

UPDATE2: @ H2CO3我正在尝试使用你的网址方案,但它不起作用。委托方法没有调用退出事件。我添加了我的html url来登录。
它是:

UPDATE2: @H2CO3 I'm trying to use your url-scheme, but it don't works. Delegate method didn't called on exit event. I added my html url to log. It is:

<html><head>    <body style="margin:0">    
<script>function endMovie() 
{document.location.href="somefakeurlscheme://video-ended";} 
 </script>      <embed id="yt" src="http://www.youtube.com/watch?v=sh29Pm1Rrc0"        
 onended="endMovie()" type="application/x-shockwave-flash"  
 width="161" height="121"></embed>  
 </body></html>

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
  if ([[[request URL] absoluteString] hasPrefix:@"somefakeurlscheme://video-ended"]) 
  {
    [self someMethodSupposedToDetectVideoEndedEvent];
    return NO; // prevent really loading the URL
   }
  return YES; // else load the URL as desired
}

UPDATE3
@Till,我无法抓住UIMoviePlayerControllerDidExitFullscreenNotification,但我找到了MPAVControllerItemPlaybackDidEndNotification。播放视频结束时会出现MPAVControllerItemPlaybackDidEndNotification。

UPDATE3 @Till, I cann't caught UIMoviePlayerControllerDidExitFullscreenNotification, but I found MPAVControllerItemPlaybackDidEndNotification. MPAVControllerItemPlaybackDidEndNotification appears when playback video is ended.

但我不明白如何捕获onDone通知?

But I don't understand how do I catch onDone notifications?

推荐答案

UIWebView 嵌入式电影播放器​​没有发送任何文件通知。

There are no documented notifications sent by the UIWebView embedded movie player.

事实上, UIWebView 中使用的封闭式实现与公共 MPMoviePlayerController不同在很多方面(例如DRM)。

In fact, the closed implementation used within the UIWebView does differ from the public MPMoviePlayerController in many aspects (e.g. DRM).

用于在 UIWebView 中播放视频内容的最重要的类称为 MPAVController UIMoviePlayerController 。后者使得播放器看起来像 MPMoviePlayerController 全屏界面。

The most important classes used for playing video content within that UIWebView are called MPAVController and UIMoviePlayerController. The latter one makes the player appear like the MPMoviePlayerController fullscreen interface.

如果您敢于冒险拒绝Apple,实际上还有一些方法可以实现您的目标。

In case you dare to risk a rejection by Apple, there are actually ways to still achieve what you are looking for.

注意
这是没有记录的,并且受制于打破每一个新的iOS版本。但它确实适用于iOS4.3,5.0和5.01,5.1和6.0,并且可能也适用于其他版本。

NOTE This is not documented and is subject to break on each and every new iOS release. It does however work on iOS4.3, 5.0 and 5.01, 5.1 and 6.0 and it may work on other versions as well.

我无法在iOS 4.1和4.2上测试此解决方案,因此您可以自行决定。我非常怀疑它会起作用。

I am not able to test this solution on iOS 4.1 and 4.2, so that is up to you to do. I highly suspect that it will work.

全屏状态

例如,如果您打算对用户点击 DONE 按钮做出反应,您可以这样做:

If, for example you are intending to react upon the user tapping the DONE button, you may be able to do it this way:

更新 此答案的旧版本建议使用 UIMoviePlayerControllerDidExitFullscreenNotification 而这个新版本(针对iOS6更新)建议使用 UIMoviePlayerControllerWillExitFullscreenNotification

C语言级别:

void PlayerWillExitFullscreen (CFNotificationCenterRef center,
                 void *observer,
                 CFStringRef name,
                 const void *object,
                 CFDictionaryRef userInfo)
{
    //do something...
}

CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), 
    NULL, 
    PlayerWillExitFullscreen, 
    CFSTR("UIMoviePlayerControllerWillExitFullscreenNotification"), 
    NULL,  
    CFNotificationSuspensionBehaviorDeliverImmediately);

Objective-C等级:

Objective-C Level:

- (void)playerWillExitFullscreen:(NSNotification *)notification
{
    //do something...
}

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(playerWillExitFullscreen:)
                                             name:@"UIMoviePlayerControllerWillExitFullscreenNotification" 
                                           object:nil];

我确实选择了C级和Objective-C级选项,因为实际的最佳方式找出所有这些是使用C级(CoreFoundation)函数,如我的答案结尾所示。如果通知的发件人不使用Objective-C(NSNotifications),则可能实际上无法使用NSNotification-mechanics捕获它们。

I did draft both, C-Level and Objective-C-Level options because the best way to actually find out about all of this is to use C-Level (CoreFoundation) functions as shown at the end of my answer. If the sender of a notification does not use Objective-C (NSNotifications), you may actually not be able to trap them using the NSNotification-mechanics.

播放状态

要检查播放状态,请留意MPAVControllerPlaybackStateChangedNotification(如上所述)并检查 userInfo ,如下所示:

For examining the playback state, look out for "MPAVControllerPlaybackStateChangedNotification" (as drafted above) and examine the userInfo which may look like this:

{
    MPAVControllerNewStateParameter = 1;
    MPAVControllerOldStateParameter = 2;
}






进一步反向工程

对于逆向工程和浏览所有已发送的通知,请使用以下代码段。

For reverse engineering and exploring all the notifications sent, use the following snippet.

void MyCallBack (CFNotificationCenterRef center,
                 void *observer,
                 CFStringRef name,
                 const void *object,
                 CFDictionaryRef userInfo)
{
    NSLog(@"name: %@", name);
    NSLog(@"userinfo: %@", userInfo);
}

CFNotificationCenterAddObserver(CFNotificationCenterGetLocalCenter(), 
    NULL, 
    MyCallBack, 
    NULL, 
    NULL,  
    CFNotificationSuspensionBehaviorDeliverImmediately);

这篇关于如何从UIWebView嵌入式YouTube视频播放中接收NSNotifications的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆