Олег Марков
Работа с видео в React Native
Введение
Работа с видео в мобильных приложениях становится все более актуальной задачей при разработке на React Native. Видео часто используется в образовательных, развлекательных, новостных сервисах и многих других платформах. Важно уметь не только отображать видео, но и управлять проигрывателем, отслеживать статус воспроизведения, реагировать на различные события и заботиться об оптимальной производительности.
В этой статье вы узнаете, как реализовать работу с видео в вашем React Native приложении, какие существуют популярные библиотеки для этого, как подключать компоненты проигрывания, настраивать их и использовать различные возможности работы с видеофайлами и потоками.
Популярные библиотеки для работы с видео
Почему нельзя просто использовать стандартные компоненты?
React Native из коробки не предоставляет готового компонента для работы с видео. Для этих целей принято использовать сторонние библиотеки. Самой популярной является react-native-video
, но есть и альтернативы, например, expo-av
(если вы используете Expo), или специализированные нативные модули.
react-native-video
react-native-video
— максимально гибкая и широко используемая библиотека для интеграции видео в React Native. Она поддерживает множество форматов, потоковое видео, работу с локальными файлами и урлами, контролирует буферизацию и может быть расширена кастомизированными контроллерами.
Установка
Первый шаг — установка библиотеки и связывающих скриптов.
Если вы используете bare React Native проект:
npm install react-native-video
# или
yarn add react-native-video
После этого выполните pod install, если работаете с iOS:
cd ios && pod install
Подключение компонента
Теперь смотрите, как просто подключить компонент:
import Video from 'react-native-video'
// в вашем компоненте
<Video
source={{ uri: 'https://www.w3schools.com/html/mov_bbb.mp4' }} // URL или require('путь/к/файлу.mp4')
style={{ width: '100%', height: 300 }} // размеры проигрывателя
/>
Так вы добавляете базовое видео. Весьма просто, правда?
Работа с видео в React Native включает в себя не только интеграцию плеера, но и захват видео с камеры, обработку, кодирование и загрузку на сервер. Для этого требуется знание нативных API, библиотек для работы с видео и понимание принципов оптимизации. Важно также учитывать особенности различных платформ и обеспечивать совместимость. Если вы хотите детальнее погрузиться в работу с видео и другие нативные возможности в React Native, — приходите на наш большой курс React Native и Expo Router. На курсе 184 уроков и 11 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Expo-av
Если ваше приложение использует Expo, самое удобное решение — модуль expo-av
. Вам не нужно связывать нативные части вручную.
Установка
expo install expo-av
Пример использования
import { Video } from 'expo-av'
import { View } from 'react-native'
<View>
<Video
source={{ uri: 'https://www.w3schools.com/html/mov_bbb.mp4' }}
style={{ width: 320, height: 240 }}
useNativeControls
resizeMode="contain"
/>
</View>
Поле useNativeControls
добавляет встроенные элементы управления.
Ключевые возможности работы с видео
Форматы и источники видео
И react-native-video
, и expo-av
поддерживают файлы MP4, MOV, HLS и другие популярные форматы. В качестве источника возможно использовать:
- Локальные файлы:
require('./video.mp4')
- Ссылки на сервере:
{ uri: 'https://...' }
- Потоковое видео по протоколу HLS
Элементы управления воспроизведением
Базовые пропсы
Давайте рассмотрим основные пропсы для управления видео.
<Video
source={{ uri: 'https://example.com/video.mp4' }}
paused={false} // Видео начнет воспроизводиться сразу
repeat={true} // Видео зациклено
muted={false} // Не выключать звук
volume={1.0} // Максимальная громкость
controls={true} // Показывать стандартные контролы (Android)
/>
На iOS встроенных контролов нет, их нужно добавлять самостоятельно.
Кастомные контроллы
Если интерфейс приложения требует уникальных кнопок «Play», «Pause», «Fullscreen» и других действий, их придется реализовать вручную. Например:
// пример управления воспроизведением из собственного состояния
const [paused, setPaused] = useState(true)
<Video
source={{ uri: 'https://example.com/video.mp4' }}
paused={paused}
style={{ width: 350, height: 200 }}
/>
<Button title={paused ? "Play" : "Pause"} onPress={() => setPaused(prev => !prev)} />
Отслеживание событий воспроизведения
Вы можете обработать массу событий: запуск, окончание, ошибки, прогресс, буферизацию.
Пример работы с событиями
<Video
source={{ uri: videoUri }}
onEnd={() => console.log('Видео завершено!')}
onError={err => console.log('Ошибка видео:', err)}
onProgress={status => console.log('Прошло секунд:', status.currentTime)}
onLoad={meta => console.log('Длительность:', meta.duration)}
/>
onLoad
срабатывает при полной загрузке файла, здесь удобно получить метаданные.onProgress
вызывается во время воспроизведения, помогает отображать прогрессбар.onEnd
сигнализирует о завершении видео.
Картинка при загрузке и обложка
Зачастую нужно показывать изображение пока видео еще не началось. В react-native-video
для этого доступны пропсы poster
и posterResizeMode
.
<Video
source={{ uri: videoUri }}
poster="https://example.com/some-image.jpg"
posterResizeMode="cover"
paused
/>
Это повысит уровень UX для пользователей с медленным подключением.
Переключение полноэкранного режима
Полноэкранный режим — важная фича для медиа-приложений. Пример управления fullscreen на Android:
// Просто передайте controls={true} — появляется стандартная кнопка Fullscreen
<Video
source={{ uri: videoUri }}
controls={true}
/>
Реализация полноэкранного режима на iOS требует отдельного экрана или кастомной обертки из-за ограничений платформы. Обычно используют сторонние обертки или отдельный модальный экран.
Буферизация и указание статуса загрузки
Если ваше видео грузится с сервера, пользователям будет полезно видеть индикатор загрузки.
const [buffering, setBuffering] = useState(false)
<Video
source={{ uri: videoUri }}
onBuffer={({ isBuffering }) => setBuffering(isBuffering)}
/>
{buffering && <ActivityIndicator />}
Работа с субтитрами
react-native-video
позволяет подключать субтитры:
<Video
source={{ uri: videoUri }}
textTracks={[
{
title: "Русский",
language: "ru",
type: TextTrackType.VTT,
uri: "https://example.com/subs-ru.vtt"
}
]}
selectedTextTrack={{
type: "system"
}}
/>
Это очень удобно для обучения и мультиязычных приложений.
Потоковое воспроизведение (HLS и DASH)
Видео по протоколу HLS (.m3u8
) и DASH (.mpd
) можно воспроизводить прямо так:
<Video source={{ uri: 'https://example.com/playlist.m3u8' }} />
Поддержка этих протоколов работает на обеих платформах, но на Android дополнительных настроек может не требоваться, а на iOS лучше использовать последние версии библиотеки.
Снимки кадра (thumbnail)
Функция создания превью, к сожалению, прямо из коробки недоступна. Обычно используют сторонние сервисы или предварительно генерируют превью на сервере. В Expo пакете есть VideoThumbnails
, а для bare React Native — сторонние плагины.
Работа с локальными видеофайлами
Для внедрения локального файла используйте require:
<Video source={require('./assets/video.mp4')} />
Либо путь к файлу на устройстве (например, для скачанного видео):
<Video source={{ uri: 'file:///path/to/file.mp4' }} />
Для работы с файловой системой часто применяют пакет react-native-fs
— он помогает копировать и удалять файлы.
Советы по производительности
Работая с видео, важно оптимизировать код во избежание большого расхода памяти и лагов на слабых устройствах.
- Не используйте слишком большие размеры видео и bit rate, если не требуется full HD.
- Контролируйте количество одновременно проигрываемых компонент Video на экране.
- Используйте миниатюры и placeholder для видео, чтобы не грузить большой ролик сразу.
- Для стримминга выбирайте HLS или DASH форматы.
Работа с видео в Expo: отличия
Expo значительно упрощает установку, но накладывает ограничения — доступно меньше системных пропсов, кастомизаций, глубокой нативной интеграции. Однако, для большинства задач — базового проигрывателя с контроллами — этого вполне хватает.
В Expo также доступно:
- Автоматическое получение разрешений
- Проигрывание в фоне
- Получение статуса и контроль громкости
Пример отслеживания состояния
const videoRef = useRef(null);
<Video
ref={videoRef}
onPlaybackStatusUpdate={status => console.log('Видео статус:', status)}
useNativeControls
source={{ uri: videoUri }}
/>
Особенности на Android и iOS
iOS
- На iOS часто требуется прописать разрешения на использование звука.
- Нет штатного fullscreen — его стоит реализовывать самому.
- Если требуется PiP (Picture-in-Picture) или воспроизведение в фоне — выбирайте свежую версию библиотеки.
Android
- Контроллы с
controls={true}
сразу добавляют полноэкранные кнопки. - Возможна потеря синхронизации аудио видеопотока на очень старых устройствах; обновление ExoPlayer помогает.
Интеграция с redux и обработка состояний
В больших приложениях часто возникает задача синхронизировать состояние видео с глобальным стейтом.
// Redux action: setPaused, глобальное управление
dispatch({ type: 'VIDEO_SET_PAUSED', payload: true })
// и в компонентах — подписываемся на статус
const paused = useSelector(state => state.video.paused)
<Video paused={paused} ... />
Импорт собственного плеера
В некоторых проектах стандартные решения не подходят — тогда популярно разрабатывать кастомный плеер на основе open-source библиотеки, добавляя свои контроллы, заголовки, overlay, функцию «смотреть позже» и т.д.
Заключение
Работа с видео в React Native приложениях бывает разной сложности — от вставки одного ролика до масштабных медиаплатформ с потоками, плеерами и расширенным UI. С помощью react-native-video
или expo-av
большинство задач решается просто, главное — правильно подбирать библиотеку под ваш стек и требования. Важно учитывать особенности платформ, резервировать время на кастомизацию для iOS, заранее планировать UX для управления загрузкой и буферизацией. Используйте приведенные выше примеры как основу и не бойтесь экспериментировать, если ваше приложение требует уникальных решений.
Работа с видео это важный аспект, но не стоит забывать, что приложение должно быть удобным и интуитивно понятным. Необходимо уметь создавать переиспользуемые компоненты, управлять состоянием, обеспечивать навигацию и работать с API. На нашем курсе React Native и Expo Router вы найдете все необходимые знания для создания профессиональных React Native приложений. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир React Native прямо сегодня.
Частозадаваемые технические вопросы
Как реализовать быстрый переход по видео (seek) на нужную позицию?
Для этого используйте ссылку на Video через ref и метод .seek(timeInSeconds)
:
jsx
const videoRef = useRef(null);
// Перемотать на 10 сек вперед
videoRef.current.seek(10);
Работает как с react-native-video
, так и с Expo Video. На некоторых версиях Android нужен небольшой delay после mount компонента.
Как загрузить субтитры из файла на устройстве?
Используйте параметр textTracks
и задайте абсолютный путь к локальному файлу субтитров:
jsx
textTracks={[{
title: 'Русский', language: 'ru', type: TextTrackType.VTT,
uri: 'file:///storage/emulated/0/Download/subs.vtt'
}]}
Важно — убедитесь, что у приложения разрешение на работу с файловой системой.
Как сохранить видеофайл из сети к себе в память устройства?
Потребуется библиотека react-native-fs
или expo-file-system
. Примерно так:
js
import RNFS from 'react-native-fs';
const url = 'https://example.com/video.mp4';
const destPath = RNFS.DocumentDirectoryPath + '/video.mp4';
RNFS.downloadFile({ fromUrl: url, toFile: destPath }).promise.then(...);
Почему видео не проигрывается на iOS, хотя ссылка работает в браузере?
На iOS действует строгий CORS и HLS/MP4 требования безопасности. Проверьте, поддерживает ли видео формат, установлен ли HTTPS и выставлены ли правильные заголовки на сервере.
Как вывести видео поверх других элементов (overlay)?
Используйте стили Position Absolute и ZIndex:
jsx
<Video style={{ ...StyleSheet.absoluteFillObject, zIndex: 99 }} />
Обязательно управляйте размерами и положением контейнера для overlay.
Постройте личный план изучения React-native до уровня Middle — бесплатно!
React-native — часть карты развития Mobile
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по React-native
Лучшие курсы по теме

React Native и Expo Router
Антон Ларичев
Основы JavaScript
Антон Ларичев