Vol*_*da2 51 youtube mpmovieplayercontroller mpmovieplayer nsnotificationcenter ios
我没有收到任何通知MPMoviePlayerController.我究竟做错了什么?
我使用以下逻辑.
我开始播放youtube视频了UIWebView.UIWebView称之为标准MPMoviePlayerController.我不控制MPMoviePlayerController因为我没有实例化MPMoviePlayerController.
我使用自动播放运行youtube的剪辑(延迟1秒):
[self performSelector:@selector(touchInView:) withObject:b afterDelay:1];
Run Code Online (Sandbox Code Playgroud)
我的代码是:
- (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];
}
Run Code Online (Sandbox Code Playgroud)
更新:我正在创建播放youtube视频的应用程序.您可以运行播放列表,您将看到第一个视频.当第一个视频结束时,第二个视频会自动开始播放,依此类推.
我需要支持ios 4.1及以上版本.
UPDATE2: @ H2CO3我正在尝试使用你的url-scheme,但它不起作用.委托方法没有调用退出事件.我添加了我的html url来登录.它是:
<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
}
Run Code Online (Sandbox Code Playgroud)
UPDATE3 @Till,我无法抓住UIMoviePlayerControllerDidExitFullscreenNotification,但我找到了MPAVControllerItemPlaybackDidEndNotification.播放视频结束时会出现MPAVControllerItemPlaybackDidEndNotification.
但是我不明白如何捕获完成通知?
Til*_*ill 64
UIWebView嵌入式电影播放器没有发送任何文档通知.
实际上,在许多方面(例如DRM)UIWebView,公开使用的封闭实现确实与公众不同MPMoviePlayerController.
用于播放视频内容的最重要的类UIWebView称为MPAVController和UIMoviePlayerController.后者使播放器看起来像MPMoviePlayerController全屏界面.
如果您敢于冒被Apple拒绝的风险,实际上还有一些方法可以实现您的目标.
注意 这没有记录,并且每个新的iOS版本都会中断.但它确实可以在iOS4.3,5.0和5.01,5.1和6.0上运行,它也可以在其他版本上运行.
我无法在iOS 4.1和4.2上测试此解决方案,因此您可以自行决定.我非常怀疑它会起作用.
全屏状态
例如,如果您打算对用户点击DONE按钮作出反应,您可以这样做:
更新 建议使用此答案的旧版本, 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);
Run Code Online (Sandbox Code Playgroud)
Objective-C级别:
- (void)playerWillExitFullscreen:(NSNotification *)notification
{
//do something...
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerWillExitFullscreen:)
name:@"UIMoviePlayerControllerWillExitFullscreenNotification"
object:nil];
Run Code Online (Sandbox Code Playgroud)
我确实选择了C级和Objective-C级选项,因为实际发现所有这些的最佳方法是使用C级(CoreFoundation)函数,如我的答案结尾所示.如果一个通知的发件人不使用的Objective-C(NSNotifications),你可能实际上没有使用NSNotification力学能够捕获它们.
播放状态
要检查播放状态,请注意"MPAVControllerPlaybackStateChangedNotification"(如上所述)并检查userInfo可能如下所示:
{
MPAVControllerNewStateParameter = 1;
MPAVControllerOldStateParameter = 2;
}
Run Code Online (Sandbox Code Playgroud)
进一步的逆向工程
对于逆向工程和浏览所有已发送的通知,请使用以下代码段.
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);
Run Code Online (Sandbox Code Playgroud)
Chr*_*sJP 32
在iOS 4.3+中,您可以使用UIMoviePlayerControllerDidEnterFullscreenNotification和UIMoviePlayerControllerDidExitFullscreenNotification通知:
-(void)viewDidLoad
{
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeStarted:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(youTubeFinished:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];
}
-(void)youTubeStarted:(NSNotification *)notification{
// your code here
}
-(void)youTubeFinished:(NSNotification *)notification{
// your code here
}
Run Code Online (Sandbox Code Playgroud)
小智 16
据我所知,在制作Cocoa Touch应用程序时,不依赖于UIWebView(以及Apple制作的所有系统类)的实现细节.也许是这样的情况,UIWebView的视频播放器不是标准的MPMoviePlayerController类,它可能有一个完全不同的委托/通知系统,用户不应该访问它.
我建议你使用HTML5元素并检测这个标签的"onended"事件:
<html>
<body>
<script>
function endMovie() {
// detect the event here
document.location.href="somefakeurlscheme://video-ended";
}
</script>
<video src="http://youtube.com/watch?v=aiugvdk755f" onended="endMovie()"></video>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
事实上,从endMovie JavaScript函数,你可以重定向到一个假的网址,你可以在你的-webView赶上:shouldStartLoadWithRequest:(UIWebViewDelegate)方法从而得到通知,该视频已结束:
- (BOOL) webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)req {
if ([[[req URL] absoluteString] hasPrefix:@"somefakeurlscheme://video-ended"]) {
[self someMethodSupposedToDetectVideoEndedEvent];
return NO; // prevent really loading the URL
}
return YES; // else load the URL as desired
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
基于@ H2CO3答案但使用iframe API.这是我能让它发挥作用的唯一方法.
这不使用任何私有API,这使它更具有未来性.
这是嵌入Youtube视频的代码.检查API以了解更多自定义方法.
<html>
<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 = "https://www.youtube.com/iframe_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 onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '480',
width: '640',
videoId: 'aiugvdk755f',
events: {
'onStateChange': onPlayerStateChange
}
});
}
// 5. The API calls this function when the player's state changes.
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
endedMovie();
}
}
function endedMovie() {
// detect the event here
document.location.href="somefakeurlscheme://video-ended";
}
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这就是您收到视频结束通知的方式(UIWebViewDelegate方法).
- (BOOL) webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)req {
if ([[[req URL] absoluteString] hasPrefix:@"somefakeurlscheme://video-ended"]) {
[self someMethodSupposedToDetectVideoEndedEvent];
return NO; // prevent really loading the URL
}
return YES; // else load the URL as desired
}
Run Code Online (Sandbox Code Playgroud)
在ViewDidLoad中添加以下代码
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoExitFullScreen:) name:@"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(VideoEnterFullScreen:) name:@"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
Run Code Online (Sandbox Code Playgroud)
以下方法用于显示进入/退出全屏的各个进程的消息/功能
- (void)VideoExitFullScreen:(id)sender{
// Your respective content/function for Exit from full screen
}
- (void)VideoEnterFullScreen:(id)sender{
// Your respective content/function for Enter to full screen
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
40754 次 |
| 最近记录: |