-
Notifications
You must be signed in to change notification settings - Fork 28.4k
First Frame of Video Once VideoPlayer Controller doesn't show in iOS Safari/Chrome #139107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hi @austinlee1993 Complete sample codeimport 'dart:async';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(const VideoPlayerApp());
class VideoPlayerApp extends StatelessWidget {
const VideoPlayerApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Video Player Demo',
home: VideoPlayerScreen(),
);
}
}
class VideoPlayerScreen extends StatefulWidget {
const VideoPlayerScreen({super.key});
@override
State<VideoPlayerScreen> createState() => _VideoPlayerScreenState();
}
class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
late VideoPlayerController _controller;
late Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
super.initState();
// Create and store the VideoPlayerController. The VideoPlayerController
// offers several different constructors to play videos from assets, files,
// or the internet.
_controller = VideoPlayerController.networkUrl(
Uri.parse(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
),
);
// Initialize the controller and store the Future for later use.
_initializeVideoPlayerFuture = _controller.initialize();
// Use the controller to loop the video.
_controller.setLooping(true);
}
@override
void dispose() {
// Ensure disposing of the VideoPlayerController to free up resources.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Butterfly Video'),
),
// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
body: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the VideoPlayerController has finished initialization, use
// the data it provides to limit the aspect ratio of the video.
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
// Use the VideoPlayer widget to display the video.
child: VideoPlayer(_controller),
);
} else {
// If the VideoPlayerController is still initializing, show a
// loading spinner.
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Wrap the play or pause in a call to `setState`. This ensures the
// correct icon is shown.
setState(() {
// If the video is playing, pause it.
if (_controller.value.isPlaying) {
_controller.pause();
} else {
// If the video is paused, play it.
_controller.play();
}
});
},
// Display the correct icon depending on the state of the player.
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
}
This may be similar to #41156. |
Hi @huycozy - thanks for the quick response - I tried the following code and the first frame still does not initialize in iOS Safari. I attached a screen recording of the implementation. RPReplay_Final1701200748.mov |
Sorry, I typed it wrong. I meant the issue appears on both Web (iOS browsers) and iOS app. I checked this again and confirmed the issue is only on Web (iOS browsers: Safari, Chrome). On iOS Flutter app, the first frame (or video thumbnail) is rendering normally; the same on Chrome browser on Android.
✅: No Issue ❗: Issue reproduced flutter doctor -v (stable and master)[✓] Flutter (Channel stable, 3.16.1, on macOS 14.1 23B74 darwin-x64, locale en-VN)
• Flutter version 3.16.1 on channel stable at /Users/huynq/Documents/GitHub/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 7f20e5d18c (9 hours ago), 2023-11-27 09:47:30 -0800
• Engine revision 22b600f240
• Dart version 3.2.1
• DevTools version 2.28.3
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/huynq/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• ANDROID_HOME = /Users/huynq/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15A507
• CocoaPods version 1.13.0
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[!] Android Studio (version unknown)
• Android Studio at /Applications/Android Studio Preview.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
✗ Unable to determine Android Studio version.
• Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)
[✓] Android Studio (version 2022.3)
• Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
[✓] Android Studio (version 2022.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• android-studio-dir = /Applications/Android Studio.app/
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
[✓] VS Code (version 1.84.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.76.0
[✓] Connected device (3 available)
• RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64 • Android 11 (API 30)
• macOS (desktop) • macos • darwin-x64 • macOS 14.1 23B74 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 119.0.6045.159
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category. [!] Flutter (Channel master, 3.17.0-17.0.pre.47, on macOS 14.1 23B74 darwin-x64, locale en-VN)
• Flutter version 3.17.0-17.0.pre.47 on channel master at /Users/huynq/Documents/GitHub/flutter_master
! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 7a0508e5de (10 minutes ago), 2023-11-28 22:01:04 -0500
• Engine revision 4beaa1195b
• Dart version 3.3.0 (build 3.3.0-170.0.dev)
• DevTools version 2.30.0-dev.4
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
• Android SDK at /Users/huynq/Library/Android/sdk
• Platform android-34, build-tools 34.0.0
• ANDROID_HOME = /Users/huynq/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.0.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 15A507
• CocoaPods version 1.13.0
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[!] Android Studio (version unknown)
• Android Studio at /Applications/Android Studio Preview.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
✗ Unable to determine Android Studio version.
• Java version OpenJDK Runtime Environment (build 17.0.8+0-17.0.8b1000.22-10799086)
[✓] Android Studio (version 2022.3)
• Android Studio at /Applications/Android Studio Giraffe Patch 3.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)
[✓] Android Studio (version 2022.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• android-studio-dir = /Applications/Android Studio.app/
• Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
[✓] VS Code (version 1.84.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.76.0
[✓] Connected device (4 available)
• RMX2001 (mobile) • EUYTFEUSQSRGDA6D • android-arm64 • Android 11 (API 30)
• iPhone (mobile) • d9a94afe2b649fef56ba0bfeb052f0f2a7dae95e • ios • iOS 15.8 19H370
• macOS (desktop) • macos • darwin-x64 • macOS 14.1 23B74 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 119.0.6045.159
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 2 categories. |
I am still facing this on ios, the first frame does not automatically show up. Is there any work around? |
The issue seems to be that when we call I fixed it by adding a listener that checks that something has actually buffered (
|
HI @rogisolorzano thanks for looking into this - I'm trying the code you provided but it seems when the _controller.value.buffered is being checked on whether or not it is being empty, the _controller.value.buffered is empty hence the setState is never called; what can be done to make sure the setState will be called? |
Hey @austinlee1993, I noticed this as well after testing on more platforms. I ended up going with seeking after initialization to force something to be buffered.
I also had to add a small delay between when we detect something is buffered and when we call It seems like having a way to reliably know when the first frame is ready across platforms would be valuable to have in |
@rogisolorzano - I'm still encountering the same issue I had before - even adding the .seekTo method after initialization, by the time _listenForFirstFrameReady() is running, the _controller.value.buffered is still empty, so I cant get the other things to even run - interesting to see how you got it to run on your end. |
@austinlee1993 I only tested on iOS and Android (native), looks like it might not work in browsers for some reason 😭 FWIW, I ultimately abandoned that approach and decided to generate a thumbnail in my backend as part of processing the video. I show the thumbnail before the video is played for the first time, using a For larger videos, getting that first frame in a state where it is ready to display can take a bit. A lightweight thumbnail image loads quickly and feels much snappier to the user. |
@rogisolorzano - would be interested in seeing how to generate the thumbnail in the backend! Maybe there's a small chance it could work for me.. But anyway - really odd the thumbnail doesn't generate by default for mobile browser - it works for desktop browser hence why I was hoping the video_player team could look into this. |
This comment was marked as duplicate.
This comment was marked as duplicate.
How can I ever thank you? |
Implement thumbnail image based video previews for Youtube & Vimeo video links, and inline video player preview using the video_player package for user uploaded videos. For user uploaded video, current implementation will fetch the metadata when the message containing the video comes into view. This metadata is used by the player to determine if video is supported on the device. If it isn't then there will be no preview, and tapping on the play button will open the video externally. If the video is supported, then the first frame of the video will be presented as a preview in the message container while tapping on the play button will start buffering and playing the video in the lightbox. There are still some quirks with the current implementation: - On iOS/macOS, there is a bug where whole video is downloaded before playing: flutter/flutter#126760 - On iOS/macOS, unlike on Android the first frame is not shown after initialization: flutter/flutter#139107 - Current implementation uses url_launcher for fallback in case video is not supported by video_player, we should switch to webview instead to correctly handle auth headers for private videos. Fixes zulip#356
Implement thumbnail image based video previews for Youtube & Vimeo video links, and inline video player preview using the video_player package for user uploaded videos. For user uploaded video, current implementation will fetch the metadata when the message containing the video comes into view. This metadata is used by the player to determine if video is supported on the device. If it isn't then there will be no preview, and tapping on the play button will open the video externally. If the video is supported, then the first frame of the video will be presented as a preview in the message container while tapping on the play button will start buffering and playing the video in the lightbox. There are still some quirks with the current implementation: - On iOS/macOS, there is a bug where whole video is downloaded before playing: flutter/flutter#126760 - On iOS/macOS, unlike on Android the first frame is not shown after initialization: flutter/flutter#139107 - Current implementation uses url_launcher for fallback in case video is not supported by video_player, we should switch to webview instead to correctly handle auth headers for private videos. Fixes zulip#356
Implement thumbnail image based video previews for Youtube & Vimeo video links, and inline video player preview using the video_player package for user uploaded videos. For user uploaded video, current implementation will fetch the metadata when the message containing the video comes into view. This metadata is used by the player to determine if video is supported on the device. If it isn't then there will be no preview, and tapping on the play button will open the video externally. If the video is supported, then the first frame of the video will be presented as a preview in the message container while tapping on the play button will start buffering and playing the video in the lightbox. There are still some quirks with the current implementation: - On iOS/macOS, there is a bug where whole video is downloaded before playing: flutter/flutter#126760 - On iOS/macOS, unlike on Android the first frame is not shown after initialization: flutter/flutter#139107 - Current implementation uses url_launcher for fallback in case video is not supported by video_player, we should switch to webview instead to correctly handle auth headers for private videos. Fixes zulip#356
Implement thumbnail image based video previews for Youtube & Vimeo video links, and inline video player preview using the video_player package for user uploaded videos. For user uploaded video, current implementation will fetch the metadata when the message containing the video comes into view. This metadata is used by the player to determine if video is supported on the device. If it isn't then there will be no preview, and tapping on the play button will open the video externally. If the video is supported, then the first frame of the video will be presented as a preview in the message container while tapping on the play button will start buffering and playing the video in the lightbox. There are still some quirks with the current implementation: - On iOS/macOS, there is a bug where whole video is downloaded before playing: flutter/flutter#126760 - On iOS/macOS, unlike on Android the first frame is not shown after initialization: flutter/flutter#139107 - Current implementation uses url_launcher for fallback in case video is not supported by video_player, we should switch to webview instead to correctly handle auth headers for private videos. Fixes zulip#356
Implement thumbnail image based video previews for Youtube & Vimeo video links, and inline video player preview using the video_player package for user uploaded videos. For user uploaded video, current implementation will fetch the metadata when the message containing the video comes into view. This metadata is used by the player to determine if video is supported on the device. If it isn't then there will be no preview, and tapping on the play button will open the video externally. If the video is supported, then the first frame of the video will be presented as a preview in the message container while tapping on the play button will start buffering and playing the video in the lightbox. There are still some quirks with the current implementation: - On iOS/macOS, there is a bug where whole video is downloaded before playing: flutter/flutter#126760 - On iOS/macOS, unlike on Android the first frame is not shown after initialization: flutter/flutter#139107 - Current implementation uses url_launcher for fallback in case video is not supported by video_player, we should switch to webview instead to correctly handle auth headers for private videos. Fixes zulip#356
As a temporary workaround, you can append the Or you can use the following branch as a
|
Is there an existing issue for this?
What package does this bug report belong to?
video_player
What target platforms are you seeing this bug on?
iOS
Have you already upgraded your packages?
Yes
Dependency versions
pubspec.lock
Steps to reproduce
Initialize VideoPlayer Controller with video with SetState called
Expected results
I expect to see the first frame of the video to appear
Actual results
Nothing shows up for iOS Safari/chrome - the width and height of the frame appear so its a blank box. What's also strange is it works in Android and my MacOS Desktop.
Code sample
Code sample
Screenshots or Videos
Screenshots / Video demonstration
First photo is the code in iOS Safari, next one is MacOS Desktop
Logs
Logs
[Paste your logs here]
Flutter Doctor output
Doctor output
The text was updated successfully, but these errors were encountered: