Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Using The Onymos Media Component In Your Ionic Framework App

TwitterFacebookRedditLinkedInHacker News

A few years back I demonstrated how to use the device camera in an Android and iOS application developed with Ionic Framework. Being able to take photos wasn’t particularly difficult, but it left a lot to be desired. This is where the Media component by Onymos comes into play.

So what is the Onymos Media component?

The Onymos Media component extends the media features offered by the Apache Cordova camera plugin. It will correct common orientation issues for photos and videos captured from the various platforms and devices, it allows access to the various internal directories on Android, and it offers advanced compression features. The component also offers tight integration with Amazon S3 for storing media online.

Per the Onymos website, the Media component reduces the time it takes to get an application released to the market and in turn saves in development costs. Paired with the component’s continuous updates, your application will always be functional.

We’re going to see how to take pictures within our application using the Onymos Media component and upload them to Amazon S3 with ease. Everything you see below can easily be expanded to videos as the Onymos Media component can accomplish the same tasks with video as well.

Let’s start by creating a new Ionic Framework project by executing the following from the Command Prompt (Windows) or Terminal (Mac and Linux):

ionic start OnymosProject blank
cd OnymosProject
ionic platform add android
ionic platform add ios

It is important to note that if you’re not using a Mac you cannot add and build for the iOS platform.

Before you can use the Onymos Media component you must first pick up a license. You will receive an email with the component download information and authentication information. Save the Media component archive somewhere and extract it.

Now we can install the component into our project. From your Command Prompt or Terminal, execute the following command:

cordova plugin add path/to/onymos_components/onymos-plugin-media

Remember to use the path to your extracted component download in the above command.

Now we can start designing and developing our project!

Onymos Media Component for Ionic Framework

Above is what we’re going to try to accomplish. We will be able to take photos from our device, upload them to Amazon S3, and then view them from Amazon S3 from whatever device we wish to use.

We’re going to spend our time in the project’s www/index.html, www/js/app.js, and www/modals/mediasearch.html files. Let’s start with the www/js/app.js file since it will be our logic file. Open it and add the following code:

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

.run(function($ionicPlatform) {
    $ionicPlatform.ready(function() {
        if(window.cordova && window.cordova.plugins.Keyboard) {
            cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
            cordova.plugins.Keyboard.disableScroll(true);
        }
        if(window.StatusBar) {
            StatusBar.styleDefault();
        }
        var onymosConnectObj = {
            customerId: "CUSTOMER_ID_HERE",
            envType: "PRD",
            onymosAuthToken: "AUTH_TOKEN_HERE",
            awsAccessKey: "AWS_PUBLIC_KEY_HERE",
            awsSecretKey: "AWS_SECRET_KEY_HERE"
        };
        window.OnymosMediaUI.onymosInitialize(onymosConnectObj, function(status) {
            console.log(status);
        }, function(error) {
            console.log(error);
        });
    });
})

.controller("MainController", function($scope, $ionicModal) {
    $scope.mediaURI = "https://placehold.it/350x150";
    $ionicModal.fromTemplateUrl('modals/mediasearch.html', {
        scope: $scope,
        animation: 'slide-in-up'
    }).then(function(modal) {
        $scope.modal = modal;
    });

    $scope.selectMedia = function() {
        window.OnymosMediaUI.onymosMediaSelect(1, OnymosMediaConstants.PictureSourceType.CAMERA, OnymosMediaConstants.MediaType.ALLMEDIA, function(mediaURI) {
            $scope.mediaURI = window.OnymosMediaUI.onymosMediaGetThumbnail(1);
            $scope.$apply();
        }, function(error) {
            console.log(JSON.stringify(error));
        });
    }

    $scope.clearMedia = function() {
        window.OnymosMediaUI.onymosMediaCancelSelect(1);
        $scope.mediaURI = "https://placehold.it/350x150";
    }

    $scope.uploadMedia = function() {
        window.OnymosMediaUI.onymosMediaUpload(1, ["test"], function(status) {
            console.log(status);
        }, function(error) {
            console.log(error);
        }, {
            mediaResizeFactor: 80,
            thumbnailResizeFactor: 20,
            uploadSizeLimit: 15
        });
    }

    $scope.searchMedia = function() {
        window.OnymosMediaUI.onymosMediaSearch(["test"], function(resultsArray) {
            $scope.uploadedMedia = resultsArray;
            $scope.modal.show();
        }, function(error) {
            console.log(error);
        }, {
            resultsValidityTime: 1800,
            searchResultsLimit: 5
        });
    }

    $scope.downloadMedia = function(media) {
        $scope.mediaURI = media.thumbnailUrl;
        $scope.modal.hide();
    }

});

That was a huge chunk of code, so let’s break it down to see what all the bits and pieces mean.

Starting in the module.run method we can see the following:

var onymosConnectObj = {
    customerId: "CUSTOMER_ID_HERE",
    envType: "PRD",
    onymosAuthToken: "AUTH_TOKEN_HERE",
    awsAccessKey: "AWS_PUBLIC_KEY_HERE",
    awsSecretKey: "AWS_SECRET_KEY_HERE"
};
window.OnymosMediaUI.onymosInitialize(onymosConnectObj, function(status) {
    console.log(status);
}, function(error) {
    console.log(error);
});

This will initialize the Onymos Media component when the application starts. Per the Onymos documentation, you can use your own AWS information if you don’t wish to use the Onymos hosting. If using your own AWS hosting, you can define the bucket with awsBucketFolder.

All the core logic will happen within a single controller. The MainController has five functions, most of which perform a task taken from the Onymos Media component documentation. When the controller loads, we default the placeholder image like so:

$scope.mediaURI = "https://placehold.it/350x150";

This is so we don’t start with a blank screen, but instead show something interesting.

To save us from having to use the UI-Router in this example, we make use of a popup modal that presents us with a list of uploaded media. We won’t get into the media part yet, but to initialize the modal we do the following:

$ionicModal.fromTemplateUrl('modals/mediasearch.html', {
    scope: $scope,
    animation: 'slide-in-up'
}).then(function(modal) {
    $scope.modal = modal;
});

Let’s jump into those component functions now.

The first thing you probably want to do is select media. We have the option to select media from storage or select media from the device camera. Here we select media from the camera:

$scope.selectMedia = function() {
    window.OnymosMediaUI.onymosMediaSelect(1, OnymosMediaConstants.PictureSourceType.CAMERA, OnymosMediaConstants.MediaType.ALLMEDIA, function(mediaURI) {
        $scope.mediaURI = window.OnymosMediaUI.onymosMediaGetThumbnail(1);
        $scope.$apply();
    }, function(error) {
        console.log(JSON.stringify(error));
    });
}

When we capture the photo that we want, we’ll receive mediaURI information. This is actually the local path to the file on your device. However, we don’t want to display the full media file, but instead we want to display a thumbnail. Using the synchronous onymosMediaGetThumbnail function we can get the thumbnail and add it to our scope. We’ll later display this image, but we need to run $scope.$apply() otherwise the data won’t refresh on the front-end.

Information about our selection is saved in memory. If we want to clear it out we can cancel the selection as seen here:

$scope.clearMedia = function() {
    window.OnymosMediaUI.onymosMediaCancelSelect(1);
    $scope.mediaURI = "https://placehold.it/350x150";
}

When we clear the selection we probably want to switch back to our placeholder image.

However, maybe we want to upload the media that we just captured. This is where my favorite part comes into play because it is incredibly simple:

$scope.uploadMedia = function() {
    window.OnymosMediaUI.onymosMediaUpload(1, ["test"], function(status) {
        console.log(status);
    }, function(error) {
        console.log(error);
    }, {
        mediaResizeFactor: 80,
        thumbnailResizeFactor: 20,
        uploadSizeLimit: 15
    });
}

We can take the callId, give it some tags, and issue the onymosMediaUpload command. In case you’re scratching your head, the callId is used in both the select and cancel methods. They must match as it is a reference.

That was easy right? No need to understand any of the Amazon APIs.

When it comes to finding the media that has been uploaded you can make use of the following:

$scope.searchMedia = function() {
    window.OnymosMediaUI.onymosMediaSearch(["test"], function(resultsArray) {
        $scope.uploadedMedia = resultsArray;
        $scope.modal.show();
    }, function(error) {
        console.log(error);
    }, {
        resultsValidityTime: 1800,
        searchResultsLimit: 5
    });
}

The search is based on tags. The results found based on the tags are added to an array that will be displayed in the modal that we will create soon.

Finally we need to know how to download the media found in the search:

$scope.downloadMedia = function(media) {
    $scope.mediaURI = media.thumbnailUrl;
    $scope.modal.hide();
}

The results array we populated from the search will be an array of objects. When a particular object is chosen it will get passed to the above function where we will set our image.

That was all our application logic.

Now let’s take a look at our UI components starting with the modal. Create and open www/modals/mediasearch.html and populate it with the following:

<ion-modal-view>
    <ion-header-bar>
        <h1 class="title">My Modal title</h1>
    </ion-header-bar>
    <ion-content>
        <ion-list>
            <ion-item ng-repeat="media in uploadedMedia" ng-click="downloadMedia(media)">{{media.fileName}}</ion-item>
        </ion-list>
    </ion-content>
</ion-modal-view>

Nothing too much going on here. We are creating an <ion-list> and looping through the searched media array we created in our logic file. We will pass the selected media object to the downloadMedia function.

Finally we have our www/index.html file. Open it and include the following code:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
        <title></title>

        <link href="lib/ionic/css/ionic.css" rel="stylesheet">
        <link href="css/style.css" rel="stylesheet">

        <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
        <link href="css/ionic.app.css" rel="stylesheet">
        -->

        <!-- ionic/angularjs js -->
        <script src="lib/ionic/js/ionic.bundle.js"></script>

        <!-- cordova script (this will be a 404 during development) -->
        <script src="cordova.js"></script>

        <!-- your app's js -->
        <script src="js/app.js"></script>
    </head>
    <body ng-app="starter">
        <ion-pane ng-controller="MainController">
            <ion-header-bar class="bar-stable">
                <h1 class="title">Ionic Blank Starter</h1>
                <button class="button button-icon icon ion-search" ng-click="searchMedia()"></button>
            </ion-header-bar>
            <ion-content>
                <img ng-src="{{mediaURI}}" width="100%" />
            </ion-content>
            <div class="bar bar-footer">
                <div class="button-bar">
                    <a class="button" ng-click="clearMedia()">Clear</a>
                    <a class="button" ng-click="selectMedia()">Capture</a>
                    <a class="button" ng-click="uploadMedia()">Upload</a>
                </div>
            </div>
        </ion-pane>
    </body>
</html>

I bet the following line looks familiar:

<img ng-src="{{mediaURI}}" width="100%" />

This is where our image media ends up. The mediaURI is what we set within our logic file after selecting or downloading a file from Amazon S3.

We want a slick footer menu with a few buttons because it makes sense in our application:

<div class="bar bar-footer">
    <div class="button-bar">
        <a class="button" ng-click="clearMedia()">Clear</a>
        <a class="button" ng-click="selectMedia()">Capture</a>
        <a class="button" ng-click="uploadMedia()">Upload</a>
    </div>
</div>

The buttons above just call the methods that we created in the www/js/app.js file.

I know it seems like we did a lot, but we really didn’t. You should have a feature rich media application now!

Conclusion

Working with media and Amazon S3 in an Ionic Framework Android and iOS mobile application can be tricky. Lucky for us the Onymos Media component takes a lot of the stress out of this.

You saw how to capture media using the device camera and display it on the screen. This same media was uploaded to Amazon S3 and also downloaded. Although we didn’t go heavy into the image compression features of Onymos, you can set various options before uploading to reduce the file size.

The Media component can also be used with videos and is not limited to just photos.

This example project has been bundled and the full code can be found on GitHub for further learning and troubleshooting.

This blog article was sponsored by Onymos.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.