Capture and playback of Video on Android (and IOS)

Hi there!
I am wondering if anyone can help me with this one. Although there seems to be a lot of questions out there in regards to this topic, I cannot seem to find anything that is particularly up to date.

Basically I am using ng-Cordova to capture video from the user’s phone. I’m using the code taken from the ng-Cordova site below (note - I only want one video of max 20 seconds).

$scope.captureVideo = function() {
var options = { limit: 1, duration: 20 };

$cordovaCapture.captureVideo(options).then(function(videoData) {
  // Success! Video data is here
}, function(err) {
  // An error occurred. Show a message to the user
});}

This correctly allows the user to take a video and returns back an array of mediaFiles (in my case with one entry). My problem is how do I then use that mediaFile to allow the user to play back the video in the ionic view? I am using videogular for the play back of videos stored on AWS and this is working perfectly. However no matter if I pass videogular or HTML5 video tag the files fullPath (file:/…) or localUrl (cdvfile:///…) nothing seems to show on an Android phone (sadly I do not have a iPhone to test on but hear it may be much easier).

From my reading, I realise that Android has some strict security around this feature but if anyone can point me in the right direction or demo with a bit of code I would be very grateful as this has been causing me major headaches.

Thanks in advance

Can anyone help me out on this one? I’m going a little crazy trying to find a solution. My latest thought is to use Cordova-Httpd plugin to start a server for the video files (though I’m unsure exactly how to do it).

Thanks

I’ve been struggling to get this fixed but still cannot find a way. Can anyone please shed some light on this?

@mhartington as a guru of all things ionic. Can I possibly trouble you for some input? I’m going a bit nuts.

Thanks

Just making sure, are you trying to do this within the ionic view app or just a regular ionic app?

Hi, thanks so much for your response. I’m just trying to do this within a normal ionic app. I’ve tried several combinations of paths but still with no luck.

@Hawkeye anything new ? I want to display local files that just have been captured too !

Hi @JerryBels,
So I finally got this working by using the CordovaHttpd plugin. In brief, I created a factory with the following functions

function startServer(){
        var dfd = $q.defer();

        if(cordova && cordova.plugins && cordova.plugins.CorHttpd){
            httpd = cordova.plugins.CorHttpd;

            httpd.getURL(function(url) {
                if (url.length > 0) {
                    dfd.resolve(url);
                } else {
                    httpd.startServer({
                        'www_root' : "/",
                        'port' : 8080,
                        'localhost_only' : false
                    }, function( url ){
                        // if server is up, it will return the url of http://<server ip>:port/
                        // the ip is the active network connection
                        // if no wifi or no cell, "127.0.0.1" will be returned.
                        dfd.resolve(url);
                    }, function( error ){
                        dfd.reject(error);
                    });
                }
            });
        } else {
            dfd.reject('plugin not available');
        }

        return dfd.promise;
    }

    function stopServer(){
        var dfd = $q.defer();

        if ( httpd ) {
            // call this API to stop web server
            httpd.stopServer(function(){
                dfd.resolve();
                httpd = null;
            },function( error ){
                dfd.reject();
            });
        } else {
            dfd.reject('CorHttpd plugin not available/ready.');
        }

        return dfd.promise;
    }

In my controller, I had the following code

ucHTTPServer.startServer().then(function(url){
                        var absPath = videoFile[0].fullPath.replace('file:', '');
                        scope.videoSrc = [{src: $sce.trustAsResourceUrl(url + absPath), type: videoFile[0].type}];
                    }, function(error){

                    });

The videofile variable is returned from the cordova capture plugin (i.e. $cordovaCapture.captureVideo(options).then(function(videoData)…). Please also note that I’m using videogular to play the video but I think it should work with basic HTML5 video tag.

Now I’m struggling to upload the video to Amazon S3 bucket. Let me know if you have any further questions.

Hope this helps!

2 Likes

Awesome ! I will try this soon :smile:

Thank you @Hawkeye great solution. I thought about it, but I didn’t know that there was an httpd plugin for Cordova (I’m new to Javascript, but there’s a lot of good stuff).
Your solution works flawlessly, you saved me a big headache. I’m sorry I can’t help you with Amazon S3.

Thank you again.

can u send me the demo project for ths one…

Hi, Sadly I don’t have a demo project for this one as have now done it slightly differently and removed the need for CordovaHttpD. What exactly are you trying to do? Just play video on Android?

Thank you for sharing your solution, Like many others, I’ve been struggling with HTML5 video playback of “cdvfile://” references (all MP4) and will try implementing your innovative CorHttpd solution. I am curious why you abandoned CorHttpd - did you find a more direct method of playing local videos?

Here is my directive where in part I play the video. It seems to work without the need to CordovaHttpd plugin. It assumes that android is greater than version 4 but there is the minimum for my app anyway.

$scope.$watchGroup([‘vm.localVideo’,‘vm.localVideo.type’], function(vals){
vm.video = true;
if(vals[1] && vals[1].match(/video//)){
if (ionic.Platform.isIOS()){
if (lastUrl) {
URL.revokeObjectURL(lastUrl);
}
vm.videoSrc = [{src: $sce.trustAsResourceUrl((lastUrl = URL.createObjectURL(vals[0]))), type: vals[1]}];
} else if (ionic.Platform.isAndroid() && ionic.Platform.version() >= ‘4’) {
vm.videoSrc = [{src: $sce.trustAsResourceUrl(vals[0].fullPath), type: vals[1]}];
} else {
vm.errorMessage = “Cannot playback video!”;
}
}
});

You could always at the CordovaHttpd code above for anything less than 4.

ucHTTPServer.startServer().then(function(url){
                        var absPath = videoFile[0].fullPath.replace('file:', '');
                        scope.videoSrc = [{src: $sce.trustAsResourceUrl(url + absPath), type: videoFile[0].type}];
                    }, function(error){
                    });

Remember I’m using videogular. Hope this helps!

1 Like