com.google.android.media.tv.companionlibrary.model.Advertisement Java Examples

The following examples show how to use com.google.android.media.tv.companionlibrary.model.Advertisement. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 6 votes vote down vote up
@Override
public TvPlayer onAdReadyToPlay(String adVideoUrl) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE);
    }

    onPlayAdvertisement(
            new Advertisement.Builder(mAdvertisement)
                    .setRequestUrl(adVideoUrl)
                    .build());
    setTvPlayerSurface(mSurface);
    setTvPlayerVolume(mVolume);

    long currentTimeMs = System.currentTimeMillis();
    long adStartTime = mAdvertisement.getStartTimeUtcMillis();
    if (adStartTime > 0 && adStartTime < currentTimeMs) {
        getTvPlayer().seekTo(currentTimeMs - adStartTime);
    }
    return getTvPlayer();
}
 
Example #2
Source File: EpgSyncWithAdsJobService.java    From xipl with Apache License 2.0 6 votes vote down vote up
/**
 * Shift advertisement time to match program playback time. For channels with repeated program,
 * the time for current program may vary from what it was defined previously.
 *
 * @param oldProgramStartTimeMs Outdated program start time.
 * @param newProgramStartTimeMs Updated program start time.
 */
private static void shiftAdsTimeWithProgram(
        InternalProviderData internalProviderData,
        long oldProgramStartTimeMs,
        long newProgramStartTimeMs) {
    if (internalProviderData == null) {
        return;
    }
    long timeShift = newProgramStartTimeMs - oldProgramStartTimeMs;
    List<Advertisement> oldAds = internalProviderData.getAds();
    List<Advertisement> newAds = new ArrayList<>();
    for (Advertisement oldAd : oldAds) {
        newAds.add(
                new Advertisement.Builder(oldAd)
                        .setStartTimeUtcMillis(oldAd.getStartTimeUtcMillis() + timeShift)
                        .setStopTimeUtcMillis(oldAd.getStopTimeUtcMillis() + timeShift)
                        .build());
    }
    internalProviderData.setAds(newAds);
}
 
Example #3
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 6 votes vote down vote up
@Override
public boolean handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_PLAY_CONTENT:
            mCurrentProgram = (Program) msg.obj;
            playCurrentContent();
            return true;
        case MSG_PLAY_AD:
            return insertAd((Advertisement) msg.obj);
        case MSG_PLAY_RECORDED_CONTENT:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                mPlayingRecordedProgram = true;
                mRecordedProgram = (RecordedProgram) msg.obj;
                playRecordedContent();
            }
            return true;
    }
    return false;
}
 
Example #4
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 6 votes vote down vote up
private void calculateElapsedTimesFromCurrentTime() {
    long currentTimeMs = getCurrentTime();
    mElapsedAdsTime = 0;
    mElapsedProgramTime = currentTimeMs - mCurrentProgram.getStartTimeUtcMillis();
    if (mCurrentProgram.getInternalProviderData() != null) {
        List<Advertisement> ads = mCurrentProgram.getInternalProviderData().getAds();
        for (Advertisement ad : ads) {
            if (ad.getStopTimeUtcMillis() < (currentTimeMs + PAST_AD_BUFFER_MILLIS)) {
                // Subtract past ad playback time to seek to
                // the correct content playback position.
                long adDuration = ad.getStopTimeUtcMillis() - ad.getStartTimeUtcMillis();
                mElapsedAdsTime += adDuration;
                mElapsedProgramTime -= adDuration;
            }
        }
    } else {
        Log.w(
                TAG,
                "Failed to get program provider data for "
                        + mCurrentProgram.getTitle()
                        + ". Try to do an EPG sync.");
    }
}
 
Example #5
Source File: EpgSyncJobService.java    From xipl with Apache License 2.0 6 votes vote down vote up
/**
 * Shift advertisement time to match program playback time. For channels with repeated program,
 * the time for current program may vary from what it was defined previously.
 *
 * @param oldProgramStartTimeMs Outdated program start time.
 * @param newProgramStartTimeMs Updated program start time.
 */
private void shiftAdsTimeWithProgram(InternalProviderData internalProviderData,
                                     long oldProgramStartTimeMs, long newProgramStartTimeMs) {
    if (internalProviderData == null) {
        return;
    }
    long timeShift = newProgramStartTimeMs - oldProgramStartTimeMs;
    List<Advertisement> oldAds = internalProviderData.getAds();
    List<Advertisement> newAds = new ArrayList<>();
    for (Advertisement oldAd : oldAds) {
        newAds.add(new Advertisement.Builder(oldAd)
                .setStartTimeUtcMillis(oldAd.getStartTimeUtcMillis() + timeShift)
                .setStopTimeUtcMillis(oldAd.getStopTimeUtcMillis() + timeShift)
                .build());
    }
    internalProviderData.setAds(newAds);
}
 
Example #6
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 6 votes vote down vote up
private void calculateElapsedTimesFromCurrentTime() {
    long currentTimeMs = getCurrentTime();
    mElapsedAdsTime = 0;
    mElapsedProgramTime = currentTimeMs - mCurrentProgram.getStartTimeUtcMillis();
    if (mCurrentProgram.getInternalProviderData() != null) {
        List<Advertisement> ads = mCurrentProgram.getInternalProviderData().getAds();
        for (Advertisement ad : ads) {
            if (ad.getStopTimeUtcMillis() < (currentTimeMs + PAST_AD_BUFFER_MILLIS)) {
                // Subtract past ad playback time to seek to
                // the correct content playback position.
                long adDuration = ad.getStopTimeUtcMillis() - ad.getStartTimeUtcMillis();
                mElapsedAdsTime += adDuration;
                mElapsedProgramTime -= adDuration;
            }
        }
    } else {
        Log.w(
                TAG,
                "Failed to get program provider data for "
                        + mCurrentProgram.getTitle()
                        + ". Try to do an EPG sync.");
    }
}
 
Example #7
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 6 votes vote down vote up
@Override
public boolean handleMessage(Message msg) {
    switch (msg.what) {
        case MSG_PLAY_CONTENT:
            mCurrentProgram = (Program) msg.obj;
            playCurrentContent();
            return true;
        case MSG_PLAY_AD:
            return insertAd((Advertisement) msg.obj);
        case MSG_PLAY_RECORDED_CONTENT:
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                mPlayingRecordedProgram = true;
                mRecordedProgram = (RecordedProgram) msg.obj;
                playRecordedContent();
            }
            return true;
    }
    return false;
}
 
Example #8
Source File: EpgSyncWithAdsJobService.java    From androidtv-sample-inputs with Apache License 2.0 6 votes vote down vote up
/**
 * Shift advertisement time to match program playback time. For channels with repeated program,
 * the time for current program may vary from what it was defined previously.
 *
 * @param oldProgramStartTimeMs Outdated program start time.
 * @param newProgramStartTimeMs Updated program start time.
 */
private static void shiftAdsTimeWithProgram(
        InternalProviderData internalProviderData,
        long oldProgramStartTimeMs,
        long newProgramStartTimeMs) {
    if (internalProviderData == null) {
        return;
    }
    long timeShift = newProgramStartTimeMs - oldProgramStartTimeMs;
    List<Advertisement> oldAds = internalProviderData.getAds();
    List<Advertisement> newAds = new ArrayList<>();
    for (Advertisement oldAd : oldAds) {
        newAds.add(
                new Advertisement.Builder(oldAd)
                        .setStartTimeUtcMillis(oldAd.getStartTimeUtcMillis() + timeShift)
                        .setStopTimeUtcMillis(oldAd.getStopTimeUtcMillis() + timeShift)
                        .build());
    }
    internalProviderData.setAds(newAds);
}
 
Example #9
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 6 votes vote down vote up
@Override
public TvPlayer onAdReadyToPlay(String adVideoUrl) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_UNAVAILABLE);
    }

    onPlayAdvertisement(
            new Advertisement.Builder(mAdvertisement)
                    .setRequestUrl(adVideoUrl)
                    .build());
    setTvPlayerSurface(mSurface);
    setTvPlayerVolume(mVolume);

    long currentTimeMs = System.currentTimeMillis();
    long adStartTime = mAdvertisement.getStartTimeUtcMillis();
    if (adStartTime > 0 && adStartTime < currentTimeMs) {
        getTvPlayer().seekTo(currentTimeMs - adStartTime);
    }
    return getTvPlayer();
}
 
Example #10
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 5 votes vote down vote up
private boolean scheduleNextAd() {
    mHandler.removeMessages(MSG_PLAY_AD);
    if (mPlayingRecordedProgram) {
        return false;
    }
    long currentTimeMs = getCurrentTime();
    if (mCurrentProgram.getInternalProviderData() != null) {
        List<Advertisement> ads = mCurrentProgram.getInternalProviderData().getAds();
        Advertisement adToPlay = null;
        long timeTilAdToPlay = 0;
        for (Advertisement ad : ads) {
            if (ad.getStopTimeUtcMillis() > currentTimeMs + PAST_AD_BUFFER_MILLIS) {
                long timeTilAd = ad.getStartTimeUtcMillis() - currentTimeMs;
                if (timeTilAd < 0) {
                    // If tuning to the middle of a scheduled ad, the played portion
                    // of the ad will be skipped by the AdControllerCallback.
                    mHandler.sendMessage(mHandler.obtainMessage(MSG_PLAY_AD, ad));
                    return false;
                } else if (adToPlay == null || timeTilAd < timeTilAdToPlay) {
                    adToPlay = ad;
                    timeTilAdToPlay = timeTilAd;
                }
            }
        }

        if (adToPlay != null) {
            Message pauseContentPlayAdMsg = mHandler.obtainMessage(MSG_PLAY_AD, adToPlay);
            mHandler.sendMessageDelayed(pauseContentPlayAdMsg, timeTilAdToPlay);
        }
    } else {
        Log.w(
                TAG,
                "Failed to get program provider data for "
                        + mCurrentProgram.getTitle()
                        + ". Try to do an EPG sync.");
    }
    return true;
}
 
Example #11
Source File: CumulusJobService.java    From CumulusTV with MIT License 5 votes vote down vote up
@Override
    public List<Channel> getChannels() {
        // Build advertisement list for the channel.
        Advertisement channelAd = new Advertisement.Builder()
                .setType(Advertisement.TYPE_VAST)
                .setRequestUrl(TEST_AD_REQUEST_URL)
                .build();
        List<Advertisement> channelAdList = new ArrayList<>();
        channelAdList.add(channelAd);

        InternalProviderData ipd = new InternalProviderData();
//        ipd.setAds(channelAdList);
        ipd.setRepeatable(true);
        ipd.setVideoType(TvContractUtils.SOURCE_TYPE_HLS);

        try {
            List<Channel> channels = ChannelDatabase.getInstance(this).getChannels(ipd);
            // Add app linking
            for (int i = 0; i < channels.size(); i++) {
                JsonChannel jsonChannel =
                        ChannelDatabase.getInstance(this).findChannelByMediaUrl(
                                channels.get(i).getInternalProviderData().getVideoUrl());
                Channel channel = new Channel.Builder(channels.get(i))
                    .setAppLinkText(getString(R.string.quick_settings))
                    .setAppLinkIconUri("https://github.com/Fleker/CumulusTV/blob/master/app/src/m" +
                        "ain/res/drawable-xhdpi/ic_play_action_normal.png?raw=true")
                    .setAppLinkPosterArtUri(channels.get(i).getChannelLogo())
                    .setAppLinkIntent(PlaybackQuickSettingsActivity.getIntent(this, jsonChannel))
                    .build();
                Log.d(TAG, "Adding channel " + channel.getDisplayName());
                channels.set(i, channel);
            }
            Log.d(TAG, "Returning with " + channels.size() + " channels");
            return channels;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        Log.w(TAG, "No channels found");
        return null;
    }
 
Example #12
Source File: SampleJobService.java    From androidtv-sample-inputs with Apache License 2.0 5 votes vote down vote up
@Override
public List<Channel> getChannels() {
    // Add channels through an XMLTV file
    XmlTvParser.TvListing listings = RichFeedUtil.getRichTvListings(this);
    List<Channel> channelList = new ArrayList<>(listings.getChannels());

    // Build advertisement list for the channel.
    Advertisement channelAd = new Advertisement.Builder()
            .setType(Advertisement.TYPE_VAST)
            .setRequestUrl(TEST_AD_REQUEST_URL)
            .build();
    List<Advertisement> channelAdList = new ArrayList<>();
    channelAdList.add(channelAd);

    // Add a channel programmatically
    InternalProviderData internalProviderData = new InternalProviderData();
    internalProviderData.setRepeatable(true);
    internalProviderData.setAds(channelAdList);
    Channel channelTears = new Channel.Builder()
            .setDisplayName(MPEG_DASH_CHANNEL_NAME)
            .setDisplayNumber(MPEG_DASH_CHANNEL_NUMBER)
            .setChannelLogo(MPEG_DASH_CHANNEL_LOGO)
            .setOriginalNetworkId(MPEG_DASH_ORIGINAL_NETWORK_ID)
            .setInternalProviderData(internalProviderData)
            .build();
    channelList.add(channelTears);
    return channelList;
}
 
Example #13
Source File: XmlTvParser.java    From androidtv-sample-inputs with Apache License 2.0 5 votes vote down vote up
private static Advertisement parseAd(XmlPullParser parser, String adType)
        throws IOException, XmlPullParserException, ParseException {
    Long startTimeUtcMillis = null;
    Long stopTimeUtcMillis = null;
    int type = Advertisement.TYPE_VAST;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_AD_START.equalsIgnoreCase(attr)) {
            startTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_AD_STOP.equalsIgnoreCase(attr)) {
            stopTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_AD_TYPE.equalsIgnoreCase(attr)) {
            if (VALUE_ADVERTISEMENT_TYPE_VAST.equalsIgnoreCase(attr)) {
                type = Advertisement.TYPE_VAST;
            }
        }
    }
    String requestUrl = null;
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_REQUEST_URL.equalsIgnoreCase(parser.getName())) {
                requestUrl = parser.nextText();
            }
        } else if (TAG_AD.equalsIgnoreCase(parser.getName())
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    Advertisement.Builder builder = new Advertisement.Builder();
    if (adType.equals(TAG_PROGRAM)) {
        if (startTimeUtcMillis == null || stopTimeUtcMillis == null) {
            throw new IllegalArgumentException(
                    "start, stop time of program ads cannot be null");
        }
        builder.setStartTimeUtcMillis(startTimeUtcMillis);
        builder.setStopTimeUtcMillis(stopTimeUtcMillis);
    }
    return builder.setType(type).setRequestUrl(requestUrl).build();
}
 
Example #14
Source File: CumulusXmlParser.java    From CumulusTV with MIT License 5 votes vote down vote up
private static Advertisement parseAd(XmlPullParser parser, String adType)
        throws IOException, XmlPullParserException, ParseException{
    Long startTimeUtcMillis = null;
    Long stopTimeUtcMillis = null;
    int type = Advertisement.TYPE_VAST;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_AD_START.equalsIgnoreCase(attr)) {
            startTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_AD_STOP.equalsIgnoreCase(attr)) {
            stopTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_AD_TYPE.equalsIgnoreCase(attr)) {
            if (VALUE_ADVERTISEMENT_TYPE_VAST.equalsIgnoreCase(attr)) {
                type = Advertisement.TYPE_VAST;
            }
        }
    }
    String requestUrl = null;
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_REQUEST_URL.equalsIgnoreCase(parser.getName())) {
                requestUrl = parser.nextText();
            }
        } else if (TAG_AD.equalsIgnoreCase(parser.getName())
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    Advertisement.Builder builder = new Advertisement.Builder();
    if (adType.equals(TAG_PROGRAM)) {
        if (startTimeUtcMillis == null || stopTimeUtcMillis == null) {
            throw new IllegalArgumentException(
                    "start, stop time of program ads cannot be null");
        }
        builder.setStartTimeUtcMillis(startTimeUtcMillis);
        builder.setStopTimeUtcMillis(stopTimeUtcMillis);
    }
    return builder.setType(type).setRequestUrl(requestUrl).build();
}
 
Example #15
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 5 votes vote down vote up
private void playCurrentChannel() {
    Message playAd = null;
    if (mCurrentChannel.getInternalProviderData() != null) {
        // Get the last played ad time for this channel.
        long mostRecentOnTuneAdWatchedTime =
                mContext.getSharedPreferences(
                                Constants.PREFERENCES_FILE_KEY, Context.MODE_PRIVATE)
                        .getLong(
                                Constants.SHARED_PREFERENCES_KEY_LAST_CHANNEL_AD_PLAY
                                        + mCurrentChannel.getId(),
                                0);
        List<Advertisement> ads = mCurrentChannel.getInternalProviderData().getAds();
        if (!ads.isEmpty()
                && System.currentTimeMillis() - mostRecentOnTuneAdWatchedTime
                        > mMinimumOnTuneAdInterval) {
            // There is at most one advertisement in the channel.
            playAd = mHandler.obtainMessage(MSG_PLAY_AD, ads.get(0));
        }
    }
    onPlayChannel(mCurrentChannel);

    if (playAd != null) {
        playAd.sendToTarget();
    } else {
        mNeedToCheckChannelAd = false;
        playCurrentContent();
    }
}
 
Example #16
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 5 votes vote down vote up
private boolean insertAd(Advertisement ad) {
    if (DEBUG) {
        Log.d(TAG, "Insert an ad");
    }

    // If timeshifting, do not play the ad.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        long timeShiftedDifference =
                System.currentTimeMillis() - mTimeShiftedPlaybackPosition;
        if (mTimeShiftedPlaybackPosition != TvInputManager.TIME_SHIFT_INVALID_TIME
                && timeShiftedDifference > TIME_SHIFTED_MINIMUM_DIFFERENCE_MILLIS) {
            mElapsedAdsTime += ad.getStopTimeUtcMillis() - ad.getStartTimeUtcMillis();
            mTimeShiftedPlaybackPosition =
                    mElapsedProgramTime
                            + mElapsedAdsTime
                            + mCurrentProgram.getStartTimeUtcMillis();
            scheduleNextAd();
            scheduleNextProgram();

            // If timeshifting, but skipping the ad would actually put us ahead of
            // live streaming, then readjust to the live stream position.
            if (mTimeShiftedPlaybackPosition > System.currentTimeMillis()) {
                mTimeShiftedPlaybackPosition = TvInputManager.TIME_SHIFT_INVALID_TIME;
                playCurrentContent();
            }
            return false;
        }
    }

    releaseAdController();
    mAdController = new AdController(mContext);
    mAdController.requestAds(ad.getRequestUrl(), new AdControllerCallbackImpl(ad));
    return true;
}
 
Example #17
Source File: XmlTvAdvertisementTest.java    From androidtv-sample-inputs with Apache License 2.0 5 votes vote down vote up
@Test
public void testAdvertisementParsing() throws XmlTvParser.XmlTvParseException, ParseException {
    long epochStartTime = 0;
    String requestUrl1 = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480" +
            "&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s" +
            "&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1" +
            "&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=";
    String requestUrl2 = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480" +
            "&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s" +
            "&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1" +
            "&cust_params=deployment%3Ddevsite%26sample_ct%3Dredirectlinear&correlator=";
    String testXmlFile = "xmltv.xml";
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(testXmlFile);
    XmlTvParser.TvListing listings = XmlTvParser.parse(inputStream);
    // Channel 1 should have one VAST advertisement.
    Channel adChannel = listings.getChannels().get(1);
    assertNotNull(adChannel.getInternalProviderData());
    List<Advertisement> adChannelAds = adChannel.getInternalProviderData().getAds();
    assertEquals(1, adChannelAds.size());
    assertEquals(epochStartTime, adChannelAds.get(0).getStartTimeUtcMillis());
    assertEquals(epochStartTime, adChannelAds.get(0).getStopTimeUtcMillis());
    assertEquals(Advertisement.TYPE_VAST, adChannelAds.get(0).getType());
    // Channel 0 should not have any advertisement.
    Channel noAdChannel = listings.getChannels().get(0);
    assertNotNull(noAdChannel.getInternalProviderData());
    List<Advertisement> noAdChannelAds = noAdChannel.getInternalProviderData().getAds();
    assertEquals(0, noAdChannelAds.size());
    // Program 7 should have 2 advertisements with different request tags.
    Program adProgram = listings.getAllPrograms().get(7);
    assertNotNull(adProgram.getInternalProviderData());
    InternalProviderData adProgramData = adProgram.getInternalProviderData();
    List<Advertisement> adProgramAds = adProgramData.getAds();
    assertEquals(2, adProgramAds.size());
    assertEquals(requestUrl1, adProgramAds.get(0).getRequestUrl());
    assertEquals(requestUrl2, adProgramAds.get(1).getRequestUrl());
}
 
Example #18
Source File: XmlTvParser.java    From xipl with Apache License 2.0 5 votes vote down vote up
private static Advertisement parseAd(XmlPullParser parser, String adType)
        throws IOException, XmlPullParserException, ParseException {
    Long startTimeUtcMillis = null;
    Long stopTimeUtcMillis = null;
    int type = Advertisement.TYPE_VAST;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_AD_START.equalsIgnoreCase(attr)) {
            startTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_AD_STOP.equalsIgnoreCase(attr)) {
            stopTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_AD_TYPE.equalsIgnoreCase(attr)) {
            if (VALUE_ADVERTISEMENT_TYPE_VAST.equalsIgnoreCase(attr)) {
                type = Advertisement.TYPE_VAST;
            }
        }
    }
    String requestUrl = null;
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_REQUEST_URL.equalsIgnoreCase(parser.getName())) {
                requestUrl = parser.nextText();
            }
        } else if (TAG_AD.equalsIgnoreCase(parser.getName())
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    Advertisement.Builder builder = new Advertisement.Builder();
    if (adType.equals(TAG_PROGRAM)) {
        if (startTimeUtcMillis == null || stopTimeUtcMillis == null) {
            throw new IllegalArgumentException(
                    "start, stop time of program ads cannot be null");
        }
        builder.setStartTimeUtcMillis(startTimeUtcMillis);
        builder.setStopTimeUtcMillis(stopTimeUtcMillis);
    }
    return builder.setType(type).setRequestUrl(requestUrl).build();
}
 
Example #19
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 5 votes vote down vote up
private boolean scheduleNextAd() {
    mHandler.removeMessages(MSG_PLAY_AD);
    if (mPlayingRecordedProgram) {
        return false;
    }
    long currentTimeMs = getCurrentTime();
    if (mCurrentProgram.getInternalProviderData() != null) {
        List<Advertisement> ads = mCurrentProgram.getInternalProviderData().getAds();
        Advertisement adToPlay = null;
        long timeTilAdToPlay = 0;
        for (Advertisement ad : ads) {
            if (ad.getStopTimeUtcMillis() > currentTimeMs + PAST_AD_BUFFER_MILLIS) {
                long timeTilAd = ad.getStartTimeUtcMillis() - currentTimeMs;
                if (timeTilAd < 0) {
                    // If tuning to the middle of a scheduled ad, the played portion
                    // of the ad will be skipped by the AdControllerCallback.
                    mHandler.sendMessage(mHandler.obtainMessage(MSG_PLAY_AD, ad));
                    return false;
                } else if (adToPlay == null || timeTilAd < timeTilAdToPlay) {
                    adToPlay = ad;
                    timeTilAdToPlay = timeTilAd;
                }
            }
        }

        if (adToPlay != null) {
            Message pauseContentPlayAdMsg = mHandler.obtainMessage(MSG_PLAY_AD, adToPlay);
            mHandler.sendMessageDelayed(pauseContentPlayAdMsg, timeTilAdToPlay);
        }
    } else {
        Log.w(
                TAG,
                "Failed to get program provider data for "
                        + mCurrentProgram.getTitle()
                        + ". Try to do an EPG sync.");
    }
    return true;
}
 
Example #20
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 5 votes vote down vote up
private void playCurrentChannel() {
    Message playAd = null;
    if (mCurrentChannel != null && mCurrentChannel.getInternalProviderData() != null) {
        // Get the last played ad time for this channel.
        long mostRecentOnTuneAdWatchedTime =
                mContext.getSharedPreferences(
                                Constants.PREFERENCES_FILE_KEY, Context.MODE_PRIVATE)
                        .getLong(
                                Constants.SHARED_PREFERENCES_KEY_LAST_CHANNEL_AD_PLAY
                                        + mCurrentChannel.getId(),
                                0);
        List<Advertisement> ads = mCurrentChannel.getInternalProviderData().getAds();
        if (!ads.isEmpty()
                && System.currentTimeMillis() - mostRecentOnTuneAdWatchedTime
                        > mMinimumOnTuneAdInterval) {
            // There is at most one advertisement in the channel.
            playAd = mHandler.obtainMessage(MSG_PLAY_AD, ads.get(0));
        }
    }
    onPlayChannel(mCurrentChannel);

    if (playAd != null) {
        playAd.sendToTarget();
    } else {
        mNeedToCheckChannelAd = false;
        playCurrentContent();
    }
}
 
Example #21
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 5 votes vote down vote up
private boolean insertAd(Advertisement ad) {
    if (DEBUG) {
        Log.d(TAG, "Insert an ad");
    }

    // If timeshifting, do not play the ad.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        long timeShiftedDifference =
                System.currentTimeMillis() - mTimeShiftedPlaybackPosition;
        if (mTimeShiftedPlaybackPosition != TvInputManager.TIME_SHIFT_INVALID_TIME
                && timeShiftedDifference > TIME_SHIFTED_MINIMUM_DIFFERENCE_MILLIS) {
            mElapsedAdsTime += ad.getStopTimeUtcMillis() - ad.getStartTimeUtcMillis();
            mTimeShiftedPlaybackPosition =
                    mElapsedProgramTime
                            + mElapsedAdsTime
                            + mCurrentProgram.getStartTimeUtcMillis();
            scheduleNextAd();
            scheduleNextProgram();

            // If timeshifting, but skipping the ad would actually put us ahead of
            // live streaming, then readjust to the live stream position.
            if (mTimeShiftedPlaybackPosition > System.currentTimeMillis()) {
                mTimeShiftedPlaybackPosition = TvInputManager.TIME_SHIFT_INVALID_TIME;
                playCurrentContent();
            }
            return false;
        }
    }

    releaseAdController();
    mAdController = new AdController(mContext);
    mAdController.requestAds(ad.getRequestUrl(), new AdControllerCallbackImpl(ad));
    return true;
}
 
Example #22
Source File: XmlTvAdvertisementTest.java    From xipl with Apache License 2.0 5 votes vote down vote up
@Test
public void testAdvertisementParsing() throws XmlTvParser.XmlTvParseException, ParseException {
    long epochStartTime = 0;
    String requestUrl1 = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480" +
            "&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s" +
            "&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1" +
            "&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=";
    String requestUrl2 = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480" +
            "&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s" +
            "&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1" +
            "&cust_params=deployment%3Ddevsite%26sample_ct%3Dredirectlinear&correlator=";
    String testXmlFile = "xmltv.xml";
    InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(testXmlFile);
    XmlTvParser.TvListing listings = XmlTvParser.parse(inputStream);
    // Channel 1 should have one VAST advertisement.
    Channel adChannel = listings.getChannels().get(1);
    assertNotNull(adChannel.getInternalProviderData());
    List<Advertisement> adChannelAds = adChannel.getInternalProviderData().getAds();
    assertEquals(1, adChannelAds.size());
    assertEquals(epochStartTime, adChannelAds.get(0).getStartTimeUtcMillis());
    assertEquals(epochStartTime, adChannelAds.get(0).getStopTimeUtcMillis());
    assertEquals(Advertisement.TYPE_VAST, adChannelAds.get(0).getType());
    // Channel 0 should not have any advertisement.
    Channel noAdChannel = listings.getChannels().get(0);
    assertNotNull(noAdChannel.getInternalProviderData());
    List<Advertisement> noAdChannelAds = noAdChannel.getInternalProviderData().getAds();
    assertEquals(0, noAdChannelAds.size());
    // Program 7 should have 2 advertisements with different request tags.
    Program adProgram = listings.getAllPrograms().get(7);
    assertNotNull(adProgram.getInternalProviderData());
    InternalProviderData adProgramData = adProgram.getInternalProviderData();
    List<Advertisement> adProgramAds = adProgramData.getAds();
    assertEquals(2, adProgramAds.size());
    assertEquals(requestUrl1, adProgramAds.get(0).getRequestUrl());
    assertEquals(requestUrl2, adProgramAds.get(1).getRequestUrl());
}
 
Example #23
Source File: XmlTvParser.java    From xipl with Apache License 2.0 4 votes vote down vote up
private static Channel parseChannel(XmlPullParser parser)
        throws IOException, XmlPullParserException, ParseException {
    String id = null;
    boolean repeatPrograms = false;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_ID.equalsIgnoreCase(attr)) {
            id = value;
        } else if (ATTR_REPEAT_PROGRAMS.equalsIgnoreCase(attr)) {
            repeatPrograms = "TRUE".equalsIgnoreCase(value);
        }
    }
    String displayName = null;
    String displayNumber = null;
    XmlTvIcon icon = null;
    XmlTvAppLink appLink = null;
    Advertisement advertisement = null;
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_DISPLAY_NAME.equalsIgnoreCase(parser.getName()) && displayName == null) {
                displayName = parser.nextText();
            } else if (TAG_DISPLAY_NUMBER.equalsIgnoreCase(parser.getName())
                    && displayNumber == null) {
                displayNumber = parser.nextText();
            } else if (TAG_ICON.equalsIgnoreCase(parser.getName()) && icon == null) {
                icon = parseIcon(parser);
            } else if (TAG_APP_LINK.equalsIgnoreCase(parser.getName()) && appLink == null) {
                appLink = parseAppLink(parser);
            } else if (TAG_AD.equalsIgnoreCase(parser.getName()) && advertisement == null) {
                advertisement = parseAd(parser, TAG_CHANNEL);
            }
        } else if (TAG_CHANNEL.equalsIgnoreCase(parser.getName())
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    if (TextUtils.isEmpty(id) || TextUtils.isEmpty(displayName)) {
        // In this case, the channel is simply invalid so skip it...
        return null;
    }

    // Developers should assign original network ID in the right way not using the fake ID.
    InternalProviderData internalProviderData = new InternalProviderData();
    internalProviderData.setRepeatable(repeatPrograms);
    Channel.Builder builder =
            new Channel.Builder()
                    .setDisplayName(displayName)
                    .setDisplayNumber(displayNumber)
                    .setOriginalNetworkId(id.hashCode())
                    .setInternalProviderData(internalProviderData)
                    .setTransportStreamId(0)
                    .setServiceId(0);
    if (icon != null) {
        builder.setChannelLogo(icon.src);
    }
    if (appLink != null) {
        builder.setAppLinkColor(appLink.color)
                .setAppLinkIconUri(appLink.icon.src)
                .setAppLinkIntentUri(appLink.intentUri)
                .setAppLinkPosterArtUri(appLink.posterUri)
                .setAppLinkText(appLink.text);
    }
    if (advertisement != null) {
        List<Advertisement> advertisements = new ArrayList<>(1);
        advertisements.add(advertisement);
        internalProviderData.setAds(advertisements);
        builder.setInternalProviderData(internalProviderData);
    }
    return builder.build();
}
 
Example #24
Source File: XmlTvParser.java    From xipl with Apache License 2.0 4 votes vote down vote up
private static Program parseProgram(XmlPullParser parser)
        throws IOException, XmlPullParserException, ParseException {
    String channelId = null;
    Long startTimeUtcMillis = null;
    Long endTimeUtcMillis = null;
    String videoSrc = null;
    int videoType = TvContractUtils.SOURCE_TYPE_HTTP_PROGRESSIVE;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_CHANNEL.equalsIgnoreCase(attr)) {
            channelId = value;
        } else if (ATTR_START.equalsIgnoreCase(attr)) {
            startTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_STOP.equalsIgnoreCase(attr)) {
            endTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_VIDEO_SRC.equalsIgnoreCase(attr)) {
            videoSrc = value;
        } else if (ATTR_VIDEO_TYPE.equalsIgnoreCase(attr)) {
            if (VALUE_VIDEO_TYPE_HTTP_PROGRESSIVE.equals(value)) {
                videoType = TvContractUtils.SOURCE_TYPE_HTTP_PROGRESSIVE;
            } else if (VALUE_VIDEO_TYPE_HLS.equals(value)) {
                videoType = TvContractUtils.SOURCE_TYPE_HLS;
            } else if (VALUE_VIDEO_TYPE_MPEG_DASH.equals(value)) {
                videoType = TvContractUtils.SOURCE_TYPE_MPEG_DASH;
            }
        }
    }
    String title = null;
    String description = null;
    XmlTvIcon icon = null;
    List<String> category = new ArrayList<>();
    List<TvContentRating> rating = new ArrayList<>();
    List<Advertisement> ads = new ArrayList<>();
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        String tagName = parser.getName();
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_TITLE.equalsIgnoreCase(parser.getName())) {
                title = parser.nextText();
            } else if (TAG_DESC.equalsIgnoreCase(tagName)) {
                description = parser.nextText();
            } else if (TAG_ICON.equalsIgnoreCase(tagName)) {
                icon = parseIcon(parser);
            } else if (TAG_CATEGORY.equalsIgnoreCase(tagName)) {
                category.add(parser.nextText());
            } else if (TAG_RATING.equalsIgnoreCase(tagName)) {
                TvContentRating xmlTvRating = xmlTvRatingToTvContentRating(parseRating(parser));
                if (xmlTvRating != null) {
                    rating.add(xmlTvRating);
                }
            } else if (TAG_AD.equalsIgnoreCase(tagName)) {
                ads.add(parseAd(parser, TAG_PROGRAM));
            }
        } else if (TAG_PROGRAM.equalsIgnoreCase(tagName)
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    if (TextUtils.isEmpty(channelId)
            || startTimeUtcMillis == null
            || endTimeUtcMillis == null) {
        throw new IllegalArgumentException("channel, start, and end can not be null.");
    }
    InternalProviderData internalProviderData = new InternalProviderData();
    internalProviderData.setVideoType(videoType);
    internalProviderData.setVideoUrl(videoSrc);
    internalProviderData.setAds(ads);
    try {
        return new Program.Builder()
                .setChannelId(channelId.hashCode())
                .setTitle(title)
                .setDescription(description)
                .setPosterArtUri(icon != null ? icon.src : null)
                .setCanonicalGenres(category.toArray(new String[category.size()]))
                .setStartTimeUtcMillis(startTimeUtcMillis)
                .setEndTimeUtcMillis(endTimeUtcMillis)
                .setContentRatings(rating.toArray(new TvContentRating[rating.size()]))
                // NOTE: {@code COLUMN_INTERNAL_PROVIDER_DATA} is a private field
                // where TvInputService can store anything it wants. Here, we store
                // video type and video URL so that TvInputService can play the
                // video later with this field.
                .setInternalProviderData(internalProviderData)
                .build();
    } catch (IllegalArgumentException e) {
        // The program might not have valid start/end time.
        // If that's the case, skip it...
        Log.e(TAG, "Program not valid: Channel id: " + channelId.hashCode() + ", Title: " + title
                + ", Start time: " + startTimeUtcMillis + ", End time: " + endTimeUtcMillis);
        return (null);
    }
}
 
Example #25
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 4 votes vote down vote up
public AdControllerCallbackImpl(Advertisement advertisement) {
    mAdvertisement = advertisement;
}
 
Example #26
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 4 votes vote down vote up
@Override
public void onTimeShiftResume() {
    if (DEBUG) Log.d(TAG, "Resume playback of program");
    mTimeShiftIsPaused = false;
    if (mCurrentProgram == null) {
        return;
    }

    if (!mPlayingRecordedProgram) {
        // If currently playing program content, past ad durations must be recalculated
        // based on getTvPlayer.getCurrentPosition().
        mElapsedAdsTime = 0;
        mElapsedProgramTime = getTvPlayer().getCurrentPosition();
        long elapsedProgramTimeAdjusted =
                mElapsedProgramTime + mCurrentProgram.getStartTimeUtcMillis();
        if (mCurrentProgram.getInternalProviderData() != null) {
            List<Advertisement> ads = mCurrentProgram.getInternalProviderData().getAds();
            // First, sort the ads in time order.
            TreeMap<Long, Long> scheduledAds = new TreeMap<>();
            for (Advertisement ad : ads) {
                scheduledAds.put(ad.getStartTimeUtcMillis(), ad.getStopTimeUtcMillis());
            }
            // Second, add up all ad times which should have played before the elapsed
            // program time.
            long programDurationPlayed = 0;
            long totalDurationPlayed = 0;
            for (Long adStartTime : scheduledAds.keySet()) {
                programDurationPlayed += adStartTime - totalDurationPlayed;
                if (programDurationPlayed < elapsedProgramTimeAdjusted) {
                    long adDuration = scheduledAds.get(adStartTime) - adStartTime;
                    mElapsedAdsTime += adDuration;
                    totalDurationPlayed = programDurationPlayed + adDuration;
                } else {
                    break;
                }
            }
        } else {
            Log.w(
                    TAG,
                    "Failed to get program provider data for "
                            + mCurrentProgram.getTitle()
                            + ". Try to do an EPG sync.");
        }

        mTimeShiftedPlaybackPosition = elapsedProgramTimeAdjusted + mElapsedAdsTime;

        scheduleNextAd();
        scheduleNextProgram();
    }

    if (getTvPlayer() != null) {
        getTvPlayer().play();
    }
    // Resume and make sure media is playing at regular speed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        PlaybackParams normalParams = new PlaybackParams();
        normalParams.setSpeed(1);
        onTimeShiftSetPlaybackParams(normalParams);
    }
}
 
Example #27
Source File: BaseTvInputService.java    From androidtv-sample-inputs with Apache License 2.0 4 votes vote down vote up
@Override
public void onTimeShiftResume() {
    if (DEBUG) Log.d(TAG, "Resume playback of program");
    mTimeShiftIsPaused = false;
    if (mCurrentProgram == null) {
        return;
    }

    if (!mPlayingRecordedProgram) {
        // If currently playing program content, past ad durations must be recalculated
        // based on getTvPlayer.getCurrentPosition().
        mElapsedAdsTime = 0;
        mElapsedProgramTime = getTvPlayer().getCurrentPosition();
        long elapsedProgramTimeAdjusted =
                mElapsedProgramTime + mCurrentProgram.getStartTimeUtcMillis();
        if (mCurrentProgram.getInternalProviderData() != null) {
            List<Advertisement> ads = mCurrentProgram.getInternalProviderData().getAds();
            // First, sort the ads in time order.
            TreeMap<Long, Long> scheduledAds = new TreeMap<>();
            for (Advertisement ad : ads) {
                scheduledAds.put(ad.getStartTimeUtcMillis(), ad.getStopTimeUtcMillis());
            }
            // Second, add up all ad times which should have played before the elapsed
            // program time.
            long programDurationPlayed = 0;
            long totalDurationPlayed = 0;
            for (Long adStartTime : scheduledAds.keySet()) {
                programDurationPlayed += adStartTime - totalDurationPlayed;
                if (programDurationPlayed < elapsedProgramTimeAdjusted) {
                    long adDuration = scheduledAds.get(adStartTime) - adStartTime;
                    mElapsedAdsTime += adDuration;
                    totalDurationPlayed = programDurationPlayed + adDuration;
                } else {
                    break;
                }
            }
        } else {
            Log.w(
                    TAG,
                    "Failed to get program provider data for "
                            + mCurrentProgram.getTitle()
                            + ". Try to do an EPG sync.");
        }

        mTimeShiftedPlaybackPosition = elapsedProgramTimeAdjusted + mElapsedAdsTime;

        scheduleNextAd();
        scheduleNextProgram();
    }

    if (getTvPlayer() != null) {
        getTvPlayer().play();
    }
    // Resume and make sure media is playing at regular speed.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        PlaybackParams normalParams = new PlaybackParams();
        normalParams.setSpeed(1);
        onTimeShiftSetPlaybackParams(normalParams);
    }
}
 
Example #28
Source File: BaseTvInputService.java    From xipl with Apache License 2.0 4 votes vote down vote up
public AdControllerCallbackImpl(Advertisement advertisement) {
    mAdvertisement = advertisement;
}
 
Example #29
Source File: XmlTvParser.java    From androidtv-sample-inputs with Apache License 2.0 4 votes vote down vote up
private static Program parseProgram(XmlPullParser parser)
        throws IOException, XmlPullParserException, ParseException {
    String channelId = null;
    Long startTimeUtcMillis = null;
    Long endTimeUtcMillis = null;
    String videoSrc = null;
    int videoType = TvContractUtils.SOURCE_TYPE_HTTP_PROGRESSIVE;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_CHANNEL.equalsIgnoreCase(attr)) {
            channelId = value;
        } else if (ATTR_START.equalsIgnoreCase(attr)) {
            startTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_STOP.equalsIgnoreCase(attr)) {
            endTimeUtcMillis = DATE_FORMAT.parse(value).getTime();
        } else if (ATTR_VIDEO_SRC.equalsIgnoreCase(attr)) {
            videoSrc = value;
        } else if (ATTR_VIDEO_TYPE.equalsIgnoreCase(attr)) {
            if (VALUE_VIDEO_TYPE_HTTP_PROGRESSIVE.equals(value)) {
                videoType = TvContractUtils.SOURCE_TYPE_HTTP_PROGRESSIVE;
            } else if (VALUE_VIDEO_TYPE_HLS.equals(value)) {
                videoType = TvContractUtils.SOURCE_TYPE_HLS;
            } else if (VALUE_VIDEO_TYPE_MPEG_DASH.equals(value)) {
                videoType = TvContractUtils.SOURCE_TYPE_MPEG_DASH;
            }
        }
    }
    String title = null;
    String description = null;
    XmlTvIcon icon = null;
    List<String> category = new ArrayList<>();
    List<TvContentRating> rating = new ArrayList<>();
    List<Advertisement> ads = new ArrayList<>();
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        String tagName = parser.getName();
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_TITLE.equalsIgnoreCase(parser.getName())) {
                title = parser.nextText();
            } else if (TAG_DESC.equalsIgnoreCase(tagName)) {
                description = parser.nextText();
            } else if (TAG_ICON.equalsIgnoreCase(tagName)) {
                icon = parseIcon(parser);
            } else if (TAG_CATEGORY.equalsIgnoreCase(tagName)) {
                category.add(parser.nextText());
            } else if (TAG_RATING.equalsIgnoreCase(tagName)) {
                TvContentRating xmlTvRating = xmlTvRatingToTvContentRating(parseRating(parser));
                if (xmlTvRating != null) {
                    rating.add(xmlTvRating);
                }
            } else if (TAG_AD.equalsIgnoreCase(tagName)) {
                ads.add(parseAd(parser, TAG_PROGRAM));
            }
        } else if (TAG_PROGRAM.equalsIgnoreCase(tagName)
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    if (TextUtils.isEmpty(channelId)
            || startTimeUtcMillis == null
            || endTimeUtcMillis == null) {
        throw new IllegalArgumentException("channel, start, and end can not be null.");
    }
    InternalProviderData internalProviderData = new InternalProviderData();
    internalProviderData.setVideoType(videoType);
    internalProviderData.setVideoUrl(videoSrc);
    internalProviderData.setAds(ads);
    return new Program.Builder()
            .setChannelId(channelId.hashCode())
            .setTitle(title)
            .setDescription(description)
            .setPosterArtUri(icon.src)
            .setCanonicalGenres(category.toArray(new String[category.size()]))
            .setStartTimeUtcMillis(startTimeUtcMillis)
            .setEndTimeUtcMillis(endTimeUtcMillis)
            .setContentRatings(rating.toArray(new TvContentRating[rating.size()]))
            // NOTE: {@code COLUMN_INTERNAL_PROVIDER_DATA} is a private field
            // where TvInputService can store anything it wants. Here, we store
            // video type and video URL so that TvInputService can play the
            // video later with this field.
            .setInternalProviderData(internalProviderData)
            .build();
}
 
Example #30
Source File: XmlTvParser.java    From androidtv-sample-inputs with Apache License 2.0 4 votes vote down vote up
private static Channel parseChannel(XmlPullParser parser)
        throws IOException, XmlPullParserException, ParseException {
    String id = null;
    boolean repeatPrograms = false;
    for (int i = 0; i < parser.getAttributeCount(); ++i) {
        String attr = parser.getAttributeName(i);
        String value = parser.getAttributeValue(i);
        if (ATTR_ID.equalsIgnoreCase(attr)) {
            id = value;
        } else if (ATTR_REPEAT_PROGRAMS.equalsIgnoreCase(attr)) {
            repeatPrograms = "TRUE".equalsIgnoreCase(value);
        }
    }
    String displayName = null;
    String displayNumber = null;
    XmlTvIcon icon = null;
    XmlTvAppLink appLink = null;
    Advertisement advertisement = null;
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.getEventType() == XmlPullParser.START_TAG) {
            if (TAG_DISPLAY_NAME.equalsIgnoreCase(parser.getName()) && displayName == null) {
                displayName = parser.nextText();
            } else if (TAG_DISPLAY_NUMBER.equalsIgnoreCase(parser.getName())
                    && displayNumber == null) {
                displayNumber = parser.nextText();
            } else if (TAG_ICON.equalsIgnoreCase(parser.getName()) && icon == null) {
                icon = parseIcon(parser);
            } else if (TAG_APP_LINK.equalsIgnoreCase(parser.getName()) && appLink == null) {
                appLink = parseAppLink(parser);
            } else if (TAG_AD.equalsIgnoreCase(parser.getName()) && advertisement == null) {
                advertisement = parseAd(parser, TAG_CHANNEL);
            }
        } else if (TAG_CHANNEL.equalsIgnoreCase(parser.getName())
                && parser.getEventType() == XmlPullParser.END_TAG) {
            break;
        }
    }
    if (TextUtils.isEmpty(id) || TextUtils.isEmpty(displayName)) {
        throw new IllegalArgumentException("id and display-name can not be null.");
    }

    // Developers should assign original network ID in the right way not using the fake ID.
    InternalProviderData internalProviderData = new InternalProviderData();
    internalProviderData.setRepeatable(repeatPrograms);
    Channel.Builder builder =
            new Channel.Builder()
                    .setDisplayName(displayName)
                    .setDisplayNumber(displayNumber)
                    .setOriginalNetworkId(id.hashCode())
                    .setInternalProviderData(internalProviderData)
                    .setTransportStreamId(0)
                    .setServiceId(0);
    if (icon != null) {
        builder.setChannelLogo(icon.src);
    }
    if (appLink != null) {
        builder.setAppLinkColor(appLink.color)
                .setAppLinkIconUri(appLink.icon.src)
                .setAppLinkIntentUri(appLink.intentUri)
                .setAppLinkPosterArtUri(appLink.posterUri)
                .setAppLinkText(appLink.text);
    }
    if (advertisement != null) {
        List<Advertisement> advertisements = new ArrayList<>(1);
        advertisements.add(advertisement);
        internalProviderData.setAds(advertisements);
        builder.setInternalProviderData(internalProviderData);
    }
    return builder.build();
}