Может показаться, что разработка проекта для видеостриминга — это просто: слепи плеер, возьми контент с сервера — и готово. Но только после того, как мы сами начали делать такой проект, мы поняли, что это — весьма нетривиальная задача для разработки и тестирования.
Меня зовут Влад Попов, я — QA в Surf. В статье расскажу, на что нужно обращать внимание при тестировании мобильных приложений для аудио- и видео стриминга.
Материал — не о технической реализации видеостриминга, а о продуктовых нюансах. Полтора года назад проект стал для нас вызовом: до этого никто не сталкивался с разработкой и тестированием видеостримингов. Всё, о чем я пишу, — личный опыт, которым хочется поделиться с сообществом.
По какому принципу работают видеостриминги
Чтобы тестировать видеостриминги, следует разобраться, что это такое и как они работают.
Видеостриминг — это потоковая передача видео в режиме реального времени на устройство пользователя через интернет. Современные видеостриминговые сервисы работают так:
Большой кусок разбивается на мелкие — «чанки».
Чанки последовательно передаются пользователю: посмотрел кусочек — дали другие.
Способы получения видео
Широко используется протокол получения видео HLS. Технологию сделали ребята из Apple: это стандарт для их техники.
В мастер-плейлист с сервера приходят медиафайлы доступного качества в формате m3u8. Устройство само выбирает нужное качество из списка, и мы получаем файлы-фрагменты, в которых содержатся видео.
Внутри мастер-плейлистов лежат чанки: они скачиваются по HTTP и по ним передаётся видеоконтент. Аудиодорожка может быть отдельным артефактом в мастер-плейлисте или вшита в фрагменты.
Content Delivery Network (CDN) — способ получать видео по прямой ссылке на сервере-хранилище.
Сеть доставки содержимого — географически распределённая сетевая инфраструктура. Позволяет оптимизировать доставку и дистрибуцию содержимого конечным пользователям в интернете.
Это удобный вариант для коротких видео: например, рекламных. Минус только в том, что надо ждать, пока видео полностью загрузится до конца. Но разница несущественная: фрагменты в HLS имеют длительность 10 секунд, реклама — 15. Зато посреди просмотра не будет ошибки.
Из каких элементов состоит видеостриминговое приложение
Представим приложение как слоеный пирог, который содержит следующие части:
Работа с сетью. Основание пирога: всё строится на взаимодействии клиента и сервера. Не уделим внимание основанию — приложение будет «невкусным».
Логика плеера. Не менее важная часть пирога: видна пользователю, он взаимодействует с ней напрямую.
Картинка в картинке и воспроизведение в фоне. Можно сравнить с декоративными украшениями пирога: пользователю «вкусно» и удобно.
Удобство пользования плеером. Вишенка на торте. Хорошо, когда плеером пользоваться удобно и ничего не отвлекает от контента. Например, когда не нужно лишний раз тапать на плеер для перемотки, чтобы вызвать контролы.
Рассмотрим каждую составляющую подробнее.
Работа с сетью
Начнем с инициализации: нужно понять, откуда приложение получает видеофайлы. Есть два варианта:
Прямая ссылка на hls/mp4. Она может приходить в API в качестве одного из полей. Приложение само уходит по ней и запрашивает мастер-плейлист.
Отдельный запрос, в котором получаем мастер-плейлист: бэк оборачивает запрос на мастер-плейлист в свое API (например, получение плейлиста по id серии id/playlist). В качестве ответа приходят плейлисты определенного качества.
Возможна ситуация, когда аудио- и видеодорожки приходят в разных полях: тогда приложение склеивает их «на лету». Отсюда возникает вопрос с обработкой ошибок при старте воспроизведения видео.
Обработка ошибок при старте
Это важный пункт: в этот момент происходит первое соприкосновение пользователя с приложением. Стоит обратить внимание:
Как показывается ошибка.
Запрос на повтор отправляется фоном или пользователь должен самостоятельно нажать на повтор.
Какова периодичность повтора запросов, если они идут фоном.
Что будет, если упал видеоконтент, но аудиодорожка при этом есть.
Что будет, если упало аудио, но видеодорожка при этом есть.
Обработка ошибок при воспроизведении
Каков размер буфера для воспроизведения.
Как обрабатывается ошибка на фрагмент.
Как восстанавливается воспроизведение после ошибки.
Как ведёт себя аудио при падении видео — и наоборот.
Как они восстанавливают коннект.
Автоматическое переключение качества при ухудшении сети или при старте с плохой сетью
Подгружает ли приложение видео сразу в самом высоком качестве.
Или берёт первый доступный плейлист.
Или «умно» проверяет скорость интернета и подстраивается под нужное качество.
Лучший вариант — загрузить сначала видео в плохом качестве и «на лету» поменять на подходящее. Долго заставлять пользователя ждать контент не стоит.
Ручная смена качества
Воспроизведение стартует в новом качестве или сначала доигрывает буфер, а потом уже подкачивается новое.
Если переключение качества не удалось, показываем ошибку или оставляем пользователя на том качестве на котором он был.
Субтитры
Фича хоть и мелкая, но важная. Нужно определиться:
Как получаем субтитры.
Как они себя ведут при ошибках воспроизведения.
Как ведёт себя плеер при ошибке на загрузку субтитров.
Логика плеера
С логикой плеера пользователь взаимодействует чаще всего. Этот раздел — больше продуктовый, чем технический. Мы убеждены, что QA обеспечивают качество продукта во всех смыслах. Поэтому важно убедиться не только в том, что фичи сделаны по ТЗ, но и в том, что они удобны для пользователей. Например, кнопка может работать технически правильно, но чтобы её нажать, потребуется выполнить лишние действия. На всё это как раз и стоит обратить внимание именно QA: он имеет доступ к проекту в той стадии, где всё это можно быстро отловить и изменить.
Прерывания
У мобильных приложений есть прерывания: например, звонок, пуши, показ шторок, переходы в другие приложения с воспроизведением видео или аудио в фоне. Понятно, что пользователю не хочется, чтобы звонящий услышал посторонние звуки и узнал, какие шоу он смотрит :)
Логично, что видео в таком случае должно запаузиться. Кроме этого, важно обратить внимание на продолжение воспроизведения после прерывания: контрол плеера может явно стоять на паузе либо видео воспроизведётся дальше само.
Рубрика «Интересные баги на iOS»
Столкнулся с багом как пользователь стримингов.
Срабатывал режим экранного времени, приложение завершало работу. После нажатия на кнопку «Позже» и временного отключения ограничения, видео или аудио «замораживалось». При этом кнопка на самом плеере была в положении «поставить паузу». Чтобы начать воспроизведение дальше, надо было тапнуть либо два раза (поставить паузу -> снять с паузы), либо четыре раза по кнопке, что весьма бесит.
Не буду упоминать про отставание картинки от звука после срабатывания прерывания :) Также отставать может картинка от звука при ускорении видео, но это уже другая история. Набравшись опыта с шарингом видео на ТВ могу сказать, что иногда он вылетает и это жутко бесит, но подобная ситуация чаще появлялась в браузерах, чем в приложениях.
Ориентация экрана
Ориентация север, я хочу, чтобы ты верил, я хочу, чтобы ты перевернул мне картинку, так как я положил телефон.
Интерактив! Представьте: вы открываете приложение с игрой, которая разворачивается в альбом, или нажимаете в видеоплеере на кнопку разворота видео. Автоповорот при этом запрещён. Представили? А теперь ответьте на вопрос «С какой стороны у вас находится кнопка „Домой“ на телефоне?»
Для меня и большинства моих коллег ответ был «справа». То есть после открытия игры или нажатия на разворот в полноэкранный режим, вы на автомате повернёте устройство влево.
Мы не описали явно этот момент в ТЗ и сделали наоборот: кнопка «Домой» оказывалась слева. Пришлось потом доказывать команде, что это не моя хотелка, как вредного QA, а такое поведение ожидает пользователь.
Отдельно стоит уточнить момент про автоповорот плеера, когда стоит блокировка автоповорота. На некоторых андроид-устройствах встречал, что плееры это игнорируют: они поворачиваются в ту сторону, в которую пользователь завалил телефон, и игнорируют блокировку автоповорота. Поэтому пропишите в ТЗ явно, что делать в таком случае. Это поможет не схлопотать лишних багов, которые одна сторона считает заведенными верно, а другая, опираясь на опыт другого приложения, — нет.
Контролы плеера
Хорош тот плеер, которым удобно пользоваться.
Появление и скрытие контролов. Стоит обращать внимание:
Когда контролы пропадают автоматически — например, начинается воспроизведение, и через две секунды они исчезают.
Когда они автоматически не исчезают.
Мы не обдумали этот момент, и контролы всегда пропадали через две секунды — даже когда видео на паузе. Но ведь если пользователь поставил на паузу, он захочет снять с неё. Придётся лишний раз тапать на экран, чтобы они снова появились. Это лишний шаг.
Перемотка. Похожая ситуация с перемоткой дабл-тапами и кнопками на плеере. Заметили, что у популярных приложений перемотка дабл-тапом работает так: если пользователь только что перемотал фрагмент, и на экране ещё есть контрол перемотки, последующая перемотка срабатывает на каждый тап.
Пример
Чтобы перемотать на 30 секунд вперед с шагом перемотки 10 сек, нужно тапнуть 4 раза, а не 6. Два раза, чтобы активировать перемотку и прыгнуть на 10 секунд вперед, и каждый следующий тап даёт +10 секунд вперед. Это удобно и не создаёт ощущение лагов при перемотке.
Контролы при открытых шторках:
Работают ли контролы, когда на плеере открыта какая-нибудь шторка.
Как эта шторка закрывается: тапом вне шторки или явно должен быть крестик.
Жесты плеера
Не забываем, конечно же, про жесты плеера: область применения и удобство расположения. Это могут быть жесты выключения рамок, жест прибавления яркости или громкости, особые жесты для вызова фич плеера. Главное — чтобы они не конфликтовали друг с другом и корректно перестраивали свою область применения на экранах с разными размерами (привет, iPhone SE).
Состояние настроек для следующего видео
Сохраняется ли состояние настроек плеера для следующего видео. Под состоянием я имею в виду:
скорость видео,
качество,
состояние рамок,
яркость (если она меняется в плеере),
включённость субтитров.
Если настройки выставлены явно — в настройках приложения — они должны сохраняться везде.
Если они выставлены один раз на плеере, то в рамках одной сессии работы с приложением должны сохраняться при переходе на другое видео.
Кнопки на плеере
Логика. Лишних прерываний видео быть не должно: лучше всё сделать бесшовно.
Область тапов. Области тапов не должны быть слишком мелкими или наезжать друг на друга. Особенно это важно для кнопок, которые находятся рядом с таймлайном плеера: чтобы случайно не перемотать в конец или в начало.
Субтитры
Важно, чтобы субтитры:
не мешали просмотру,
хорошо читались,
не блочили видео, если не могут отображаться,
удобно выключались, но это уже опционально — важно не захламлять экран плеера контролами.
Картинка в картинке и воспроизведение в фоне (пипафон)
Переходим к авторской и самой больной рубрике: картинка в картинке и воспроизведение в фоне. Больная она потому, что стриминговое приложение мы делали на Flutter: плагины нативные, логику дописывали на нативе, где-то получалось криво. Плюс тестить это довольно сложно: живых примеров всего несколько.
Почему «пипафон»: лирическое отступление
Мы в команде назвали фичу картинки в картинке и воспроизведения в фоне «пипафон». Pip — «картинка в картинке», потом добавили в приложение воспроизведение в фоне, а потом сделали, чтобы пип и фон были доступны одновременно.
Требований к картинке в картинке и фону немного: кастомизация практически отсутствует. Расскажу, на что важно смотреть при тестировании фичи.
Логика контролов в этих режимах: какими они могут быть. И на то когда контролы недоступны совсем.
Очередь воспроизведения: должен быть плавный и бесшовный переход от одного контента к другому без длинных пауз и задержек.
Если вы решили внедрить в видео рекламу, которую нельзя пропускать и она доступна в режиме пипафон, позаботьтесь о том, чтобы:
Контролы плеера в этом режиме были недоступны для перемотки и пропуска.
После окончания рекламы они обязательно вернулись в исходное состояние.
Если реклама в середине видео, контролы на ней тоже должны быть заблочены для перемотки.
Сюда же отнесу окончание воспроизведения контента. Важно, чтобы пользователь понимал, что происходит у него на экране, и не был шокирован изменениями.
Скорость видео, качество и субтитры должны вести себя, как и у «большого» плеера.
Совет от автора
Если у вас доступен режим пипафон, проверьте его на всех доступных ОС и оболочках. Очень много подводных камней и специфичных багов зависят как раз от оболочки.
Ну взаимодействия картинки в картинке и фона — отдельное искусство. Бывает, после активации одного второй перестает работать и чинится только перезапуском приложения.
Удобство пользования плеером
Мелочи, которые позволяют пользователю не думать о том, что между ним и контентом ещё есть прослойка в виде приложения.
Работа с наушниками. Наушники умеют во всякие сенсоры, жесты, голосовое управление, могут останавливать контент, когда из уха вытаскивается один из них. Они даже могут произносить сообщения в момент прослушивания.
Представьте ситуацию: человек едет в автобусе и слушает подкаст. Вытащил наушник из уха, чтобы уточнить, какая остановка следующая, а контент начинает орать на весь автобус. Будет очень неловко. Наверно, многие (и я в том числе) опасаются такой ситуации.
Аналогично при подключении наушников: что происходит с контентом, паузится ли или продолжает воспроизведение. Ну и всем известные жесты и кнопки на наушниках должны корректно отрабатывать с приложением.
Перемотка. Не любим рекламу, которая встроена в видео, или хотим перемотать до припева? Перемотка — наше все, но только если у нее удобный шаг. Согласитесь, не суперкруто, когда перемотка идёт вперёд сразу на минуту, когда хотелось бы перемотать на несколько секунд. Хорошо, когда она настраивается в приложении. Обговорите с командой и заказчиком, проведите исследование и предоставьте доказательство того, что это неудобно. И потом вам скажут спасибо.
Удобство расположения кнопок на плеере и какую роль они играют. Например, кнопка настроек в левом верхнем углу. Представили? Согласен, неудобно совсем. Если вы держите телефон с диагональю 6,6 дюйма правой рукой и пытаетесь дотянуться до кнопки настроек — могу только пожелать удачи. Сделать это могут не только лишь все.
Стриминг на ТВ. Вначале я не обратил никакого внимания на то, что существует стриминг из приложений на ТВ. Но попробовал один раз и уже не могу остановиться.
Смотреть видео на большом экране с любимыми закусками и лежа на диване — огромное удовольствие. Не лишайте пользователей этого — укажите на это команде сразу. AirPlay для iOS или любой другой каст для Android — залог отсутствия негативных отзывов от пользователей на тему «Кто смотрит контент в 2к22 на телефоне?»
Важно не только указать, что можно кастить на ТВ, но и проверить на нескольких моделях ТВ возможность каста. Да, в этом случае придется прибегнуть к помощи коллег, но оно того стоит.
В тестировании видеостримингов нет ничего сложного по части кода, зато много продуктовой работы
С технической стороны QA ждёт всё то же самое, что и в других приложениях: всё те же компонентные проверки на каждый элемент плеера плюс некоторые особенности с интеграциями библиотек или фич.
А вот продуктовки и головняка с логикой будет много: я говорю про мелкие вещи типа «следить за поведением контролов в каких-то супернеочевидных кейсах» или «следить за удобством расположения разных кнопок, когда смотришь видео лежа на диване».
И это весьма важные моменты, ведь мы смотрим на проект не с точки зрения «проверить, чтобы всё было по ТЗ», а именно с точки зрения качества итогового продукта. И если не учесть этих мелочей, продукт будет качественный с точки зрения отсутствия багов, но некачественный с точки зрения пользовательского опыта.
Поэтому, дорогие друзья, по коду — делайте вашу обычную работу. А вот по логике — объединяйтесь с продактами и аналитиками и фигачьте, чтобы всё было круто и красиво.