Adam Mark

Web design and development

Video and Apps: So Happy Together

What do macaroni and cheese, peanut butter and jelly, and franks and beans have in common? Yes, they’re all delicious. But more importantly, in each case the whole is greater than the sum of its individual parts. Peanut butter by itself is delicious, but it’s made better with jelly. I feel the same way about video and apps:

  • Video breathes life into apps while apps provide a contextual framework for discovering and delivering video.

  • Video depends on the entire app landscape (phones, tablets, web sites, and smart TVs) for broad distribution. Likewise, the app landscape depends on pluggable, reusable forms of content like video.

  • Video drives engagement and engagement drives app usage.

Video + Apps

Meanwhile, the growth of mobile video is staggering. Apps that deliver great video experiences to a broad array of devices and platforms stand to benefit from this trend. And content owners stand to benefit from using services that facilitate a multi-platform, multi-device approach.

Brightcove App Cloud makes it easy to create video-centric apps for iOS and Android devices using content from Brightcove Video Cloud, YouTube, and many other video services. It’s an end-to-end, cross-platform publishing solution that includes an HTML5-based SDK plus cloud-based services for optimizing and managing content. Here’s a quick look at how App Cloud content feeds can be used to integrate videos into apps.

App Cloud + Video Cloud

App Cloud and Video Cloud are—surprise!—tightly integrated. From App Cloud Studio, select “New Content Source,” then choose “Video Cloud,” then enter a Video Cloud Read API token:

Screen shot

Then it’s just a matter of selecting some playlists to send to the custom application template. Here, I’ve selected two playlists from my Video Cloud account:

Screen shot

It’s that simple. I can reorder or swap out playlists at any time, even after the app is deployed. My changes take effect without having to repackage and resubmit the app to the various app stores—an invaluable feature considering how often I change my mind! In content-driven apps, this kind of flexibility is essential.

App Cloud + YouTube

App Cloud can also ingest data feeds (RSS, XML, JSON) from YouTube and other video services. From App Cloud Studio, select “New Content Source,” then choose “Content Feed,” then enter a feed URL:

Screen shot

App Cloud optimizes the feed before sending it to devices. In some cases, the savings are dramatic:

Screen shot

Every bit counts, especially in mobile apps! By using App Cloud as a proxy, I can speed up my apps tremendously.

A match made in the cloud

If video and apps are like peanut butter and jelly—a perfect food pairing—then Video Cloud and App Cloud are a perfect collaboration of cloud content services. One improves the other.

There’s another joke to be made here about how videos are sticky, but I should quit while I’m ahead. Try App Cloud today and see how easy it is to create video-centric native apps for iOS and Android. It’s free to get started—all you need are some basic web development skills and a good app idea. You can load videos from Video Cloud or almost any other video service. And while you’re at it, check out some of the other App Cloud services like image transcoding, analytics and ad insertion. (App Cloud is like jelly … it’s pretty sweet!)

The Pursuit of Appiness: Building Native Apps With App Cloud and HTML5

As a web developer and designer for thirteen years, I’ve jockeyed from one hot technology to another with relative ease. First Java, then PHP, then Ruby. I rode the Flash train for a long time. I kept up with every major UI library, from Prototype to jQuery, and kept pace with rapidly evolving web standards.

But like many web developers, I missed the boat on mobile. I had no experience with low-level programming languages like C++ or Objective-C, nor did I have time to learn them. And the thought of making small apps with Java—a language that always seemed big and bulky to me—was unappealing.

I looked at a number of products for cross-platform development, but every one fell short of my expectations:

  • App “factories” that wrap RSS feeds in prefab templates tend to produce low- budget or cookie-cutter apps.

  • Frameworks that convert JavaScript or ActionScript into native code require complex toolchains to create and compile the apps.

  • Frameworks that wrap web pages in native shells provide little or no back-end infrastructure necessary to operate data-driven apps in production.

So when I learned about App Cloud, a framework for creating native mobile apps with HTML, CSS and JavaScript, I was skeptical. Would App Cloud be different from the other products I tried? Would it live up to its many promises? I set out to make a real app and learned the answer is a resounding YES. Here’s why:

App Cloud speaks my language

App Cloud draws on all my skills as a web developer: HTML to structure content, CSS to style it, and JavaScript to manipulate it. I don’t have to learn new languages to create rich, content-driven apps. After all, web technologies have always excelled in this area. Compare the complexity of creating a table view in iOS to the simplicity of creating a list of things in HTML. (There is no comparison.)

Plus, I can use almost any JavaScript libraries I want on top of the App Cloud SDK. After many years of web development, I came to App Cloud with a big bag of tricks that I didn’t want to throw away.

It’s my way or the highway

When I write code, I alternate between using Sublime Text and vim. So when I jumped into App Cloud, I was relieved to find that I could use my trusty tools. And since App Cloud uses standard web technologies, I can use Chrome Developer Tools to inspect and debug my code on the desktop.

While some other systems ride the coattails of XCode or Eclipse—a bulky and maddeningly complex Java-based IDE—App Cloud gives me freedom of choice.

The Workshop—it’s refreshing!

The App Cloud Workshop app for iOS and Android lets me test and experience my apps as I develop them. I change some code, click “Refresh,” and see the results immediately. As a web developer, I rely on this kind of rapid iteration. Code, refresh, repeat.

While much of my work can be tested in a desktop web browser, there’s no substitute for actually experiencing the app running on real devices. The Workshop app makes this process a snap.

There’s an API for that

App Cloud provides a ridiculously simple JavaScript bridge to native device capabilities like the camera and photo library—things that aren’t possible in a regular mobile web site. Here’s how to access the camera to scan a QR code:

bc.device.getQRCode(successCallback, errorCallback);

That was easy! And it works across iOS and Android, tablet and phone. I don’t need to worry about the underlying characteristics of each platform or device form factor. It just works.

App Cloud Studio: Compile in style

I recently installed the Android developer tools to compile an app I made in another framework, an exercise not unlike building an IKEA bookshelf. The directions were incomprehensible, it took half a day, and the results were a bit rickety.

With App Cloud Studio, my apps are compiled in the cloud with the touch of a button (okay, a few buttons). In just a few minutes, the compiled apps are ready for download, at which point I can submit them to the various app stores. Absolutely no special tooling is required on my end.

Content optimization: Less is more

In content-driven apps—and especially in content-driven mobile apps—the biggest bottleneck is the content itself. App Cloud speeds up my apps in a couple important ways:

  • App Cloud removes unnecessary and unwanted data from my content feeds. Then it compresses them, caches them, and makes them highly available to thousands of devices. My blog feed went from 39KB to 4KB after optimization and compression, a 90% reduction!

  • App Cloud resizes and caches images on the fly. The cumulative effects of image transcoding cannot be overstated: one of my blog images was reduced from 125KB at 425px wide to 8KB at 200px wide, a 94% reduction! Multiply this by the number of images in my blog, the number of users, and the number of sessions per user. We’re talking big, big savings.

Studies have shown that load time affects the bottom line. With App Cloud, it’s one less thing I have to worry about.

Set and forget? Not with App Cloud

Do you remember the Showtime Rotisserie Oven? You set it and forget it! If only apps were this simple. Content-driven apps, like web sites, often require configuration changes after being deployed. With App Cloud Studio, I can change data, styles and other custom settings after an app has been deployed and without recompiling and resubmitting the app to the various app stores.

This not only gives me a ton of flexibility as a developer, it empowers others in the organization to help manage the apps I create.

What’s more, the ability to change data, settings and styles in App Cloud Studio means I can create multiple apps from a single template without writing any additional code. I didn’t fully appreciate this power until I made two very distinct apps from the same template:

All I did was swap out data feeds and adjust a few settings. The design and configuration options were entirely up to me.

Sharing is caring

While App Cloud doesn’t solve the problem of hovering art directors, it does make it easier for colleagues to review my work in the comfort of their own offices. For example, I can send screenshots directly from the Workshop app:

Or I can share an entire template with anyone who has the Workshop app just by sending them a URL or QR code:

100% Cloud coverage

App Cloud is a one-stop shop for nearly everything I need to manage and monetize my content apps in production, from native ad insertion to real-time analytics. For example, in the Analytics section, I can see how my apps are performing in the wild, from total installs to total usage time:

And because App Cloud is service-oriented and all-inclusive, I get performance enhancements and feature updates for free. I’m excited for what’s to come: push notifications, in-app purchases, Facebook integration, additional platform support, and more.

If you’re still reading, you’re probably interested in trying App Cloud for yourself. Just register for a free account and download the SDK from App Cloud Studio.

Happy (er, “appy”) developing!

Lazy Loading Your Views in App Cloud

“Lazy loading” doesn’t mean you’re lazy. It’s simply a technique for deferring an operation until it’s absolutely necessary.

If your template has multiple views, you should consider building up each view when the user enters it—and not before. You’ll save memory and improve the performance of your app by preventing all your business logic across all your views from running at the same time.

In the following example from my “Map” view (map.html), the function MapView is responsible for loading and rendering the dynamic content on the page:

var view;

$(bc).on("viewfocus", function (evt) {
    if (!view) {
        view = new MapView();
        view.init();
    }
});

By listening for a "viewfocus" event, I can wait to create a MapView instance until the moment the user enters the view. This way, I avoid eating up system resources—and slowing down the user experience—while the user is off playing in another view.

(And while the new content is loading, I show cached content alongside a “Loading …” message.)

More JavaScript Tricks to Impress Your Friends

And now for another installment of cool but unreadable JavaScript techniques!

Repeating a string

Use the Array constructor to repeat a string. For example, to create the string “**********”:

// old way
var str = "";
for (var i = 0; i < 10; i++) {
    str += "*";
}

// ninja way
var str = Array(11).join("*");

In the ninja example above, an array with 11 empty values (“”) is joined by “*”. (Thanks to JavaScript Garden.)

Casting function arguments to an array

Sometimes you need to treat function arguments as an array:

// old way
function func(a, b, c) {
    var arr = [];
    for (var i in arguments) {
        arr.push(arguments[i]);
    }
}

// ninja way
function func(a, b, c) {
    var arr = [].slice.call(arguments);
}

Calling Array.prototype.slice, or [].slice on the arguments object returns an array of arguments. Now you can pass it around or slice and dice it.

Testing for even or odd

In my tutorial on bitwise operations, I explained how to use a bitwise AND to test if a number is even or odd:

// old way
if (i % 2 == 0) { … }

// ninja way
if (i & 1 == 0) { … }

In binary, an even number AND 1 is always 0 (even); an odd number AND 1 is always 1 (odd).

Testing minimum length of a list

Sometimes (or never) you need to know whether a list is at least a certain length:

var list = ["a", "b", "c"];

// old way
if (list.length >= 3) { … }

// ninja way
if (2 in list) { … }

Wait, what? Imagine the above array as an object literal:

var list = {
    0: "a",
    1: "b",
    2: "c"
};

Now it makes sense!

Creating a function on the fly

We’ve been told over and over again that eval is evil. If you believe this, the following technique is just as bad:

// old way
var rand = eval("var rand = function () { return Math.random() }");

// ninja way
var rand = new Function("return Math.random()");

Notice we’re using the Function constructor with a capital F.

Casting a number literal to a string

When calling toString on a number literal, the number must be wrapped in parentheses so the JavaScript parser doesn’t interpret the dot as part of a floating point number. But there are two ways around this major inconvenience (also thanks to JavaScript Garden):

// old way
(123).toString();

// ninja way
123..toString(); // extra dot!
123 .toString(); // space!

Entering the void

Who needs undefined? Avoid it with void:

// old way
var val = undefined;

// ninja way
var val = void 0;

Introducing Markup.js: Powerful JavaScript Templates

When I started making App Cloud apps, I thought I could benefit from using a JavaScript templating system. So I toyed around with two popular frameworks, Mustache and jQuery Templates. Unfortunately I didn’t like either. I found Mustache to be too simplistic (it prides itself on being logicless), while jQuery Templates required me to use jQuery.

So I decided to write my own templating system with the following goals:

  • It should have an elegant syntax with minimal punctuation
  • It should be fast and lightweight
  • It should have no library dependencies
  • It should not require a browser or DOM
  • It should be flexible enough to support internationalization (i18n) tasks

The result: Markup.js. Weighing in at only 1.7KB after minification and gzipping, it includes a simple yet powerful expression language for transforming structured data into HTML and other text formats. So far, I’m loving it.

JavaScript Tricks to Impress Your Friends

I recently came across some mind-bending JavaScript shortcuts in a web project I inherited from another developer. Most of these techniques are bad from a readability perspective—and none of them offer significant performance gains—but you should feel free to discuss them at cocktail parties to impress your friends.

Casting a string to a number

Use the unary plus operator to cast a string to a number:

// old way
parseInt("123", 10); // 123
parseFloat("45.678"); // 45.689
Number("9"); // 9

// ninja way
+"123.45"; // 123.45

Note parseInt() and parseFloat() are actually more versatile:

parseInt("123px", 10); // 123
+"123px"; // NaN

parseFloat("45.678deg"); // 45.678
+"45.678deg"; // NaN

Convert a date to UTC milliseconds

Use the unary plus operator to cast a Date object to milliseconds since the Unix epoch:

var date = new Date(); // Thu Aug 11 2011 10:47:37 GMT-0400 (EDT)

// old way
date.getTime(); // 1313074057920
date.valueOf(); // 1313074057920

// ninja way
+date; // 1313074057920

Testing for a substring with bitwise NOT

Use the bitwise NOT operator to test for the presence of a substring:

// old way
"Hahaha".indexOf("ha") > -1; // true

// ninja way
~"Hahaha".indexOf("ha"); // true

Wait, what? The bitwise NOT (or complement) of a signed integer is equal to the negative of that number minus 1:

~2 = -3; // resolves to true
~0 = -1; // also true
~-1 = 0; // false

This is kind of nuts, but it does save you from typing about four extra characters.

Testing for the presence of a value

Use a double NOT (or “bang bang”) to test if a variable value is not null, not undefined and not an empty string:

var name = "Adam";

// old way
name != null && name != undefined && name != ""; // true

// ninja way
!!name; // true

The first bang casts the value to a Boolean and the second bang negates it. In the ninja example above, the expression resolves to !false, or true.

Preempting a function call

Create a boolean expression to avoid calling a function if the function value is undefined:

// old way
var handleResponse = function (data, callback) {
    if (callback) {
        callback(data);
    }
}

// ninja way
var handleResponse = function (data, callback) {
    callback && callback(data);
}

In the ninja example above, if the the first half of the Boolean test is false or undefined, the second half is never evaluated.

Chaining function calls

Variables are for suckers! If one function returns another, you can just execute the returned function right away:

var stack = [function1, function2, function3];

// old way
var func = stack.pop();
func();

// ninja way
stack.pop()();

Concatenating strings

The plus sign: also for suckers. Use an array to join string fragments:

// old way
var name = "A" + "d" + "a" + "m";

// ninja way
var name = ["A", "d", "a", "m"].join("");

Understanding Bitwise Operations in JavaScript

I’ve been reading Code: The Hidden Language of Computer Hardware and Software by Charles Petzold. It’s a great introduction to the building blocks of computer science—ones and zeros—for the liberal arts majors among us. Check it out and you’ll understand this joke:

There are only 10 kinds of people in the world: Those who understand binary and those who don’t.

When you’re done ROFLing, consider some of the ways you can use bitwise operations in everyday JavaScript code:

Use a bitmask to check for inclusion in a set

Say you’ve got a bowl of five different fruits and you want to know if it contains a banana. You could simply check every piece of fruit in the bowl to see if it’s a banana:

function contains(bowl, fruit) {
    for (var i = 0; i < bowl.length; i++) {
        if (bowl[i] == fruit) {
            return true;
        }
    }

    return false;
}

// has banana? yes
contains(["apple", "banana", "cherry"], “banana”);

Or you could use Array.indexOf to get the same result:

function contains(bowl, fruit) {
    return bowl.indexOf(fruit) > -1;
}

// has banana? yes
contains(["apple", "banana", "cherry"], “banana”);

// has banana? no
contains(["apple", "grape", "cherry"], “banana”);

But what if you want to know whether the bowl contains a banana, a cherry and an apple?

var bowl = ["apple", "banana", "cherry", "grape", "peach"];

// has banana, cherry and apple? yes
contains(bowl, “banana”) && contains(bowl, “cherry”) && contains(bowl, “apple”);

This gets ugly fast. You could, of course, modify the contains function to accept an array of fruits:

function contains(bowl, fruits) {
    for (var i = 0; i < fruits.length; i++) {
        if (bowl.indexOf(fruits[i]) == -1) {
            return false;
        }
    }

    return true;
}

var bowl = ["strawberry", "grape", "peach", "orange"];

var fruits = ["banana", "cherry", "apple"];

// has banana, cherry and apple? no
contains(bowl, fruits);

That’s better, but let’s try doing it without arrays and loops. Enter bitmasks! First, assign each possible option a value of 2 to the power of n, starting with n=0:

var Fruit = {
    BANANA:       1,
    ORANGE:       2,
    STRAWBERRY:   4,
    PEACH:        8,
    APPLE:       16,
    GRAPE:       32,
    CHERRY:      64,
    TANGERINE:  128
};

Each decimal value converts to a binary sequence that contains exactly one “1.” For example, ORANGE equals 10 and STRAWBERRY equals 100. Together they equal 110:

   010
OR 100
   —
   110

You can quickly calculate the sum of the bowl using a bitwise OR expression. Say the bowl has a banana, a peach and a tangerine:

var bowl = Fruit.BANANA | Fruit.PEACH | Fruit.TANGERINE;

This bowl equals 137 in decimal or 10001001 in binary. Notice the number of ones in the result equals the number of fruits in the bowl:

   00000001  BANANA
OR 00001000  PEACH
OR 10000000  TANGERINE
   ——–
   10001001

Now you can represent any configuration of eight fruits in just eight digits!

The resulting value, 10001001, will serve as a bitmask to determine whether the bowl contains certain fruits. Testing for the presence of a single fruit is straightforward with a bitwise AND:

    10001001  BOWL
AND 00000001  BANANA
    ——–
    00000001  TRUE

    10001001  BOWL
AND 00000010  ORANGE
    ——–
    00000000  FALSE

Now just check to see if bowl AND fruit is greater than zero:

function contains(bowl, fruit) {
    return (bowl & fruit) > 0;
}

var bowl = Fruit.BANANA | Fruit.PEACH | Fruit.TANGERINE;

// has banana? yes
contains(bowl, Fruit.BANANA);

Testing for the presence of multiple fruits is a bit trickier but just as elegant. Since the ANDed value can be positive if just some of the fruits are present, you need to make sure the ANDed value is greater than or equal to the value of fruits itself:

function contains(bowl, fruits) {
    return (bowl & fruits) >= fruits;
}

var bowl = Fruit.BANANA | Fruit.PEACH | Fruit.TANGERINE;

// has banana and tangerine? yes
contains(bowl, Fruit.BANANA | Fruit.TANGERINE);

// has banana and apple? no
contains(bowl, Fruit.BANANA | Fruit.APPLE);

See how the bitmask method performs against the array method at jsperf.com.

Use bitwise AND for alternation

You’ve probably used a modulus to test whether the value of a counter is odd or even:

for (var i = 0; i < 10000; i++) {
    if (i % 2 == 0) {
        // even
    }
    else {
        // odd
    }
}

But in big loops it’s faster to use a binary AND expression. In binary, an even number AND 1 is always 0 (even), while an odd number AND 1 is always 1 (odd):

for (var i = 0; i < 10000; i++) {
    if (i & 1 == 0) {
        // even
    }
    else {
        // odd
    }
}

Use bitwise shifting to convert hexadecimal values

Did you ever wonder what “hex” (base 16) color values look like in another number system? Take the value of pure red: FF0000. In decimal (base 10) it’s 16711680 and in binary (base 2) it’s 111111110000000000000000. Try it for yourself in a JavaScript console:

0xFF0000.toString(10);
0xFF0000.toString(2);

Now let’s say you want to convert the hex value to RGB, in which R, G and B are values ranging from 0 to 255:

function hexToRGB(hex) {
    var r = (hex & 0xFF0000) >> 16;
    var g = (hex & 0x00FF00) >> 8;
    var b = (hex & 0x0000FF);
    return [r,g,b];
}

Here, the inputted value is being ANDed with the values of pure red, green and blue, then the red and green values are shifted to the right by 16 bits and 8 bits, respectively. The result is three 8-bit values, or 0-255 in decimal.

Take the color gold: 0xFFCC00. What are the individual RGB values?

// returns [255, 204, 0]
var rgb = hexToRGB(0xFFCC00);

And it works the other way around. For example, to create a hex string from red, blue and green values:

function rgbToHexString(r, g, b) {
    var color = (r << 16) | (g << 8) | b;
    return “#” + (“000000″ + color.toString(16)).substr(-6);
}

// returns “#ffcc00″
rgbToHexString(255, 204, 0);

As you can see, binary operations are useful for everyday JavaScript programming tasks. And they’re super fast!