Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective c - How to autoplay Vimeo videos using JS

Everyone who tried to make Youtube/Vimeo videos start play automatically on iOS knows that it could be a painful task. Apple blocked the 'autoplay' parameter for the right reasons, but sometimes you still need to get this functionality working.

I had the same issue with auto playing youtube videos, apparently, to get the autoplay to work, you need to do some javascript magic, listen for the player's 'onReady' event, than when the player is loaded and ready to play you call 'player.play()' to start it without any another user intervention.

Vimeo also got some javascript API, and I'm pretty sure you can do the autoplay trick with it, I just can't figure it up how to use it.

They have JS mini-library called Froogaloop to make things easier, I saw this answer by @ila who use it in conjunction with the following html string:

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];
}

But this doesn't work for me, after adding alerts to this code, I can see that func1() get called and executing the 'addEvent' line, BUT it seams that the ready() method never gets called because the 'ready' event never fired (?)...

Any ideas?

like image 283
Eyal Avatar asked Apr 01 '13 09:04

Eyal


1 Answers

My first answer to the question is a less than ideal brute force method. I'd suggest looking at my second method using the Vimeo Javascript API and froogaloop.

I'm going to assume you're using the Vimeo iframe inside a html page and that you're using this page inside a UIWebView inside an iOS app or inside Safari.

A little bit on introspection into the Vimeo iframe shows that it doesn't load the html video tag initially. You're going to have to programatically tap the 'play' button for it to load the video.

In order to do that today (April 2013, it may change) you can just grab the right elements and call the right functions. It's best demonstrated with some working sample code.

// 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

A sane person may say this is not the best way to do it, but for the purpose of automatically playing a vimeo video within your iOS app it does seem to work.

The code to load the html file from your bundle and load it into a UIWebView is boilerplate:

- (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];
}
like image 140
Jessedc Avatar answered Sep 17 '22 23:09

Jessedc