логотип PurpleSchool
логотип PurpleSchool

Работа с видео в 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.

Стрелочка влевоРабота со ScrollView в React NativeКак реализовать аудиоплеер на React NativeСтрелочка вправо

Постройте личный план изучения React-native до уровня Middle — бесплатно!

React-native — часть карты развития Mobile

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по React-native

Работа со ScrollView в React NativeРабота с видео в React NativeКак реализовать аудиоплеер на React NativeНастройка и использование input и textinput в React NativeИнтеграция видео плеера в приложение на React NativeИспользование выпадающих списков в React NativeСоздание и настройка native module на React NativeКак создать модальные окна в React NativeРабота с изображениями в React NativeОтображение списков данных в React NativeГайд по файловой системе в React NativeИнтеграция камеры в приложение на React NativeСоздание интерактивных кнопок в React Native
Как использовать векторные иконки в React Native5 популярных библиотек UI компонентов React NativeСоздание и использование tabs в React NativeРуководство по стилизации компонентов в React NativeОптимизация переходов между экранами в React NativeАдаптация safe area context на React NativeОбзор библиотек для навигации в React NativeСоздание сложных анимаций (reanimated) на React NativeИспользование библиотеки стилей Paper в React NativeРуководство по navigation в React NativeКак реализовать linking на React NativeОптимизация отображения списков в React NativeГайд по UI-китам для React NativeГде искать elements для приложения на React NativeРабота с цветами в React Native
Открыть базу знаний

Лучшие курсы по теме

изображение курса

React Native и Expo Router

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Основы JavaScript

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий