Введение
Я считаю, что студенты, которые занимались разработкой мобильного видео, должны понимать, что реализовать логику воспроизведения видео из обычного воспроизведения в полноэкранное не очень просто.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 также определяет, включен ли переключатель конфигурации ротации..
Рекомендация ресурса
- Демонстрация этой статьи:flutter_video_full_controller
- Гитхаб:github.com/CarGuo
- Полный проект Flutter с открытым исходным кодом:GitHub.com/car GU O/GS YG…
- Учебный проект Flutter с открытым исходным кодом для нескольких случаев:GitHub.com/car GU O/GS YF…
- Проект практической электронной книги Flttre с открытым исходным кодом:GitHub.com/car GU O/GS YF…
- Проект React Native с открытым исходным кодом:GitHub.com/car GU O/GS YG…