iosnsurlsessiontitanium-alloyappcelerator-mobiletitanium-modules

how to download video using URLSession, save and play it in appcelerator titanium?


I am trying to download and save a video using URLSession and then play it in video player. But somehow it's not playing, rather it's crashing the app. Here's the code for it.I have tried almost everything to read the exact path of file using nativePath , getNativePath(), file.resolve(), but nothing seems to work. Take a look at the code and suggest a solution. This is for iOS. (iOS Version 8.4)

UPDATED CODE :

    var args = arguments[0] || {};

    var vidWin = $.winTestVideo;
    var isDownloading = false;

    var urlSession = require("com.appcelerator.urlSession");
    var downloadSession;

    var urlArray = ["http://www.kaltura.com/p/{PARTNERID}/sp/{SUBPARTNERID}/playManifest/entryId/{entryId}/format/applhttp/protocol/http/flavorId/{flavorId}/video.mp4",
"http://www.kaltura.com/p/{PARTNERID}/sp/{SUBPARTNERID}/playManifest/entryId/{entryId}/format/applhttp/protocol/http/flavorId/{flavorId}/video.mp4"];

    var urlArrIndex = 0;
    var progress;
    var videoPlayer;
    var imageUrl = 'http://dreamatico.com/data_images/rose/rose-4.jpg';
    //'http://cdn.playbuzz.com/cdn/5d41f0c6-2688-47fe-85cf-82890ef6d91d/45611be8-42f9-4d02-9b63-f7195c0dc18c_560_420.jpg';
    var img;
    function onLoad() {
        Alloy.Globals.CurrentWindowName = 'testvideoplayer';
        var triggerBtn = Ti.UI.createButton({
            top : 10,
            width : Ti.UI.FILL,
            height : 40,
            backgroundColor : "#cccccc",
            color : "#000000",
            title : "Download Videos"
        });
        vidWin.add(triggerBtn);
        triggerBtn.addEventListener('click', downloadVideoBackround2);

        progress = Titanium.UI.createProgressBar({
            width : 200,
            height : 20,
            min : 0,
            max : 1,
            value : 0,
            top : 60,
            backgroundColor : "#0000ff",
            style : Ti.UI.iPhone.ProgressBarStyle.BAR,

        });

        vidWin.add(progress);

        img = Ti.UI.createImageView({
            width : 100,
            height : 100,
            backgroundColor : "#cccccc"
        });
        //vidWin.add(img);

        //videoPlayer.play();

    }

    function createVideoPlayer() {
        videoPlayer = Ti.Media.createVideoPlayer({
            width : Ti.UI.FILL,
            height : 240,
            top : 100,
            mediaControlStyle : Titanium.Media.VIDEO_CONTROL_DEFAULT,
            scalingMode : Titanium.Media.VIDEO_SCALING_ASPECT_FIT,
            backgroundColor : "#000000",

        });
        vidWin.add(videoPlayer);
        videoPlayer.removeEventListener('playbackstate', playbackStateEventListener);
        videoPlayer.addEventListener('playbackstate', playbackStateEventListener);
    }

    // Require in the urlSession module
    var urlSession = require("com.appcelerator.urlSession");
    var session;
    // App UI

    function playbackStateEventListener(evt) {
        Ti.API.error("PlaybackStateEventListener  : " + JSON.stringify(evt));
    }

    function downloadVideoBackround2(evt){
        // Create a session configuration
        // The string parameter is an arbitrary string used to identify the session in events
        var sessionConfig = urlSession.createURLSessionBackgroundConfiguration("com.appcelerator.test");
        // Create a session
        session = urlSession.createURLSession(sessionConfig);
        // Create a background download task to get the asset with the URL
        urlSession.backgroundDownloadTaskWithURL(session,urlArray[0].replace('applhttp','url'));
        progress.show();
    }

    // Monitor this event to receive updates on the progress of the download
    Ti.App.iOS.addEventListener("downloadprogress", function(e) {
        // Update the progress indicator
        Ti.API.error("DOWNLOAD PROGRESS : " + e.totalBytesWritten + "/" + e.totalBytesExpectedToWrite);
        progress.value = (e.totalBytesWritten / e.totalBytesExpectedToWrite);
    });

    // Monitor this event to know when the download completes
    Ti.App.iOS.addEventListener("downloadcompleted", function(e) {
        Ti.API.error("download completed " + JSON.stringify(e));
        // Update the image
        try {

            var file = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, 'myplvideo.mp4');
            if (!file.exists()) {
                file.createFile();
            }
            file.write(e.data);
            Ti.API.error('data : ' + e.data.length);
            Ti.API.error('file : ' + file.nativePath);
            Ti.API.error('file resolve path :' + file.resolve());
            progress.hide();

            // Notify the user the download is complete if the application is in the background
            setTimeout(function() {

                //videoPlayer.media = file;
                createVideoPlayer();
                videoPlayer.media = file;
                urlSession.finishTasksAndInvalidate(session);
                //videoPlayer.play();
            }, 3000);

            //alert('Download completed!');
            /*
             Ti.App.iOS.scheduleLocalNotification({
             alertAction : "update",
             // Alert will display the following message
             alertBody : "Download was successfull",
             // The badge value in the icon will be changed to 1
             badge : 1,
             // Alert will be sent in three seconds
             date : new Date(new Date().getTime() + 3000),
             });*/

        } catch(ex) {
            Ti.API.error('download completed : ' + ex);
        }
    });
    // Monitor this event to know when all session tasks have completed
    Ti.App.iOS.addEventListener('sessioncompleted', function(e) {
        try {

            Ti.API.error("sessioncompleted " + JSON.stringify(e));
            if (e.success) {
                //alert("Downloads completed successfully.");
            }
        } catch(ex) {
            Ti.API.error('Exception session completed : ' + ex);
        }
    });

The app is crashing when i assign the file to videoPlayer's media property. But when i download the file using HttpClient, it works fine. Not really sure why it's happening as i can't see any error in the logs.

Here are the logs. I have used the [Error] for highlighting the important logging.

[ERROR] :  DOWNLOAD PROGRESS : 67470/5794757
[ERROR] :  DOWNLOAD PROGRESS : 133006/5794757
[ERROR] :  DOWNLOAD PROGRESS : 199614/5794757
[ERROR] :  DOWNLOAD PROGRESS : 266222/5794757
[ERROR] :  DOWNLOAD PROGRESS : 275982/5794757
[ERROR] :  DOWNLOAD PROGRESS : 341518/5794757
[ERROR] :  DOWNLOAD PROGRESS : 408126/5794757
[ERROR] :  DOWNLOAD PROGRESS : 474734/5794757
[ERROR] :  DOWNLOAD PROGRESS : 541342/5794757
[ERROR] :  DOWNLOAD PROGRESS : 609398/5794757
[ERROR] :  DOWNLOAD PROGRESS : 677454/5794757
[ERROR] :  DOWNLOAD PROGRESS : 745510/5794757
[ERROR] :  DOWNLOAD PROGRESS : 758166/5794757
[ERROR] :  DOWNLOAD PROGRESS : 823702/5794757
[ERROR] :  DOWNLOAD PROGRESS : 897550/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1048142/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1114750/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1182806/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1249414/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1316022/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1382630/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1385150/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1450686/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1518742/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1586798/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1653406/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1720014/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1786622/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1854678/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1921286/5794757
[ERROR] :  DOWNLOAD PROGRESS : 1989342/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2057398/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2059918/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2125454/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2205094/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2271702/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2341206/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2342278/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2407814/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2410334/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2475870/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2542478/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2609086/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2675694/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2676766/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2742302/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2808910/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2876966/5794757
[ERROR] :  DOWNLOAD PROGRESS : 2943574/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3010182/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3076790/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3143398/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3212902/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3274790/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3340326/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3422862/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3557526/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3624134/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3692190/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3758798/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3825406/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3893462/5794757
[ERROR] :  DOWNLOAD PROGRESS : 3960070/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4026678/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4094734/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4161342/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4227950/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4294558/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4362614/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4430670/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4497278/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4498350/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4563886/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4630494/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4697102/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4699622/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4765158/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4831766/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4898374/5794757
[ERROR] :  DOWNLOAD PROGRESS : 4964982/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5031590/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5098198/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5106510/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5172046/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5319742/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5320814/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5386350/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5455854/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5523910/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5591966/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5658574/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5726630/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5794686/5794757
[ERROR] :  DOWNLOAD PROGRESS : 5794757/5794757
[ERROR] :  download completed {"taskIdentifier":1,"data":{},"bubbles":true,"type":"downloadcompleted","source":{},"cancelBubble":false}
[ERROR] :  open on /var/mobile/Containers/Data/Application/9FBAAEB4-4878-4611-8BCC-EFC112AF9777/Documents/myplvideo.mp4: File exists
[ERROR] :  data : 5794757
[ERROR] :  file : file:///var/mobile/Containers/Data/Application/9FBAAEB4-4878-4611-8BCC-EFC112AF9777/Documents/myplvideo.mp4
[ERROR] :  file resolve path :/var/mobile/Containers/Data/Application/9FBAAEB4-4878-4611-8BCC-EFC112AF9777/Documents/myplvideo.mp4
[ERROR] :  sessioncompleted {"success":true,"message":"","errorCode":0,"taskIdentifier":1,"bubbles":true,"type":"sessioncompleted","source":{},"cancelBubble":false}

Solution

  • My quick guess would be that you have a race condition. Inside of your setTimeout you never actually check to see if the file has been written, like you do when you have finished downloading, assuming at this point that 3s is long enough.

    // Notify the user the download is complete if the application is in the background
    setTimeout(function() {
      //videoPlayer.media = file;
      createVideoPlayer();
      videoPlayer.media = file;
      urlSession.finishTasksAndInvalidate(session);
      //videoPlayer.play();
    }, 3000);
    

    Additionally, the xcode logs for the device or simulator should be telling you where/what crashed (these may not always appear in the titanium logs)