Use MediaCapture to Add Profile Pic to Meteor User Account
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

Use media capture (http://dev.opera.com/articles/view/media-capture-in-mobile-browsers/) with Meteor - and save a profile pic to a standard user account (built-in accounts).

Crowdsource coding tasks.

1 Solution


Here you go (mediacapture.meteor.com), it's not working with real user accounts, but it should do the trick:

Photos = new Meteor.Collection('photos');

if (Meteor.isClient) {
    Template.media.rendered = function () {
        var user = Photos.findOne({user: 1});
        var source = null;
        var constraints = {
            video: true,
        };

        if (user !== undefined) {
            $('#media img').attr({
                src: user.dataURL,
            }).show();
        }

        navigator.getUserMedia =    navigator.getUserMedia ||
                                    navigator.webkitGetUserMedia ||
                                    navigator.mozGetUserMedia ||
                                    navigator.msGetUserMedia;

        $('#media button#capture').click(function () {
            var img = $('#media img')[0];
            var video = $('#media video')[0];
            var canvas = $('#media canvas')[0];

            if (source) {
                if ($('#media video').is(':visible')) {
                    canvas.getContext('2d').drawImage(video, 0, 0);

                    $('#media img').attr({
                        src: canvas.toDataURL('image/webp'),
                    }).show();

                    $('#media video').hide();
                    $('#media button#capture').text('Take another Photo');

                    if (user === undefined) {
                        Photos.insert({user: 1, dataURL: canvas.toDataURL('image/webp')});
                    }

                    else {
                        Photos.update(user._id, {$set: {dataURL: canvas.toDataURL('image/webp')}});
                    }

                }

                else {
                    $('#media img').hide();
                    $('#media video').show();
                    $('#media button#capture').text('Snapshot!');
                }
            }

            else if (navigator.getUserMedia) {
                navigator.getUserMedia(constraints, function (stream) {
                    video.src = window.URL.createObjectURL(stream);

                    setTimeout(function () {
                        canvas.width = video.videoWidth;
                        canvas.height = video.videoHeight;
                    }, 100);

                    source = stream;

                    $('#media img').hide();
                    $('#media video').show();
                    $('#media button#capture').text('Snapshot!');
                });
            }

            else {
                alert('Sorry, your browser does not support capturing media.');
            }
        });

        $('#media button#upload').click(function () {
            alert('Sorry, this feature is not yet implemented.');
        });
    };
}

if (Meteor.isServer) {
    Meteor.startup(function () {
    });
}

And the HTML:

<head>
    <title>Media Capture</title>
    <style type="text/css">
        body {
            background-color: #f5f5f5;
            padding: 1em;
        }

        img,
        video {
            display: block;
            margin-bottom: 0.5em;
            width: 100%;
        }

        #media {
            background-color: #fff;
            border-radius: 5px;
            -moz-border-radius: 5px;
            -webkit-border-radius: 5px;
            border: 1px solid #e5e5e5;
            margin: 0 auto;
            max-width: 640px;
            min-width: 320px;
            padding: 10px;
        }
    </style>
</head>

<body>
    <div class="container">
        {{> media}}
    </div>
</body>

<template name="media">
    <div id="media">
        <img src="http://placehold.it/640x480">
        <video style="display: none;" autoplay></video>
        <canvas style="display: none;"></canvas>
        <button id="capture" class="btn btn-large btn-primary btn-block" type="submit">Take a Photo</button>
        <button id="upload" class="btn btn-large btn-primary btn-block" type="submit">Upload a Photo</button>
    </div>
</template>

PS: I don't know why this is happening but it seems that var user = Photos.findOne({user: 1}); returns undefined 2 out of 3 times. Refreshing a couple of time should eventually load the last snapshot taken.