Skip to content

[video_player][android] Video player can't render video view but can play audio #184241

Closed
flutter/packages
#11416

Description

@lix-wood

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.platformView
Harmory_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
无主要信息

Activity

  1. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Mar 27, 2026
  2. mbcorona commented on Mar 27, 2026

    @mbcorona
    Member

    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).

  3. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Mar 30, 2026
  4. lix-wood commented on Mar 30, 2026

    @lix-wood
    Author

    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).

    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,
    ]);

    // 跳转到全屏页面(传递 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),
    ],
    ),
    ),
    ),
    );
    }
    }

    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
  5. moepanda commented on Mar 30, 2026

    @moepanda

    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. In VideoViewType.platformView mode, this forced route transition disrupts the connection between the Flutter VideoPlayer widget and the underlying native surface.

    Verification Results

    I performed several cross-tests to confirm this:

    1. Chewie + TextureView: Works perfectly (since it's just a texture, not a native window).
    2. Chewie + PlatformView: Fails (frozen video, sound remains).
    3. Manual In-place Fullscreen + PlatformView: Works perfectly. I implemented fullscreen by simply resizing the player widget within a Stack (no Navigator.push). Since the widget instance remains the same, the PlatformView connection stays stable.

    Conclusion

    This is not a bug in the Flutter engine, but a limitation of using Navigator-based fullscreen transitions with PlatformView.

    Suggested Workaround

    • Use VideoViewType.textureView for best compatibility with Chewie.
    • If platformView is required, avoid using Navigator for fullscreen; instead, use an in-place layout transformation.
  6. lix-wood commented on Mar 30, 2026

    @lix-wood
    Author
  7. added
    in triagePresently being triaged by the triage team
    platform-androidAndroid applications specifically
    packageflutter/packages repository. See also p: labels.
    team-androidOwned by Android platform team
    fyi-ecosystemFor the attention of Ecosystem team
    and removed
    in triagePresently being triaged by the triage team
    on Mar 30, 2026
  8. mbcorona commented on Mar 30, 2026

    @mbcorona
    Member

    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.

  9. kailane1231ho-code commented on Mar 30, 2026

    @kailane1231ho-code
  10. added
    P2Important issues not at the top of the work list
    triaged-androidTriaged by Android platform team
    on Mar 31, 2026
  11. moepanda commented on Apr 2, 2026

    @moepanda

    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. In VideoViewType.platformView mode, this forced route transition disrupts the connection between the Flutter VideoPlayer widget and the underlying native surface.

    Verification Results

    I performed several cross-tests to confirm this:

    1. Chewie + TextureView: Works perfectly (since it's just a texture, not a native window).
    2. Chewie + PlatformView: Fails (frozen video, sound remains).
    3. Manual In-place Fullscreen + PlatformView: Works perfectly. I implemented fullscreen by simply resizing the player widget within a Stack (no Navigator.push). Since the widget instance remains the same, the PlatformView connection stays stable.

    Conclusion

    This is not a bug in the Flutter engine, but a limitation of using Navigator-based fullscreen transitions with PlatformView.

    Suggested Workaround

    • Use VideoViewType.textureView for best compatibility with Chewie.
    • If platformView is required, avoid using Navigator for fullscreen; instead, use an in-place layout transformation.

    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.

  12. lix-wood commented on Apr 2, 2026

    @lix-wood
    Author

    退出全屏模式(平台视图模式)后“视频卡顿”问题的调查结果总结:
    经过深入调查,这个问题似乎是Chewie 的全屏实现与 Flutter 的 PlatformView 渲染之间存在架构不兼容的问题。****

    根本原因

    Chewie 通过推送一个新的PageRoute. 来处理全屏模式。在全屏模式下,这种强制路由转换会中断 Flutter组件与底层原生 SurfaceVideoViewType.platformView之间的连接。VideoPlayer

    验证结果

    我进行了多次交叉测试来证实这一点:

    1. Chewie + TextureView:完美运行(因为它只是一个纹理,而不是一个原生窗口)。
    2. Chewie + PlatformView:失败(视频冻结,声音仍然存在)。
    3. 手动全屏 + PlatformView:完美运行。我通过简单地调整播放器控件的大小Stack(无需其他控件Navigator.push)实现了全屏效果。由于控件实例保持不变,PlatformView连接保持稳定。

    结论

    这不是 Flutter 引擎的 bug,而是使用Navigator基于全屏过渡的PlatformView.

    建议的解决方法

    • 与 Chewie 搭配使用VideoViewType.textureView效果最佳。
    • 如果platformView需要,请避免使用Navigator全屏模式;而应使用就地布局转换。

    更新:我想更正一下我之前的评论。我最初没有仔细查看提供的复现示例,而是用我自己实现的基于堆栈的全屏模式进行测试,结果表现有所不同。

    在进一步调查原始复现案例中使用的基于 Navigator 的过渡效果后,我发现原生 Surface 确实在路线过渡期间被分离了。虽然我之前提出了一种变通方案,但现在我发现了一种通过监听可见性变化直接在引擎内部处理此恢复的方法。

    我提交了一个 PR [https://github.com/ flutter/packages/pull/11416 ],在 Android PlatformView 中实现了一个强大的重新绑定机制,这应该可以解决所有基于 Navigator 的全屏过渡的渲染冻结问题。

    Okay, thank you very much for your help!

  13. github-actions commented on Jul 14, 2026

    @github-actions

    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 -v and a minimal reproduction of the issue.

  14. locked as resolved and limited conversation to collaborators on Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listp: video_playerThe Video Player pluginpackageflutter/packages repository. See also p: labels.platform-androidAndroid applications specificallyteam-androidOwned by Android platform teamtriaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions