Требования

Для работы Teleport SDK необходимо:

  1. Версия Android 5.0 и выше.
  2. Версия Android System WebView 58 и выше.

В случае, если Android System WebView не удовлетворяет требованиям, начиная с версии Android 5.0 его можно обновить из Google Play. Также TeleportSDK работает на Android TV. Подключение и использование TeleportSDK на Android TV выполняется таким же образом.

При разработке Teleport SDK используется Java 8. Для корректного подключения Teleport SDK к вашему приложению необходимо дабавить поддержку Java 8 в build.gradle.

android{
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
   }
}

Подключение

Перед использованием SDK необходимо добавить его в зависимости в gradle файле. Для этого необходимо указать Url Maven репозитория в секции "repositories" и указать зависимость в разделе "dependencies".

Пример подключения TeleportSDK:

repositories {
    //Url Maven репозитория Teleport
    maven { url 'https://sdk.teleport.media/artifactory/android/'}
    jcenter()
}

dependencies {
    //Зависимость TeleportSDK
    implementation 'media.teleport.sdk:teleport-sdk:2.4.+'
}

Также необходимо добавить в файл манифеста "AndroidManifest.xml" разрешение на использование интернета:

<uses-permission android:name="android.permission.INTERNET"/>

Использование

Перед инициализацией плеера необходимо инициализировать TeleportSDK. Инициализация происходит с помощью статического метода init. Рекомендуется инициализировать Teleport SDK в методе onCreate() расширяющего класс Application вашего приложения.

Пример инициализации TeleportSDK:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        TeleportSDK.init(getApplicationContext());
    }
}

После иницализации SDK необходимо создать экземпляр класса TeleportSDK который используется для настройки. Далее TeleportSDK запускается вызовом метода start(). При инициализации SDK возможны ошибки, в таких случаях при вызове метод start() выбросить исключение InitializationException. Далее инициализируется плеер с использованием измененной ссылки на манифест, полученной из SDK с помощью метода getChangedManifestUrl().

Пример использования с ExoPlayer:

TeleportSDK teleportSdk = new TeleportSDK(apiKey);

try{
  //Запуск работы sdk
  teleportSdk.start();
}
catch (InitializationException ex){
  Log.d("TeleportSDK",ex.getMessage().toString());
}
 //Получение измененной или исходной(в случае ошибки) ссылки на манифест
Uri manifestUriSdk = teleportSdk.getChangedManifestUrl(manifestUri);

 //Инициализация плеера
DataSource.Factory factory = new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "TeleportDemo"));
MediaSource mHlsMediaSource = new HlsMediaSource(changedUriFromSDK,factory, mainHandler, null);
simpleExoPlayerView.setPlayer(player);
player.prepare(mHlsMediaSource, false, false);

В конструктор TeleportSDK передаются следующие параметры:

  • apiKey - Api ключ. Не может быть null. Api ключ для мобильной версии TeleportSDK можно получить в личном кабинете по ссылке.

    public TeleportSDK(@NonNull String apiKey)
    

События

Для получения обратной связи в класс TeleportSDK может быть передан с помощью метода setTeleportEventsListener(TeleportEvents eventsListener) класс реализующий интерфейс TeleportEvents:

  • void onServerConnected(String peerId)

    Вызывается при иницализации Sdk и подключении к серверу Teleport.

    peerId - уникальный идентификатор пира.

  • void onSegmentLoaded(DownloadStatSegment stat)

    Вызывается при загрузке сегмента.

    DownloadStatSegment - класс содержащий информацию о загруженном сегменте.

  • void onSegmentUploaded(UploadStatSegment stat)

    Вызывается при отдаче сегмента в пиринговую сеть.

    UploadStatSegment - класс содержащий информацию об отданном сегменте.

  • void onPeerConnected(String peerId)

    Вызывается при установке соединения с новым пиром

    peerId - уникальный идентификатор подключившегося пира.

  • void onPeerDisconnected(String peerId)

    Вызывается при разрыве соединения с пиром.

    peerId - уникальный идентификатор пира.

  • void onPeeringModeChanged(PeeringMode mode)

    Вызывается при смене режима пиринга.

    PeeringMode - режим пиринга.

  • void onError(Throwable error)

    Вызывается при возниконовении ошибок при обработке запросов манифеста или сегментов.

Методы

  • public void start() throws InitializationException

    Запускает TeleportSDK. При возникновении ошибки при запуске или инициализации выбрасывает исключение.

  • public void buffering()

    Сообщает Teleport о событии буферизации плеера.

    Пример с ExoPlayer:

    //Переопределенный метод листенера ExoPlayer
    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
        if (playbackState == ExoPlayer.STATE_BUFFERING){
           teleportSdk.buffering();
        }
    }
    
  • public void dispose()

    Метод высвобождающий все ресурсы используемые Teleport SDK.

  • public void setPeeringMode(PeeringMode mode)

    Устанавливает режим пиринга с помощью перечисления PeeringMode.

    Пример:

    teleportSdk.setPeeringMode(PeeringMode.FULL);
    
  • private void getStats(StatType type, StatsCallback callback)

    Возвращает суммарную статистику по траффику у текущего сеанса работы SDK.

    • type - тип запращиваемой статистики заданный с помощью перечисления StatType.
    • callback - класс реализующий интерфейс StatsCallback.

    Пример:

    teleportSdk.getStats(StatType.FULL, new StatsCallback() {
        @Override
        public void onStatsReady(Stats stats) {
           Log.i("TeleportStats", stats.toString());
        }
    });
    
  • public Uri getChangedManifestUrl(Uri manifestUri)

    Получает изменненую ссылку на манифест после иницализации SDK.

Настройка

Для улучшения работы Teleport возможно установить перед инициализацией дополнительные параметры.

  • public void setUrlCleaner(UrlCleaner urlCleaner)

    Для корректной работы Teleport PDN из URL видео-сегмента или манифеста необходимо удалить персофицированную информацию. Данный метод задате класс реализующий интерфейс UrlCleaner, содержащий функцию cleanUrl, для унифицирования url-адресов видео-сегментов и манифеста видео потока.

    Пример:

    teleportSdk.setUrlCleaner(new UrlCleaner() {
          @Override
          public String cleanUrl(Uri url) {
              return url.getPath();
           }
    });
    
  • public void setQualityGetter(QualityGetter qualityGetter)

    Для повышения качества работы Teleport PDN, рекомендуется указать класс реализующий интерфейс QualityGetter для идентификации активного качества видео-потока.

    Пример:

    public class SimpleQualityGetter implements QualityGetter {
    
    Map<Integer, Quality> id2qualitys;
        public FirstChannelQualityGetter() {
            id2qualitys = new HashMap<>();
            id2qualitys.put(1, Quality.Q720P);
            id2qualitys.put(2, Quality.Q720PLow);
            id2qualitys.put(3, Quality.Q360PHigh);
        }
        @Override
        public Quality getQuality(Segment segment) {
            try {
                int id = Integer.parseInt(segment.getQualityId());
                Quality res = id2qualitys.get(id);
                if (res == null)
                    return Quality.Unknown;
                    return res;
            } catch (NumberFormatException ex) {
                  return Quality.Unknown;
           }
        }
    }
    
    . . .
    
    teleportSdk.setQualityGetter(new SimpleQualityGetter());
    
    
  • public void setBufferSizeGetter(BufferSizeGetter bufferSizeGetter)

    Для работы Teleport PDN, обязательно необходимо указать класс реализующий интерфейс BufferSizeGetter, для идентификации размера буфера плеера, иначе не будет загрузки сегментов из пиринга. Пример использования с ExoPlayer:

    teleportSdk.setBufferSizeGetter(new BufferSizeGetter() {
            @Override
            public float getBufferSize() {
                if (player != null)
                    return (player.getBufferedPosition() - player.getCurrentPosition()) / 1000f;
                else return 0;
            }
        });
    
  • public void setManifestAcceptor(ManifestAcceptor accepter)

    Для поиска необходимых соединения Teleport использует URL видео-потока. По умолчанию Teleport определяет манифест по расширению .m3u8 или .mpd Если ваш медиасервер выдает специфичные url для манифеста, то необходимо определить класс реализующий интерфейс ManifestAcceptor для определения http-запроса с манифестом видео-потока.

    Пример:

    teleportSdk.setManifestAcceptor(new ManifestAcceptor() {
             @Override
             public boolean acceptManifest(Uri manifestUrl) {
                 return manifestUrl.getPath().contains("m3u8");
             }
         });
    
  • public void setSegmentAcceptor(SegmentAcceptor accepter)

    Для того, чтобы передача данных началась в Teleport PDN, необходимо определить, что данный запрос скачивает видео-сегмент. По умолчанию Teleport определяет видео-сегменты по следующим расширениям: .ts,.mp4,.m4s. Если ваш медиасервер выдает специфичные url для видео-сегментов, то необходимо определить класс реализующий интерфейс SegmentAcceptor для определения http-запросов с видео-сегментом.

    Пример:

    teleportSdk.setSegmentAcceptor(new SegmentAcceptor() {
             @Override
             public boolean acceptSegment(Segment segment) {
                 return segment.getSegmentURL().contains(".ts");
             }
         });
    

Конфигурация сетевой безопасности

Teleport SDK обрабатывает запросы от плеера отправленные на localhost. Начиная с Android 9 (API 28) запрещена передача данных открытым текстом. Для работы SDK необходимо разрещить отправку данных открытым текстом на localhost. Для этого надо задать конфигурацию сетевой безопасности. Более подробно об этом "Конфигурация сетевой безопасности". Teleport SDK уже содержит необходимые настройки сетевой безопасности, но если вы используете свои настройки то вам необходимо добавить разрешение передачи данных открытым текстом для localhost.

res/xml/network_security_config.xml:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config xmlns:android="http://schemas.android.com/apk/res/android">
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">localhost</domain>
    </domain-config>
</network-security-config>

Настройка плееров

ExoPlayer

Настройка времени чтения

Для лучшей работы ExoPlayer c Teleport SDK мы рекомендуем установить время чтения в 2 раза больше установленного по умолчанию.

DefaultHttpDataSourceFactory defaultHttpDataSourceFactory =  new DefaultHttpDataSourceFactory(
        Util.getUserAgent(this, "ApplicationName"),
        null,
        DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
        DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS * 2,
        false
    );
        

Настройка получения размера буфера

Начиная с версии ExoPlayer 2.9.0 требует получение доступа к плееру только из главного потока. Для решения этой проблемы в абстрактном классе BufferSizeGetter необходимо переопределить метод looper() который возвращает Looper связанный с главным потоком. Более подробно об этом "What do “Player is accessed on the wrong thread” warnings mean?"

Пример реализации BufferSizeGetter для ExoPlayer 2.9.0 и выше

class ExoPlayerCustomBufferSizeGetter extends BufferSizeGetter {

    private ExoPlayer player;

    public ExoPlayerCustomBufferSizeGetter(ExoPlayer player) {
        this.player = player;
    }

    @Override
    public Looper looper() {
        return player.getApplicationLooper();
    }

    @Override
    public float getBufferSize() {
        if (player != null)
            return (player.getBufferedPosition() - player.getCurrentPosition()) / 1000f;
        else return 0;
    }
}

Перечисления

  • Quality

    Перечисление качеств видео-потока
    
    public enum Quality {
          Unknown,
          Q144P,
          Q240P,
          Q360P,
          Q480P,
          Q720P,
          Q1080P,
          Q4K
     }
    
  • StatType

    Определяет тип запращиваемой статистики в методе getStats.

    public enum StatType {
        FULL,
        FROM_LAST_CHECKPOINT
    }
    
    Доступные значения:  
    
    • FULL - запращивает полную статистику с момента начала работы Teleport SDK.
    • FROM_LAST_CHECKPOINT - запрашивает статистику собранную с момента последнего запроса.
  • PeeringMode

    Перечисление режимов пиринга для работы Teleport

    public enum PeeringMode {
          OFF,
          DOWNLOAD,
          UPLOAD,
          FULL
     }
    

    Доступные значения:

    • OFF - пиринг выключен
    • DOWNLOAD - пир может только скачивать из Teleport PDN
    • UPLOAD - пир может только раздавать в Teleport PDN
    • FULL - пир работает в полном режиме
  • SegmentType

    Перечисление типов сегментов

    public enum SegmentType {
          UNKNOWN,
          VIDEO,
          AUDIO,
          CAPTION,
          OTHER
     }
    
  • Source

    Перечисление источников загрузки сегмента

    public enum Source {
        PDN,
        CDN
    }
    

Классы

  • class Segment

    Предоставляет информацию о сегменте.

    public class Segment {
        SegmentType type;   // тип сегмента
        String segmentURL;  // url сегметна
        String qualityId;   // идентификатов качества сегмента
        double duration;    // длительность сегмента
        int bandwidth;      // битрэйт сегмента
    }
    
  • class DownloadStatSegment

    Предоставляет статистику о скачанном сегменте

    public class DownloadStatSegment {
        long timestamp;     // Время загрузки сегмента
        Result result;      // Обьект с данными загрузки сигмента
        Timings timings;    // Обьект с данными замеряемых таймингов
        Request request;    // Обьект с данными запрашиваемого сегмента
    }
    
  • class UploadStatSegment

    Предоставляет статистику о скачанном сегменте

    public class UploadStatSegment {
        long timestamp;           // Время закгрузки сегмента
        Result result;            // Обьект с данными загрузки сигмента
        Timings timings;          // Обьект с данными замеряемых таймингов
        UploadRequest request;    // Обьект с данными запрашиваемого сегмента
    }
    
  • class Result

    Класс с данными загрузки сигмента

    public class Result {
          String segmentId;       //Идентификатор сегмента
          Source sourceId;        // CDN или PDN
          int waitTimeout;        //Таймаут ожидания из Teleport PDN
          int flags;              //Флаги загрузки
          int downloadTimeout;    //Таймаут загрузки из Teleport PDN
          long size;              //Размер сегмента в байтах
          int haves;              //Количество пиров с указанным сегментов в рое
          boolean connected;      //Флаг активности соединения с серверами Teleport
          boolean active;         //Флаг активности Teleport PDN
          int swarmSize;          //Размер роя
          PeeringMode mode;       //Режим пиринга
    }
    
  • class Request

    Класс с данными запроса сегмента

    public class Request {
        String uri;          //Унифицированный URI сегмента, после обработки urlCleaner'ом
        String url;          //Исходный url сегмента
        float bufferSize;    //Размер буфера в плеере, секунд
        float duration;      //Длительность сегмента, секунд
        int quality;         //Tекущее качество видео-потока
        SegmentType type;    //Тип сегмента
    }
    
  • class Timings

    Класс с данными замеряемых таймингов

    public class Timings {
        long reqStart;      //Timestamp времени запроса сегмента плеером
        long ttFinish;      //Дельта окончания обработки сегмента и передача данных в плеер
        int ttHave;         //Дельта ожидания сегмента в Teleport PDN
        int ttlb;           //Дельта окончания загрузки сегмента
        int ttSent;         //Дельта времени инициализации загрузки
        int ttFb;           //Дельта ожидания первого чанка
    
    }
    
  • class UploadRequest

    Класс с данными о запросе на отдачу сегмента

    public class UploadRequest {
          String connectionId;   //Идентификатор пира
          String segmentId;      //Идентификатор сегмента
    }
    
  • class StatsTotals

    Класс с даннымы статистики по загрузке и отдаче

    public class Stats {
        long duration;    // Длительность сбора статистики
        Traffic cdn;      // Статистика загрузки из CDN
        Traffic pdn;      // Статистика загрузки из PDN
        Traffic upload;   // Статистика отдачи в PDN
    }
    
  • class Traffic

    Класс с даными статистики

    public class Traffic {
        int size;      //Размер в байтах
        int count;     //Количество скаченных или отданных сегментов
        long time;     //Общее время загрузки или отдачи сегментов в миллисекундах
        double speed;  //Средняя скорость загрузки или отдачи сегментов в Мегабитах в секунду
    }
    

Интерфейсы

  • TeleportEvents

    События уведомляющие о работе TeleportSDK.

    public interface TeleportEvents {
        void onServerConnected(String peerId);
        void onSegmentLoaded(DownloadStatSegment stat);
        void onSegmentUploaded(UploadStatSegment stat);
        void onPeerConnected(String userId);
        void onPeerDisconnected(String userId);
        void onPeeringModeChanged(PeeringMode mode);
    
    }
    
  • StatsCallback

    Интерфейс содержащий метод обратного вызова onStatsReady сигнализирующий о готовности статистики.

        public interface StatsCallback {
            void onStatsReady(Stats stats);
        }