Search code examples
androidioscordovahtml5-videocordova-plugins

Play audio and video in Cordova application which works in Android, IOS and desktop devices


I need to play audio and video in my Hybrid Application which should works in Android, IOS and windows desktops. Application is build on top of JQuery Mobile wrapped with Cordova for Mobile.

HTML5 video tag works in browser but not in Android. I browsed and found few plugins specific to a platform(Android) where we have to add code in .java file which I don't want to do.

<video width="350" height="150" controls>
            <source  type="video/m4v" src="http://techslides.com/demos/sample-videos/small.mp4" >
 </video>

I also looked at Media API of Cordova and I found that works with Audio ( http://cordova.apache.org/docs/en/2.4.0/cordova_media_media.md.html ).

Is there any way by which I can play Audio as well as Video that works in Android, IOS and desktop browsers.


Solution

  • After several hours of finding problems, this solution works for me, in desktop and mobile browsers and Cordova on iOS and Android. It addresses the following findings:

    • On iOS, <audio> works, but without volume control.
    • On Android, <audio> doesn't work, the Media plugin is needed.
    • On iOS, the src attribut of the <audio> element can be used for the Media object, on Android the src property of the js Audio object works.
    • The setVolume() method must be called directly after play() to take effect.
    • On Android, the Media event handlers were never called. That's bad, because according to the documentation, the release() method should be called after playback. No solution yet for this issue.

    The example has a static audio element with a src path relative to index.html, inside Cordova's www folder. On startup the script checks for Cordova and sets up a DeviceReady handler, if so. Then the audio element is found and gets played via playAudio().

    HTML head:

    <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline' data: gap: https://ssl.gstatic.com; style-src 'self' 'unsafe-inline'; media-src *">
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1">
    
    <title>Audio Example</title>
    
    <script src="cordova.js"></script>
    
    <script>
        var config = {
            audioVolume: 0.25
        }
    
        // Use onDeviceReady if we run in Cordova
        window.addEventListener('load', function(){
            if (window.Cordova) {
                console.log("Cordova found");
                document.addEventListener('DeviceReady', start, false);
            } else {
                console.log("Cordova not found, using pure html audio")
                start();
            }
        }, false);
    
        function start() {
            var audioElement = document.querySelector("audio");
            playAudio(audioElement);
        }
    
        function playAudio(ae) {
            var source, me, successFunction, onSuccess, onError;
    
            onSuccess = function() {
                console.log('Playing ' + ae.src + ' at volume ' + config.audioVolume);
                me.release();
            }
    
            onError = function(e) {
                console.log('ERROR on playing ' + ae.src + ' at volume ' + config.audioVolume
                            + ': (' + e.code + ') ' + e.message);
            }
    
            onStatusChange = function(s){
                console.log('Media status changed to ' + s);
                if (s === Media.MEDIA_STOPPED) onSuccess();
            }
    
           // If running in Cordova and Media plugin loaded, use that
            if (typeof Media === "function") { 
                source = device.platform === 'iOS'
                            ? ae.getAttribute('src')     // relative path
                            : ae.src;                    // file-url, platform-dependant
                me = new Media(source, onSuccess, onError, onStatusChange);
                me.play();     
                me.setVolume(config.audioVolume);   
            } else {
                ae.volume = config.audioVolume;
                ae.play();
            }
        }
    
    </script>
    

    HTML body:

    <audio src="sounds/mysound.mp3"></audio>