目标c - 如何使用JS自动播放Vimeo视频

时间:2013-04-01 09:41:34

标签: javascript iphone ios objective-c vimeo

每个试图让Youtube / Vimeo视频在iOS上自动播放的人都知道这可能是一项痛苦的任务。 Apple出于正确的原因阻止了'autoplay'参数,但有时您仍然需要使此功能正常工作。

我和auto playing youtube videos有同样的问题,显然,为了让自动播放工作,你需要做一些javascript魔术,听取玩家的'onReady'事件,而不是玩家加载并准备好玩你叫'player.play()'来启动它而不需要任何其他用户干预。

Vimeo也有一些javascript API,我很确定你可以用它做自动播放技巧,我只是无法弄清楚如何使用它。

他们有一个名为Froogaloop的JS迷你库,以简化操作,我看到this answer by @ila与以下html字符串一起使用它:

NSString *htmlString = [NSString stringWithFormat:
                                                @"<html><head>"
                                                "<script src=\"froogaloop.js\"></script>"
                                                " <script>"
                                                    "function ready()"
                                                        "{$f(document.getElementById(\"player\")).api(\"play\");}"
                                                    "function func1() "
                                                        "{$f(document.getElementById(\"player\")).addEvent(\"ready\", ready);}"
                                                    "window.onload=func1;"
                                                "</script></head><body>"
                                                       "<iframe id=\"player\" src=\"http://player.vimeo.com/video/39287488?api=1&amp;player_id=player\" width=\"315\" height=\"455\" frameborder=\"0\" webkit-playsinline>"
                                               " </iframe></body></html>"];    

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    NSLog(@"webview loaded");
    NSString *path = [[NSBundle mainBundle] pathForResource:@"froogaloop" ofType:@"js"];
    NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
    [webView stringByEvaluatingJavaScriptFromString:jsCode];
}

但这对我不起作用,在向此代码添加警报后,我可以看到func1()被调用并执行'addEvent'行,但是它接收到ready()方法永远不会被调用,因为'ready'事件永远不会被触发(?)...

有什么想法吗?

2 个答案:

答案 0 :(得分:8)

我对这个问题的第一个答案是一种不太理想的蛮力方法。我建议使用Vimeo Javascript API和froogaloop查看我的第二种方法。

我假设您在html页面中使用Vimeo iframe,并且您在iOS应用程序内或Safari内部的UIWebView中使用此页面。

对Vimeo iframe进行内省的一点点表明它最初没有加载html视频标签。您将不得不以编程方式点击“播放”按钮来加载视频。

为了在今天(2013年4月,它可能会改变)这样做,您可以抓住正确的元素并调用正确的功能。最好用一些工作示例代码进行演示。

// You are loading this page inside a UIWebView
<html>
<head></head>
<body>
    <iframe width="" height="" src="http://player.vimeo.com/video/62207569 " frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
    <script>
    // Add a listener for the window's load event
    window.addEventListener('load', onWindowLoad, false);

    function onWindowLoad(event) {
        //use a loop to continue checking the vimeo iframe for the 'play' button
        checkForTrue(isIframeButtonLoaded, iFrameButtonLoaded);
    }

    function checkForTrue(func, callback) {
        setTimeout(function() {
            if (func()) {
                callback( iFrameButton() );
            } else {
                checkForTrue(func, callback);
            };
        }, 1000);
    }

    //finds the 'play' button within the Vimeo iframe
    function iFrameButton() {
                    //window.frames[0].document.getElementsByTagName('div')[1]; // this also works...
        return window.frames[0].document.getElementsByTagName('button')[5];
    }

    //simple boolean condition to check for the iframe button
    function isIframeButtonLoaded() {
        return ( iFrameButton() != null );
    }

    //once the button is loaded, click it
    function iFrameButtonLoaded(iFrameButton) {
        iFrameButton.click();
    }

    </script>
</body>
</html>

This source code is also available as a gist

一个理智的人可能会说这不是最好的方法,但为了在你的iOS应用程序中自动播放vimeo视频,它似乎确实有效。

从包中加载html文件并将其加载到UIWebView中的代码是样板:

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSString *htmlFile = [[NSBundle mainBundle] pathForResource:@"VimeoTrial" ofType:@"html"];
    NSString *htmlString = [NSString stringWithContentsOfFile:htmlFile encoding:NSUTF8StringEncoding error:nil];

    [self.webView loadHTMLString:htmlString baseURL:nil];
}

答案 1 :(得分:2)

由于网络浏览器强制执行Same Origin Policy,因此无法在本地或通过HTML字符串加载文件。

iframe无法将postEvent()调用传播回主窗口,因为正在通过iframe协议访问Vimeo http://并且本地文件是通过file://协议。 “就绪”事件通过此机制发送。

可以在此实例中使用Vimeo API,但为了自动播放视频,您需要知道iframe何时加载,但“ready”事件通过postEvent从iframe发送到窗口。

Vimeo API Documentation中提供的代码清楚地说明了它正在使用postEvent。 Froogaloop也使用相同的代码

window.addEventListener('message', onMessageReceived, false);

如果您在计算机上的HTML文件中运行Vimeo API的最基本示例,Google Chrome将会抛出一条描述性消息:( Safari不会显示此消息)

  

不安全的JavaScript尝试从具有URL http://player.vimeo.com...的帧访问具有URL文件:///...index.html的帧请求访问的帧具有“http”协议,被访问的帧具有协议'文件'。协议必须匹配。

有问题的代码很简单:(See this gist for the full source

<iframe id="player" width="" height="" src="http://player.vimeo.com/video/62207569?api=1&player_id=player" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>

<script src="http://a.vimeocdn.com/js/froogaloop2.min.js"></script>

<script>    
  var player = $f(document.getElementById('player'));
  player.addEvent('ready', function() { 
  player.api('play');
});
</script>

正确的解决方案是在与Vimeo iframe具有相同协议的远程服务上托管HTML页面。在这种情况下,来自http://地址的任何内容。

如果您从http://(insert your host here)加载上述内容,则可立即在iOS模拟器,Safari和Google Chrome中使用。

如果你想在设备上做更多的事情,你必须合并我给出的两个答案;轮询iframe直到你认为准备就绪,然后告诉玩家对象进行游戏。