Apple Fairplay TVML can't get AssetId, certificate and key

After spending many days on search on google about how to use Fairplay in TVML (Apple TV), i can't get this work.

I am trying to use Apple FairPlay using TVML, there is no clear documentation or example that can help for integration.

in my code on singleVideo.loadCertificate function i am trying to get the assetId, but it's keep calling the same function with out errors


can anyone help me with integration and tell me where is the error in my code?

singleVideo.loadAssetID = function(url, callback) {
        console.log("===== HERE === ");
        console.log("======== loadAssetID=======");
        console.log(url);


        var extractContentId = function (initData) {


            var uri = initData;
            var uriParts = uri.split('://');
            var protocol = uriParts[0].slice(-3);
            var contentId = uriParts.length > 0 ? uriParts[1] : '';
            return protocol.toLowerCase() == 'skd' ? contentId : '';
        };


        asset=extractContentId(url);
        var error=null;
        console.log("->AssetID="+ asset);


        callback(btoa(asset));
    }


    singleVideo.loadCertificate = function(url, callback) {


        console.log("==== Getting the certificate");


        var certUrl = "cer url";


        var request = new XMLHttpRequest();
        request.responseType = 'arraybuffer';
        request.addEventListener('load', function () {
            console.log( "RESPONSE ");
            console.log( request.getAllResponseHeaders () );
            console.log( request.response );
            var base64 = btoa(new Uint8Array(request.response)
                .reduce((data, byte) => data + String.fromCharCode(byte), '')
            );
            callback( base64);


        }, false);
        request.addEventListener('error', function (error) {
            console.log(error)}
        , false);




        request.open('GET', certUrl, true);
        request.setRequestHeader('Pragma', 'Cache-Control: no-cache');
        request.setRequestHeader("Cache-Control", "max-age=0");
        request.send();




    }


    singleVideo.loadKey = function(url, requestData, callback) {
        console.log("======= [FPS] getting the FPS asset key");




        var assetID = asset;
        var postBody = "payload=" + base64EncodeUint8Array(requestData) + "&id=" + base64EncodeUint8Array(assetID);


        var keyUrl = "server key url";
        console.log("======= [FPS] keyurl: " + keyUrl + " sending " + postBody);




        var request = new XMLHttpRequest();
        request.responseType = 'text';
        request.addEventListener('load', function(){
            console.log(request);
            callback(request.responseText, null, null);
        }, false);
        request.addEventListener('error', function(){
            console.log(request);
            callback(null, null, "Got bad response from server: " + request.status)
        }, false);
        request.open('POST', keyUrl, true);
        request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        request.send(postBody);
    }