| layout | page |
|---|---|
| title | Android Download-to-Go Library |
| subcat | SDK 2.0 - Android |
| weight | 500 |
Download to Go (DTG) is an Android library that facilitates the download of video assets, withan emphasis on DASH and HLS.
The library is external to the Player SDK, and is added separately by the application.
- MPEG-DASH
- Clear and Widevine
- Currently only streams generated by Kaltura MediaPrep are supported
- Track selection
- HLS
- Clear only
- No track selection
- Widevine Classic
- Must be single-bitrate for proper playback
- MP4
The simplest way to get up and running is by using JitPack's Maven repository.
- Add JitPack's repository to the top-level build.gradle:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
- Add the dependency:
dependencies {
compile 'com.kaltura:playkit-dtg-android:v2.0.0'
}
Replace v2.0.0 with the latest release.
JitPack provides more options and information.
As with any Open Source library, you can also clone the repository from GitHub and add it to your project:
- Add a reference to the project in settings.gradle:
include ':dtglib'
project(':dtglib').projectDir = file('../../playkit-dtg-android/dtglib')
- Add the local dependency in build.gradle:
dependencies {
compile project(":dtglib");
}
Now when you build your own project, DTGLib gets built as well. However, this setup should only be used when you want to contribute to DTGLib development.
The following classes/interfaces are the public API of the library:
com.kaltura.dtg.
- ContentManager
- DownloadItem
- DownloadState
- DownloadStateListener
Please see their Javadoc comments.
Following are some basic sequence diagrams.
{% plantuml %}
@startuml
participant "ContentManager class" as ContentManager
participant "app: Application" as app
participant "cm: ContentManager" as cm
app->ContentManager: getInstance(context)
ContentManager->app: cm
app->cm: addDownloadStateListener(this)
app->cm: start()
...
app->cm: stop()
@enduml
{% endplantuml %}
{% plantuml %}
@startuml
participant "app: Application" as app
participant "cm: ContentManager" as cm
participant "item: DownloadItem" as item
activate app
activate cm
note over app: User enters media info page
note over app: Check if item exists
app->cm: findItem(itemId)
cm->cm: lookup(itemId)
alt item found
cm-->app: item
else not found
cm-->app: null
app->cm: createItem(itemId, contentURL)
cm->item: new(itemId, contentURL)
activate item
cm-->app: item
app->cm: loadMetadata()
note over cm
Download and parse manifest, save in db
end note
cm-->app: onTracksAvailable
cm-->app: onDownloadMetadata
note over app: * See //track-selection// flow
end group
note over app: app is ready to start downloading
app->item: startDownload()
@enduml
{% endplantuml %}
Tracks are selected, by type, using a TrackSelector object. A TrackSelector is obtained by calling getTrackSelector() on a DownloadItem.
Given a TrackSelector, the application performs selection:
List<DownloadItem.Track> tracks = trackSelector.getAvailableTracks(AUDIO);
// Application logic for track filtering.
trackSelector.setSelectedTracks(AUDIO, filteredTracks)
// Repeat for other track types (VIDEO, TEXT)
trackSelector.apply();{% plantuml %}
@startuml
participant "app: App" as app
participant "item: DownloadItem" as item
participant "selector: TrackSelector" as selector
group for type in VIDEO, AUDIO, TEXT
app->selector: tracks = getAvailableTracks(type)
note over app: filter tracks
app->selector: setSelectedTracks(type, filteredTracks)
end group
app->selector: apply()
@enduml
{% endplantuml %}
In this scenario, the metadata for an item was downloaded, the default tracks were selected, but the download wasn't yet started. The application calls item.getTrackSelector(), makes a selection and applies it. The selected tracks are downloaded as part of the normal download.
The entire item has downloaded. The user now decides to download additional tracks - such as another audio language. The application calls item.getTrackSelector(), makes a selection and applies it. Then, item.startDownload() is called again, to start downloading the extra tracks.
The application may have a policy on track selection, for example:
- Always choose the highest quality video
- Always prefer audio in the user's UI language
The ContentManager calls the application's listener method onTracksAvailable() with an open TrackSelector. The application selects tracks to download and when onTracksAvailable() returns, the selection is applied.
If no selection was made, some defaults are applied instead. However, it's recommended that the application adopts its own defaults.
If the application can select tracks without user interaction, it is best to do so inside the onTracksAvailable() handler. It avoids writing data to the database that will be discarded immediately after.
Select the video track with the lowest bitrate:
List<DownloadItem.Track> videoTracks = trackSelector.getAvailableTracks(DownloadItem.TrackType.VIDEO);
DownloadItem.Track minVideo = Collections.min(videoTracks, DownloadItem.Track.bitrateComparator);
trackSelector.setSelectedTracks(DownloadItem.TrackType.VIDEO, Collections.singletonList(minVideo));Select all available tracks:
void selectAllAvailableTracksByType(DownloadItem.TrackSelector trackSelector, DownloadItem.TrackType trackType) {
List<DownloadItem.Track> availableTracks = trackSelector.getAvailableTracks(trackType);
trackSelector.setSelectedTracks(trackType, availableTracks);
}Then, from onAvailableTracks():
selectAllAvailableTracksByType(trackSelector, DownloadItem.TrackType.AUDIO);
selectAllAvailableTracksByType(trackSelector, DownloadItem.TrackType.TEXT);- Video: highest bitrate track
- Audio: highest bitrate version of the first language
- Text: first track.