Cordova Demo - Apple TV HD Video Viewer

So a few days ago, someone on Twitter (sorry, I forget who) mentioned that the new Apple TV has some pretty stellar screen savers. Turns out - the data for those screen savers was all driven by a public JSON file. It didn't take long for someone to notice and then build a cool demo: Watch All The Apple TV Aerial Video Screensavers. You should check it out. Seriously. Absolutely beautiful stuff.

Now it looks like everyone is playing with it. You can even get a OSX and Windows screen saver of the videos. I'm sure Apple is going to kill this off sometime soon - I mean - they have to I imagine - but in the meantime they are some darn pretty visuals to look at.

While exercising today, I thought I'd quickly whip up a demo of this using Apache Cordova and Ionic. Here it is in action. And yes - for the life of me I couldn't get it to be 100% of the canvas. I'm sure there is some way in CSS to say, "Stretch this so it covers everything and I'm OK if parts of it are off screen", but such CSS Wizardry is beyond me.

So the code isn't anything special. The front end is pretty much just the "pull to refresh" widget and a video tag:

<ion-pane>
    <ion-header-bar class="bar-dark">
    <h1 class="title">Apple Arial Viewer</h1>
    </ion-header-bar>
    <ion-content ng-controller="MainCtrl">
            <ion-refresher
                pulling-text="Pull to select new video..."
                on-refresh="loadVideo()">
            </ion-refresher>
            <video autoplay loop id="mainVideo" controls2>
                <source src="" />
            </video>
    </ion-content>
</ion-pane>

And here is the JavaScript:

angular.module('starter', ['ionic'])

.controller('MainCtrl', function($scope, AppleVideoService) {

    $scope.loadVideo = function() {
        AppleVideoService.getVideo().then(function(vid) {
            console.log(vid.url);
            document.querySelector("#mainVideo source").setAttribute("src", vid.url);
            document.querySelector("#mainVideo").load();
            $scope.$broadcast('scroll.refreshComplete');
        });
    };
    
    $scope.loadVideo();
        
})
.factory('AppleVideoService', function($http,$q) {

    var jsonURL = "http://a1.phobos.apple.com/us/r1000/000/Features/atv/AutumnResources/videos/entries.json";
    var videoData = "";
    
    //http://stackoverflow.com/a/7228322
    var randomIntFromInterval = function (min,max) {
        return Math.floor(Math.random()*(max-min+1)+min);
    }
    
    /*
    first, I determine if night or data
    then, I pick a random video matching that
    */
    var randomVideo = function() {
        //what time is it?
        var hour = new Date().getHours();
        if(hour > 6 && hour < 18) {
            return videoData.day[randomIntFromInterval(0, videoData.day.length)];   
        } else {
            return videoData.night[randomIntFromInterval(0, videoData.night.length)];               
        }
    };
    
    /*
    I convert Apple's JSON into two array of day and night videos. That makes it easier to pick a random one.
    */
    var process = function(data) {
        var processed = {night:[], day:[]};
        for(var i=0; i<data.length;i++) {
            for(var video in data[i].assets) {
                if(data[i].assets[video].timeOfDay === "day") {
                    processed.day.push(data[i].assets[video]);  
                }   else {
                    processed.night.push(data[i].assets[video]);    
                }
            }   
        }
        return processed;
    };
    
    return {
        
            getVideo:function() {
                var deferred = $q.defer();
                if(videoData === "") {
                    $http.get(jsonURL).success(function(data) {
                        videoData = process(data);
                        deferred.resolve(randomVideo());
                    }); 
                }   else deferred.resolve(randomVideo());
                return deferred.promise;
            }
        
    };
    
})
.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
    // for form inputs)
    if(window.cordova && window.cordova.plugins.Keyboard) {
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
        
        
  });
})

So the controller simply sets up a call to my service and updates the DOM with the proper HTML. I'm always unsure about how to do DOM manipulations like this with Angular. I'm guessing I should have used ng-model or something here, right?

The service isn't too complex either. We load Apple's JSON once and parse it into a list of day and night videos. We then figure out what time it is, and arbitrarily decide that 7AM to 6PM is "day". Obviously your world may differ. Then we can just select a random video and return it.

And really that's it. I could add a label to the display so folks knew what it is. I could also add support for knowing when you are offline. But I won't. I will, however, share all the code: https://github.com/cfjedimaster/Cordova-Examples/tree/master/arialscreensaver.

Like This?

If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can also subscribe to the email feed to get notified of new posts.

See Also