Flutter реализует логику полноэкранного воспроизведения и анализа видео.

Android Flutter
Flutter реализует логику полноэкранного воспроизведения и анализа видео.

Введение

Я считаю, что студенты, которые занимались разработкой мобильного видео, должны понимать, что реализовать логику воспроизведения видео из обычного воспроизведения в полноэкранное не очень просто.GSYVideoPlayerЭффект динамического полноэкранного перехода вSurfaceзаменить реализацию:

  • Создать совершенно новыйSurface, и будет дляViewдобавлен на верхний уровень приложенияDecorViewсередина;
  • Поместите только что созданныйSurfaceи установите Player Core ;
  • синхронизировать дваViewПараметры состояния воспроизведения и интерфейс системы вращения;
  • Удалить при выходе из полноэкранного режимаDecorViewсерединаSurface, переключает элемент спискаSurfaceВ Player Core, статус синхронизации.

Конечно, ядро ​​разных игроков может потребоваться выполнить некоторые дополнительные операции,Но все это предельно просто во Flutter.

На самом деле реализовать эффект полноэкранного переключения во Flutter очень просто, позже мы объясним, почему его так легко реализовать во Flutter.

2. Осознайте эффект

Как показано на рисунке ниже, это полноэкранный эффект, достигнутый во Flutter, и ключом к достижению этого эффекта являетсяПросто прыгайте в стек, и все готово! Да, вы можете добиться плавного полноэкранного переключения во Flutter, просто пропуская страницы.

Как показано в следующем коде, сначала добавьте официальный сайт под обычную страницу воспроизведения.video_playerплагинVideoPlayerконтролировать и инициализироватьVideoPlayerControllerИспользуется для загрузки и инициализации видео, которое необходимо воспроизвести, а также используется здесьHeroЭлемент управления используется для реализации анимационного эффекта перехода между страницами.

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.network(
        'https://res.exexm.com/cw_145225549855002')
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });
  }
  
 Container(
   height: 200,
   margin: EdgeInsets.only(
       top: MediaQueryData.fromWindow(
               WidgetsBinding.instance.window)
           .padding
           .top),
   color: Colors.black,
   child: _controller.value.initialized
       ? Hero(
           tag: "player",
           child: AspectRatio(
             aspectRatio: _controller.value.aspectRatio,
             child: VideoPlayer(_controller),
           ),
         )
       : Container(
           alignment: Alignment.center,
           child: CircularProgressIndicator(),
         ),
 ))

Как показано в следующем коде, позже он также используется на полноэкранных страницах.Heroконтроль иVideoPlayerЭлементы управления реализуют анимацию перехода и рендеринг видео.

здесьVideoPlayerControllerЕго можно передать через конструктор или черезInheritedWidgetДля обеспечения совместной передачи, если он такой же, как и предыдущий интерфейс обычного воспроизведения.controllerто же самое.

Container(
     color: Colors.black,
     child: Stack(
       children: <Widget>[
         Center(
           child: Hero(
             tag: "player",
             child: AspectRatio(
               aspectRatio: widget.controller.value.aspectRatio,
               child: VideoPlayer(widget.controller),
             ),
           ),
         ),
         Padding(
           padding: EdgeInsets.only(top: 25, right: 20),
           child: IconButton(
             icon: const BackButtonIcon(),
             color: Colors.white,
             onPressed: () {
               Navigator.pop(context);
             },
           ),
         )
       ],
     ),
    )

К тому же, во Flutter нужно всего лишь пройтиSystemChrome.setPreferredOrientationsМетод может быстро реализовать горизонтальное и вертикальное переключение экрана приложения.

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

  Navigator.of(context)
                      .push(MaterialPageRoute(builder: (context) {
                    return VideoFullPage(_controller);
                  }));

Это очень просто, просто нужноVideoPlayer,Heroа такжеNavigatorВы можете быстро добиться эффекта полноэкранного переключения воспроизведения,Так почему же это так просто реализовать на Flutter?

3. Логика реализации

Причина, по которой динамический полноэкранный эффект может быть достигнут так легко, в основном связана сvideo_playerРеализация плагина на Flutter:Внешняя текстураTexture.

Поскольку элементы управления во Flutter в основном не зависят от платформы, а его элементы управления в основном отрисовываются непосредственно Flutter Engine, просто:Нативная платформа предоставляет толькоActivity / ViewControllerконтейнер, после чего предоставляется контейнерSurfaceРисунок для пользователей Flutter Engine.

Таким образом, стек рендеринга элементов управления во Flutter является независимым и не может быть напрямую смешан с нативной платформой.В настоящее время, чтобы вставить некоторые функции нативной платформы во Flutter,В дополнение к предоставлениюPlatformViewВ дополнение к такой логике реализации он также обеспечиваетTextureВ качестве поддержки внешних текстур.

Как показано выше, в«Раскрытие полное настоящее объяснение»введен в,Рендеринг интерфейса Flutter требует опытаWidget -> RenderObject -> Layerпроцесс, пока вLayerво время рендеринга, когдаTextureLayerКогда узел отображается, это означает, что этот узел используетTextureэлемент управления, то содержимое этого элемента управления будет предоставлено собственной платформой, иуправлятьTextureглавным образом черезtextureIdидентифицированный.

Например, на собственном уровне Androidvideo_playerиспользуетexoplayerЗапустите ядро, затем, как показано выше,VideoPlayerControllerбудет передано во время инициализацииMethodChannelПообщайтесь с нативной стороной, затем приготовьтесь играть в ядро ​​иSurface, и, наконец, соответствующийtextureIdСнова в Дарте.

Итак, в предыдущем коде вам нужно использовать один и тот же код для полноэкранных и не полноэкранных страниц.VideoPlayerController, чтобы они были одинаковымиtextureId.

Имеют то же самоеtextureId, то пока родной слой не перестанет играть,textureIdСоответствующие исходные данные всегда находятся в обновленном состоянии, и в это время, хотя страница маршрутизации перескакивает, разныеVideoPlayerВнутреннийTextureЭлементы управления используют те жеVideoPlayerController, то есть тот самыйtextureId, поэтому они представляют общую картину.

Как показано ниже, этот процесс представляет собой краткое резюме:Flutter и нативные платформы черезPixelBufferДля взаимодействия со средой собственный слой записывает данныеPixelBuffer, Flutter проходит зарегистрированныйtextureIdполучатьPixelBufferЗатем нарисован Flutter Engine.

Последнее, что следует отметить, это то, что при реализации поворота страницы на iOSSystemChrome.setPreferredOrientationsметод может показаться недействительным, эта проблема находится в рассмотрении#23913а также#13238Упоминается, что здесь может понадобиться реализовать еще один нативный интерфейс для совместимости.auto_orientationилиorientationДругие сторонние библиотеки также совместимы в этом отношении.

Кроме того, ротация страниц iOS также определяет, включен ли переключатель конфигурации ротации..

Рекомендация ресурса