company_banner

Стриминг видео с помощью Azure и .NET

    В рамках проекта Jisp, разработкой которого занимается компания WaveAccess, возникла задача по загрузке и проигрыванию видео. В целом, ничего необычного, но с ней связаны известные проблемы, такие как необходимость препроцессинга, а также необходимость поддержать возможность стриминга в требуемом качестве и формате. Видео должно успешно проигрываться на основных платформах, а именно Android, iOS и desktop (web). Подробнее о решении проблем читайте под катом!



    Jisp
    Jisp — приложение для покупателей и владельцев онлайн и оффлайн магазинов. Устанавливается на мобильное устройство пользователя. Делится скидками и спецпредложениями, собирает историю просмотров, составляет для ритейлеров портрет пользователя.

    Интегрирован с iBeacons. Они в оффлайновом магазине устанавливаются на товар (одежду, технику), и при просмотре этого товара (прикосновении к тегу) посетителем, на мобильном устройстве появляется спецпредложение и подробные данные о товаре. В приложении реализован аналог соцсети для любителей шопинга: можно делиться видеозаписями, интересными товарами, отзывами о них.

    В 2017 году приложение получило Microsoft Partners Award в номинации Business за модуль машинного обучения, позволяющий составлять точный портрет пользователя на основе его выбора онлайн и оффлайн и рассылать персональные предложения.

    Для решения данной задачи мы использовали технологию Azure Media Services. На серверной части используется платформа .Net. Помимо стандартных требований, связанных со стримингом видео, были также свои требования, предъявляемые бизнес-логикой приложения. Пользователи могут загружать видео и прикреплять их к определённой геолокации. Полное видео должно быть доступно только в заданной области. В остальных же случаях другие пользователи могут проиграть лишь короткий фрагмент, заданный автором видео. Кроме того, необходимо обрезать видео до квадратных пропорций.

    Настройка доступа


    Прежде чем перейти к загрузке видео, необходимо настроить хранилище и доступ к нему. Для этого надо подготовить 2 аккаунта: Media service account и Azure storage Account.

    Media service account


    Он отвечает за хранение метаданных видео. При создании этого типа аккаунта нужно задать следующий набор параметров:

    • Resource group — используется для группировки ресурсов в Azure в возможностью настроить доступ на группу целиком
    • Location — территориальное расположение data-центра, в котором будет создан ресурс
    • Storage account — используется для сохранения assets-файлов

    Storage account


    Данный тип аккаунтов предназначен для хранения файлов, в данном случае он отвечает непосредственно за хранение видео.

    Авторизация


    После того, как созданы аккаунты, необходимо настроить авторизацию. В Azure media services используется авторизация через Azure Active Directory. Есть 2 варианта авторизации:

    • Пользователь
    • Service principal

    Первый подход имеет смысл, если у нас нет промежуточного сервиса, который брал бы авторизацию на себя. Например, если мы имеем дело с desktop-приложением, которое напрямую взаимодействует с Azure Media Services. В этом случае мы будем запрашивать у пользователя логин и пароль для Azure Active Directory.

    Авторизация аккаунтов пользователей


    Второй вариант удобнее, если у нас есть свой сервис, отвечающий за авторизацию пользователей в приложении. Например, если у нас есть мобильное или веб-приложение со своим back-end сервисом. В этом случае на сервере хранятся ключи доступа к AMS, а авторизация пользователей лежит на бизнес-логике приложения.

    Авторизация с использованием Service Principal


    В случае с Jisp выбран второй вариант.

    Подготовив аккаунты и авторизацию, можем начать интеграцию с .Net SDK для AMS. Основной объект, отвечающий за работу с AMS сущностями, — CloudMediaContext. Ниже приведён код, который отвечает за его инициализацию:

    var azureKey = new AzureAdClientSymmetricKey(clientId, clientKey);
    var credentials = new AzureAdTokenCredentials(tenant, azureKey, AzureEnvironments.AzureCloudEnvironment);
    var tokenProvider = new AzureAdTokenProvider(credentials);
    var context = new CloudMediaContext(new Uri(url), tokenProvider);

    Assets


    После того, как мы инициализировали CloudMediaContext, можно переходить к загрузке видео. Для этого в AMS используются asset-сущности. Это ресурс, который содержит непосредственно видеопоток, аудио, thumbnail-изображения и прочие файлы, связанные с видео. Для начала, нужно создать сам asset-ресурс.

    var inputAsset = context.Assets.Create(assetName, storageName, AssetCreationOptions.None);

    После этого надо добавить в asset исходный видеофайл:

    var assetFile = inputAsset.AssetFiles.Create(fileName);

    Далее нужно преобразовать его для адаптивного стриминга:

    var job = context.Jobs.CreateWithSingleTask("Media Encoder Standard", "Adaptive Streaming", inputAsset, "Adaptive Bitrate MP4", AssetCreationOptions.None);
    job.Submit();
    job = job.StartExecutionProgressTask(
        j =>
        {
            Console.WriteLine("Job state: {0}", j.State);
            Console.WriteLine("Job progress: {0:0.##}%", j.GetOverallProgress());
        }, CancellationToken.None).Result;
    Console.WriteLine("Transcoding job finished.");
     
    var outputAsset = job.OutputMediaAssets[0];

    После того, как видео готово, публикуем его с помощью Locator’а:

    context.Locators.Create(LocatorType.OnDemandOrigin, outputAsset, AccessPermissions.Read, TimeSpan.FromDays(365));

    Теперь мы можем проигрывать наше видео.

    var videoUri = outputAsset.GetMpegDashUri();

    Фильтры


    Для модификации видео Azure Media Services предлагает механизм фильтров. Есть возможность указать качество аудио или видео, разрешение, используемый кодек, выбрать определённый интервал.

    Есть 2 типа фильтров:

    • Локальные. Такие фильтры могут быть применены только к тому видео, для которого они были созданы. Соответственно, на каждое видео нужно создавать отдельный фильтр.
    • Глобальные. Такие фильтры могут быть применены к любым видео данного аккаунта. Они особенно актуальны, когда требуется поддержать стриминг видео в различных форматах для различных устройств.

    Далее приведён пример создания фильтра, который ограничивает проигрывание видео заданным интервалом:

    var filterName = $"{length}seconds";
    outputAsset.AssetFilters.Create(filterName,
    	new PresentationTimeRange(start: 0, end: Convert.ToUInt64(10000000 * length)),
    	new List<FilterTrackSelectStatement>());

    Для применения созданных фильтров нужно модифицировать url для стриминга следующим образом.

    Исходный url:
    testendpoint-testaccount.streaming.mediaservices.windows.net/fecebb23-46f6-490d-8b70-203e86b0df58/BigBuckBunny.ism/Manifest(format=mpd-time-csf)

    url после добавления фильтра 10seconds:
    testendpoint-testaccount.streaming.mediaservices.windows.net/fecebb23-46f6-490d-8b70-203e86b0df58/BigBuckBunny.ism/Manifest(format=mpd-time-csf,filter=10seconds)

    Если нам нужно применить несколько фильтров, url будет следующим:
    testendpoint-testaccount.streaming.mediaservices.windows.net/fecebb23-46f6-490d-8b70-203e86b0df58/BigBuckBunny.ism/Manifest(format=mpd-time-csf,filter=10seconds;square)

    Масштабирование


    Как и любой облачный сервис, AMS значительно упрощает процесс масштабирования.
    Если говорить о препроцессинге видео, AMS предоставляет следующие варианты:

    1. Вертикальное масштабирование, в данном случае увеличение скорости обработки видео. Есть 3 тарифа с производительностью x1, x2 и x4 соответственно. Поэтому, если время подготовки видео не является критичным, можно выбрать минимальный тариф. Если необходимо свести время процессинга к минимуму, есть смысл использовать х4.
    2. Горизонтальное масштабирование, т.е. возможность одновременной обработки нескольких видео. Это легко достигается заданием требуемого количества Media processing units.

    Если говорить о стриминге видео, AMS поддерживает автоматические изменение пропускной способности по мере необходимости. Также есть разделение на standard и premium тарифы. Первый рассчитан на пропускную способность до 600Mbps. Второй — 200 Mbps на каждый streaming unit.

    Скорость


    Для примера возьмём видео качества 720p, длиной 30 секунд, 1 минуту и 5 минут, и сравним время предобработки. Результаты получились следующими:

    Тариф 30 сек (4,4 Мб) 1 минута (8,1 Мб) 5 минут (44,9 Мб)
    x1 1:32 (49 Кб/с) 2:14 (62 Кб/с) 8:38 (89 Кб/с)
    x2 1:07 (68 Кб/с) 1:31 (91 Кб/с) 5:07 (150 Кб/с)
    x4 0:33 (137 Кб/с) 0:45 (185 Кб/с) 1:49 (422 Кб/с)
    Для небольших видео прирост в производительности предобработки получается не таким существенным, особенно, для тарифа х2. Но по мере увеличения ситуация меняется в лучшую сторону, и тарифы х2 и х4 дают соответствующий прирост в скорости обработки.

    Подводные камни


    Azure Media Services, как и любая технология, накладывает свои ограничения.

    Первая сложность, с которой мы столкнулись, эта задержка между моментом загрузки видео и моментом, когда оно будет готово для стриминга. Идеальный вариант — иметь возможность стриминга сразу после загрузки. В принципе, AMS даёт возможность получить ссылку на необработанное видео. Но подготовка asset-файлов всё равно оказывалось дольше, чем простая загрузка видео в Azure Storage в обход AMS. В связи с этим мы решили сначала загружать исходное видео в Azure Storage в обход AMS и на период предобработки отдавать его напрямую.

    Следующая сложность была связана с изменением пропорции видео. В нашем случае AMS некорректно обрабатывал нестандартные пропорции (1:1). Несмотря на то, что само видео становилось квадратным, метаданные показывали другое соотношение, а thumbnail-изображение искажалось. В связи с этим данную задачу пришлось реализовать средствами ffmpeg.

    Также была определённая сложность с указанием проигрываемого фрагмента. По умолчанию длительность была кратной 6 секундам. С использованием расширенной конфигурации удалось снизить шаг до двух секунд, что являлось приемлемым.

    В остальном же Azure Media Services отлично справляется со своей задачей, предоставляя готовое решение для стриминга видео множеству клиентов.

    Об авторе


    Команда WaveAccess создаёт технически сложное высоконагруженное отказоустойчивое ПО для компаний всего мира. Александр Азаров, старший вице-президент по разработке ПО в WaveAccess, комментирует:
    Сложные на первый взгляд задачи можно решить сравнительно простыми методами. Важно не только изучать новые инструменты, но и доводить до совершенства знание привычных технологий.
    Блог компании
    • +16
    • 2,9k
    • 2

    Microsoft

    284,42

    Microsoft — мировой лидер в области ПО и ИТ-услуг

    Поделиться публикацией
    Комментарии 2
      +1
      задержка между моментом загрузки видео и моментом, когда оно будет готово для стриминга. Идеальный вариант — иметь возможность стриминга сразу после загрузки.
      Хочу уточнить терминологию. Судя по тексту, Вы под «стримингом» подразумеваете оффлайн передачу видео, но вроде бы "стриминг" означает онлайн трансляцию, нет?
        –1
        Речь именно о просмотре заранее загруженного видео, не о прямой трансляции

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое