【问题标题】:ios7 UIWebView Youtube Videoios7 UIWebView Youtube 视频
【发布时间】:2013-09-26 17:38:29
【问题描述】:

我有一个 UIWebView 子类,用于播放 youtube 和本地视频。在 iOS6 下完美运行。在升级到 iOS7 时,我遇到了一个我真的不知道从哪里开始的问题。虽然子类似乎仍然可以在 iOS7 模拟器上播放 youtube 和本地视频,但当我在设备上播放 youtube 时,我会记录以下消息:

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextSaveGState: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextSetBlendMode: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextSetAlpha: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextTranslateCTM: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextScaleCTM: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update. 

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextGetCTM: invalid context 0x0.
This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextDrawImage: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

Sep 26 10:17:27 JRR-IPad SVOx[558] <Error>: CGContextGetCTM: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context  and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.

===

这种情况只发生在设备上,不会发生在模拟器上,iOS6下也不会发生。我在这里看到一些帖子讨论了 beta 上各种类的类似问题,但我还没有看到关于 iOS7 发布版本的 cmets。

我没有在我的代码中使用任何这些方法,因此这些消息来自库。

有人吗? TIA。

【问题讨论】:

  • 我也面临这个问题。你提交了错误吗?
  • 我刚刚提交了错误报告 #15106115。
  • 你找到解决办法了吗。如果你这样做了,请分享。谢谢
  • 不,没有解决方案。虽然,我正在继续前进。除了消息(似乎是无害的)之外,我还有两个担忧:(1)内存消耗似乎相当高,因为即使加载很短的 youtube 也会导致内存使用量从大约 10MB 猛增到大约 40MB,以及(2)之后单击 youtube 上的播放按钮,然后您必须单击 webview TWICE 上的播放按钮。我在其他地方也看到过这个问题。还没有在这些问题上花费太多时间。
  • 我提交了一份错误报告,并附上了一个示例 xCode 项目。 #15423020

标签: ios ios7


【解决方案1】:

使用它,您可以在视图中运行 youtube 视频..

UIWebView *videoView = [[UIWebView alloc] initWithFrame:self.view.bounds];

    NSString *strparse = [NSString stringWithFormat:@"http://www.youtube.com/watch?v=%@",youtubeVideoId];
    NSRange rng = [strparse rangeOfString: @"watch?v="];
    strparse = [strparse substringFromIndex:rng.location];
    rng = [strparse rangeOfString:@"&feature="];


    if (rng.length >0)
    {
        strparse = [strparse substringToIndex:rng.location];
    }
    strparse = [strparse stringByReplacingOccurrencesOfString:@"watch?v=" withString:@""];
    //http://www.youtube.com/embed/FJkiwbqlSy0
    NSString *youTubeVideoHTML =[NSString stringWithFormat:@"<!DOCTYPE html><html><head><style>body{margin:0px 0px 0px 0px; background:#1111}</style></head> <body> <div id=\"player\"></div> <script> var tag = document.createElement('script'); tag.src = \"http://www.youtube.com/player_api\"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; function onYouTubePlayerAPIReady() { player = new YT.Player('player', { width:'%0.0f', height:'%0.0f', videoId:'%@', events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } });} function onPlayerReady(event) { event.target.playVideo(); } function onPlayerStateChange(event) {if(event.data === 0) {   event.target.destroy(); }}  </script> </body> </html>",0.0, 0.0,youtubeVideoId];


    videoView.scalesPageToFit=NO;
    videoView.mediaPlaybackRequiresUserAction=NO;
    videoView.backgroundColor = [UIColor clearColor];
    videoView.opaque= NO;


    [SharedObj showLoadingWithText:@""];

    [videoView loadHTMLString:youTubeVideoHTML baseURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.youtube.com/watch?v=%@",youtubeVideoId]]];


    [self.view addSubview:videoView];

【讨论】:

    【解决方案2】:

    这是IOS7中的测试代码,运行良好

    [self embedYouTube:[self getYTUrlStr:@"https://www.youtube.com/watch?v=Zq4o_Ca14aw"] frame:CGRectMake(0,40,self.view.frame.size.width, self.view.frame.size.height-40)];
    
    
    - (NSString*)getYTUrlStr:(NSString*)url
    {
        if (url == nil)
            return nil;
    
        NSString *retVal = [url stringByReplacingOccurrencesOfString:@"watch?v=" withString:@"v/"];
    
        NSRange pos=[retVal rangeOfString:@"version"];
        if(pos.location == NSNotFound)
        {
            retVal = [retVal stringByAppendingString:@"?version=3&hl=en_EN"];
        }
        return retVal;
    }
    
    
    
    - (void)embedYouTube:(NSString*)url frame:(CGRect)frame {
    
        NSString* embedHTML = @"\
        <html><head>\
        <style type=\"text/css\">\
        body {\
        background-color: transparent;\
        color: white;\
        }\
        </style>\
        </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, url, frame.size.width, frame.size.height];
        if(videoView == nil) {
            videoView = [[UIWebView alloc] initWithFrame:frame];
            videoView.delegate=self;
            [self.view addSubview:videoView];
        }
    
    
        videoView.mediaPlaybackAllowsAirPlay=YES;
        videoView.allowsInlineMediaPlayback=YES;
        [videoView loadHTMLString:html baseURL:nil];
    
    }
    

    【讨论】:

    【解决方案3】:

    我在我的应用程序中使用了以下方式,它在 iOS6 和 iOS 7 中都可以使用。可能适合你。

    NSString *youTubeID = [self extractYoutubeID:url];   // url is youtube url 
    NSString *embedHTML =[NSString stringWithFormat:@"\
                              <html><head>\
                              <style type=\"text/css\">\
                              body {\
                              background-color: #666666;\
                              padding:%f %f %f %f;\
                              color: blue;\
                              }\
                              </style>\
                              </head><body style=\"margin:0\">\
                              <iframe height=\"%f\" width=\"%f\" title=\"YouTube Video\" class=\"youtube-player\" src=\"http://www.youtube.com/embed/%@\" ></iframe>\
                              </body></html>",paddingTop,paddingRight,paddingBottom,paddingLeft,videoHeight,videoWidth,youTubeID];
    [self.webView loadHTMLString:embedHTML baseURL:nil];
    
    
    
    
    - (NSString *)extractYoutubeID:(NSString *)youtubeURL
        {
            //NSLog(@"youtube  %@",youtubeURL);
            NSError *error = NULL;
            NSString *regexString = @"(?<=v(=|/))([-a-zA-Z0-9_]+)|(?<=youtu.be/)([-a-zA-Z0-9_]+)";
            NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:&error];
            NSRange rangeOfFirstMatch = [regex rangeOfFirstMatchInString:youtubeURL options:0 range:NSMakeRange(0, [youtubeURL length])];
            if(!NSEqualRanges(rangeOfFirstMatch, NSMakeRange(NSNotFound, 0)))
            {
                NSString *substringForFirstMatch = [youtubeURL substringWithRange:rangeOfFirstMatch];
                return substringForFirstMatch;
            }
            return nil;
        }
    

    【讨论】:

      【解决方案4】:

      试试这个:

      NSString* videoUrl = @"//www.youtube.com/embed/Of_hjbYCx4Y";
      if([videoUrl hasPrefix:@"//"]) {
          videoUrl = [NSString stringWithFormat:@"https:%@", videoUrl]; // or http
          // if its a local file add proper scheme like "file:///"
      }
      NSString* iframeWidth = @"100%";
      NSString* iframeHeight = @"240px";
      NSString *iframeHTML =[NSString stringWithFormat:@"<iframe width=\"%@\" height=\"%@\" src=\"%@\" frameborder=\"0\" allowfullscreen></iframe>", iframeWidth, iframeHeight, videoUrl];
      // you can directly use iframeHTML below or u can wrap it up in body and span tags and then use it if u need to add any extra stuff or customize the page itself
      [videoWebView loadHTMLString:htmlString baseURL:nil];
      

      确保两件事: 视频网址以 http (正确的方案)开头,如果您还没有它,请将 /watch?v= 替换为 embed/网址。检查此处给出的其他答案以了解如何执行此操作。 希望对您有所帮助。

      【讨论】:

        【解决方案5】:

        YouTube 提供了一个框架,让我们免于直接使用网络视图的麻烦。该框架位于:https://github.com/youtube/youtube-ios-player-helper

        您需要做的就是创建一个 YTPlayerView 视图,将其添加到具有您喜欢的约束的视图层次结构中,然后加载视频。像这样:

            youTubePlayer = YTPlayerView()
            youTubePlayer!.translatesAutoresizingMaskIntoConstraints = false
            contentView.addSubview(youTubePlayer!)
            youTubePlayer!.pinAllAnchors(to: contentView)
            youTubePlayer!.load(withVideoId: url.youTubeVideoId()!)
        

        请注意 pinAllAnchors 和 youTubeVideoId 是我创建的助手。它们不是框架的一部分。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-24
          • 1970-01-01
          • 1970-01-01
          • 2011-09-11
          • 2011-05-05
          • 2011-06-11
          • 2015-05-05
          • 2013-01-19
          相关资源
          最近更新 更多