Source: models/production/stream.js

define('application/models/production/stream', [
    'application/models/stream',
    'rofl/lib/utils',
    'rofl/media/source',
    'rofl/devices/mediaplayer/mediaplayer',
    'antie/runtimecontext',
    'rofl/media/drm/item/playready',
    'application/managers/feature'
], function (
    Base,
    Utils,
    MediaSource,
    MediaPlayer,
    RuntimeContext,
    PlayReadyDRMItem,
    FeatureManager
) {
    'use strict';

    var device = RuntimeContext.getDevice(),
        application = RuntimeContext.getCurrentApplication(),
        capitalizeFirstLetter = function (text) {
            return text.charAt(0).toUpperCase() + text.slice(1);
        },
        featureManager = FeatureManager.getInstance(),
        baseUrl = '101/1.2.0/A/nld/smarttv/kpn/CONTENT/VIDEOURL',
        commonUrlParams = 'deviceId={{deviceId}}&profile={{profile}}',
        ENDPOINTS = {
            LIVE: baseUrl + '/LIVE/{{contentId}}/{{assetId}}/?' + commonUrlParams,
            REPLAY: baseUrl + '/LIVE/{{contentId}}/{{assetId}}/?time={{startTime}}-{{endTime}}&' + commonUrlParams,
            VOD: baseUrl + '/PROGRAM/{{contentId}}/{{assetId}}?' + commonUrlParams,
            VOD_MOVIE: baseUrl + '/VOD/{{contentId}}/{{assetId}}?' + commonUrlParams,
            RESTART: baseUrl + '/LIVE/{{contentId}}/{{assetId}}/?time={{startTime}}&' + commonUrlParams,
            RECORDING: baseUrl + '/RECORDING/{{contentId}}/{{assetId}}/?startDeltaTime={{startTime}}&' + commonUrlParams
        },
        PROFILES = {
            DASH: 'M21',
            SMOOTH: 'S22'
        };

    return Base.extend({

        /**
         * Resolves the endpoint.
         *
         * @param {Object} params - The parameters.
         * @param {string} params.type - The stream type. LIVE, RESTART or VOD.
         * @param {string} params.contentId - The content id.
         * @param {string} params.assetId - The asset id.
         * @param {boolean} [params.stop] - True if it should stop the stream. Optional.
         * @returns {string} - The endpoint.
         */
        resolveEndpoint: function (params) {
            var now = application.getDate().getTime(),
                timeGap = 24 * 60 * 60 * 1000,
                replayBuffer = 15 * 60 * 1000,
                type,
                endpoint,
                profile,
                streamType;

            if (!params || !params.type || !params.contentId) {
                throw 'Missing type or content id.';
            }

            type = params.type;
            streamType = featureManager.getStreamType(type);
            profile = PROFILES[streamType.toUpperCase()];
            endpoint = ENDPOINTS[type];

            if (type === 'VOD') {
                if ((params.replayAssetId && params.replayContentId) && (now - params.endTime < replayBuffer)) {
                    endpoint = ENDPOINTS.REPLAY;
                    params.contentId = params.replayContentId;
                    params.assetId = params.replayAssetId;
                }

                if (now - params.startTime < timeGap) {
                    params.startTime -= (5 * 60 * 1000);
                }
            }

            params.profile = profile;
            params.deviceId = device.getUdid();
            this._type = type;

            return Utils.formatTemplate(endpoint, params);
        },

        /**
         * Determine the device MimeType.
         *
         * @param {string} type - The stream type.
         * @returns {string} - The MimeType.
         * @private
         */
        _determineStreamMimeType: function (type) {
            var streamType = featureManager.getStreamType(type),
                streamMimeType;

            switch (streamType.toUpperCase()) {
                case 'DASH':
                    streamMimeType = MediaSource.MIME_TYPES.mpd;
                    break;
                case 'SMOOTH':
                    streamMimeType = MediaSource.MIME_TYPES.ism;
                    break;
                default:
                    throw Error('Streamtype ' + streamType.toUpperCase() + ' is not handled');
            }

            return streamMimeType;
        },

        /**
         * Validates the response.
         *
         * @param {Object} response - The response.
         * @returns {boolean} - True if valid.
         */
        validateResponse: function (response) {
            return response.resultCode === 'OK'
                && Utils.hasNested(response, 'resultObj', 'src', 'sources');
        },

        /**
         * Return true in case failed request should be repeated.
         *
         * @param  {Object} response - Response.
         * @returns {boolean} True if retry.
         */
        shouldRetry: function (response) {
            return response.errorDescription !== '403-10146';
        },

        /**
         * Transforms the response.
         *
         * @param {Object} response - The response.
         * @returns {Object} - The media source.
         */
        transformFrom: function (response) {
            var data = Utils.getNested(response, 'resultObj', 'src', 'sources'),
                streamUrl = data.src,
                deviceBrand = device.getBrand(),
                streamType = ((this._type === 'VOD' || this._type === 'VOD_MOVIE') || 'RECORDING') ? MediaPlayer.TYPE.VIDEO : MediaPlayer.TYPE.LIVE_VIDEO,
                streamMimeType = this._determineStreamMimeType(this._type),
                mediaSource = new MediaSource(streamUrl, streamType, streamMimeType),
                drmItem = new PlayReadyDRMItem(),
                licenseOverride;

            mediaSource.setStartBitRate(2500000);

            licenseOverride = this._getLicenseOverrideUrl(data);

            if (licenseOverride) {
                drmItem.setLicenseOverrideUri(licenseOverride);
            }

            if (deviceBrand === 'hbbtv' || deviceBrand === 'lg') {
                drmItem.setEmbeddedLicense(false);
            }

            drmItem.setProtectionHeaderUTF16(true);

            if (licenseOverride) {
                mediaSource.setDrmItem(drmItem);
            }

            return mediaSource;
        },

        /**
         * Returns the license override url.
         *
         * @param {Object} data - The data.
         * @returns {string|null} - The license override url or null..
         * @private
         */
        _getLicenseOverrideUrl: function (data) {
            var contentProtection = Utils.getNested(data, 'contentProtection'),
                url = Utils.getNested(contentProtection, 'playready', 'licenseAcquisitionURL');

            if (!url || !contentProtection) {
                return null;
            }

            Utils.each(contentProtection, function (value, key) {
                var object = {};

                if (key !== 'playready') {
                    object[capitalizeFirstLetter(key)] = value;

                    url = Utils.addToQueryStringOfURL(url, object);
                }
            });

            return url;
        }
    });
});