Repository navigation
[video_player][android] Video player can't render video view but can play audio #184241
Copy link
Copy link
Closed
flutter/packages
#11416Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listp: video_playerThe Video Player pluginThe Video Player pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyAndroid applications specificallyteam-androidOwned by Android platform teamOwned by Android platform teamtriaged-androidTriaged by Android platform teamTriaged by Android platform team
Description
What package does this bug report belong to?
video_player
What target platforms are you seeing this bug on?
Android
Have you already upgraded your packages?
No
Dependency versions
pubspec.lock
flutter v3.38.1
video_player: ^2.10.0
chewie: ^1.12.1
Steps to reproduce
1.Run this code 2. Click on full screen 3. Close full screen
Expected results
XiaomiHyper_os2.0.206.0.voqcnxm_Redmi.note.14.5g :
viewType: VideoViewType.textureView
After closing the full screen, the video can be rendered and played normally
Actual results
Harmory_os4.2.0_hornor.v30 :
viewType: VideoViewType.platformView
After closing the full screen, the video sound plays normally, but the video frame does not update and render, only displaying the frame from the last time the full screen was clicked
Code sample
Code sample
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(const MaterialApp(home: Video()));
class Video extends StatefulWidget {
const Video({super.key});
@override
_VideoState createState() => _VideoState();
}
class _VideoState extends State<Video> {
// 视频播放控制器
VideoPlayerController? _videoPlayerController;
@override
void initState() {
super.initState();
_initVideo();
}
@override
void dispose() {
print('dispose');
super.dispose();
disposeController();
}
void _initVideo() async {
_videoPlayerController = VideoPlayerController.networkUrl(
Uri.parse('https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8'),
viewType: VideoViewType.platformView,
);
await _videoPlayerController!.initialize();
setState(() {});
}
void disposeController() {
_videoPlayerController?.pause();
_videoPlayerController?.dispose();
_videoPlayerController = null;
}
// 进入全屏
void _goFullScreen() {
// 隐藏状态栏、导航栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
// 强制横屏
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
// 跳转到全屏页面(传递 controller 保证播放不中断)
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return FullScreenPage(controller: _videoPlayerController!);
},
),
);
}
@override
Widget build(BuildContext context) {
print('_videoPlayerController: ${_videoPlayerController != null && _videoPlayerController!.value.isInitialized}');
return Scaffold(
body: Center(
child: _videoPlayerController != null && _videoPlayerController!.value.isInitialized
? AspectRatio(
aspectRatio: _videoPlayerController!.value.aspectRatio,
child: Stack(
alignment: Alignment.bottomRight,
children: [
VideoPlayer(_videoPlayerController!),
// 播放暂停按钮
Positioned(
top: 0,
left: 0,
child: IconButton(
onPressed: () {
setState(() {
_videoPlayerController!.value.isPlaying
? _videoPlayerController!.pause()
: _videoPlayerController!.play();
});
},
icon: Icon(
_videoPlayerController!.value.isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
size: 30,
),
),
),
// 全屏按钮
IconButton(
onPressed: _goFullScreen,
icon: const Icon(Icons.fullscreen, color: Colors.white, size: 26),
),
VideoProgressIndicator(_videoPlayerController!, allowScrubbing: true),
],
),
)
: const CircularProgressIndicator(),
),
);
}
}
class FullScreenPage extends StatelessWidget {
final VideoPlayerController controller;
const FullScreenPage({super.key, required this.controller});
@override
Widget build(BuildContext context) {
return PopScope(
onPopInvokedWithResult: (bool didPop, result) async {
// 返回时恢复竖屏 + 状态栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
},
child: Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Stack(
alignment: Alignment.bottomRight,
children: [
GestureDetector(
onTap: () {
controller.value.isPlaying ? controller.pause() : controller.play();
},
child: VideoPlayer(controller),
),
Padding(
padding: const EdgeInsets.all(20),
child: IconButton(
icon: const Icon(Icons.fullscreen_exit, color: Colors.white, size: 28),
onPressed: () {
Navigator.pop(context); // 返回上一页
},
),
),
VideoProgressIndicator(controller, allowScrubbing: true),
],
),
),
),
);
}
}
Screenshots or Videos
Screenshots / Video demonstration
这个采用的是:viewType: VideoViewType.platformViewHarmory_os4.2.0_hornor.v30.mp4
这个采用的是:viewType: VideoViewType.textureView
XiaomiHyper_os2.0.206.0.voqcnxm_Redmi.note.14.5g.mp4
Logs
Logs
[Paste your logs here]Flutter Doctor output
Doctor output
无主要信息Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P2Important issues not at the top of the work listImportant issues not at the top of the work listp: video_playerThe Video Player pluginThe Video Player pluginpackageflutter/packages repository. See also p: labels.flutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyAndroid applications specificallyteam-androidOwned by Android platform teamOwned by Android platform teamtriaged-androidTriaged by Android platform teamTriaged by Android platform team
Activity
mbcorona commentedon Mar 27, 2026
Hi @lix-wood
Thanks for the report. It is difficult to tell if this is a bug in the first-party video_player plugin, or an issue with how the third-party chewie package manages the widget tree during fullscreen route transitions.
To help us investigate, could you please:
Provide a minimal reproducible code sample that does not use the chewie package. Try to implement the fullscreen push manually using only video_player to see if the freeze still occurs.
Run flutter upgrade to ensure this hasn't already been fixed in the latest stable release.
Provide the full output of flutter doctor -v (currently missing).
lix-wood commentedon Mar 30, 2026
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
class Video extends StatefulWidget {
@OverRide
_VideoState createState() => _VideoState();
}
class _VideoState extends State
// 视频播放控制器
VideoPlayerController? _videoPlayerController;
@OverRide
void initState() {
super.initState();
_initVideo();
}
@OverRide
void dispose() {
print('dispose');
super.dispose();
disposeController();
}
void _initVideo() async {
_videoPlayerController = VideoPlayerController.networkUrl(
Uri.parse('https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8'),
viewType: VideoViewType.platformView
);
await _videoPlayerController!.initialize();
setState(() {
}
void disposeController() {
_videoPlayerController?.pause();
_videoPlayerController?.dispose();
_videoPlayerController = null;
}
// 进入全屏
void _goFullScreen() {
// 隐藏状态栏、导航栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
// 强制横屏
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
DeviceOrientation.landscapeRight,
]);
}
@OverRide
Widget build(BuildContext context) {
print('_videoPlayerController: ${_videoPlayerController != null && _videoPlayerController!.value.isInitialized}');
return Scaffold(
body:Center(
child: _videoPlayerController != null && _videoPlayerController!.value.isInitialized
? AspectRatio(
aspectRatio: _videoPlayerController!.value.aspectRatio,
child: Stack(
alignment: Alignment.bottomRight,
children: [
VideoPlayer(_videoPlayerController!),
// 播放暂停按钮
Positioned(
top: 0,
left: 0,
child: IconButton(
onPressed: () {
setState(() {
_videoPlayerController!.value.isPlaying ? _videoPlayerController!.pause() : _videoPlayerController!.play();
});
},
icon: Icon(
_videoPlayerController!.value.isPlaying ? Icons.pause : Icons.play_arrow,
color: Colors.white,
size: 30,
),
),
),
// 全屏按钮
IconButton(
onPressed: _goFullScreen,
icon: const Icon(Icons.fullscreen, color: Colors.white, size: 26),
),
VideoProgressIndicator(_videoPlayerController!, allowScrubbing: true),
],
),
)
: const CircularProgressIndicator(),
),
);
}
}
class FullScreenPage extends StatelessWidget {
final VideoPlayerController controller;
const FullScreenPage({super.key, required this.controller});
@OverRide
Widget build(BuildContext context) {
return PopScope(
onPopInvokedWithResult: (bool didPop, result) async {
// 返回时恢复竖屏 + 状态栏
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
},
child: Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Stack(
alignment: Alignment.bottomRight,
children: [
GestureDetector(
onTap: () {
controller.value.isPlaying ? controller.pause() : controller.play();
},
child: VideoPlayer(controller),
),
Padding(
padding: const EdgeInsets.all(20),
child: IconButton(
icon: const Icon(Icons.fullscreen_exit, color: Colors.white, size: 28),
onPressed: () {
Navigator.pop(context); // 返回上一页
},
),
),
VideoProgressIndicator(controller, allowScrubbing: true),
],
),
),
),
);
}
}
Harmory_os4.2.0_hornor.v30 中使用: viewType: VideoViewType.platformView
Harmory_os4.2.0_hornor.v30.mp4
XiaomiHyper_os2.0.206.0.voqcnxm_Redmi.note.14中使用: viewType: VideoViewType.textureView
XiaomiHyper_os2.0.206.0.voqcnxm_Redmi.note.14.mp4
moepanda commentedon Mar 30, 2026
Summary of findings on the "frozen video" bug after exiting full screen (PlatformView mode):
After deep investigation, this issue appears to be an architectural incompatibility between Chewie's fullscreen implementation and Flutter's PlatformView rendering.
Root Cause
Chewie handles fullscreen by pushing a new
PageRoute. InVideoViewType.platformViewmode, this forced route transition disrupts the connection between the FlutterVideoPlayerwidget and the underlying native surface.Verification Results
I performed several cross-tests to confirm this:
Stack(noNavigator.push). Since the widget instance remains the same, thePlatformViewconnection stays stable.Conclusion
This is not a bug in the Flutter engine, but a limitation of using
Navigator-based fullscreen transitions withPlatformView.Suggested Workaround
VideoViewType.textureViewfor best compatibility with Chewie.platformViewis required, avoid usingNavigatorfor fullscreen; instead, use an in-place layout transformation.lix-wood commentedon Mar 30, 2026
mbcorona commentedon Mar 30, 2026
Hi @lix-wood , thank you for providing a code sample without external packages. I was able to reproduce the issue on Flutter 3.41.4, after exiting full-screen audio continues playing, but video stops, video_player video_player: ^2.11.1 when viewType: VideoViewType.platformView,
Routing this to team-android for further investigation.
kailane1231ho-code commentedon Mar 30, 2026
moepanda commentedon Apr 2, 2026
Update: I would like to correct my previous comment. I originally didn't look closely enough at the reproduction demo provided and was instead testing with my own "Stack-based" fullscreen implementation, which behaved differently.
Upon further investigation of the Navigator-based transition used in the original reproduction case, I found that the native Surface is indeed detached during the route transition. While I previously suggested a workaround, I have now discovered a way to handle this recovery directly within the engine by listening to visibility changes.
I've submitted a PR [https://github.com/flutter/packages/pull/11416] that implements a robust re-binding mechanism in the Android PlatformView, which should resolve the rendering freeze for all Navigator-based fullscreen transitions.
lix-wood commentedon Apr 2, 2026
Okay, thank you very much for your help!
[video_player_android] Fix rendering freeze after full-screen transit… (
github-actions commentedon Jul 14, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of
flutter doctor -vand a minimal reproduction of the issue.