[webview_flutter][Android] Non youtube iframe video not showing up
Steps to reproduce
- Open a page with an iframe with a player playing .ts videos (some streaming services does that)
- Try playing the video
Expected results
The video starts
Actual results
Android logo appears on top left of screen and nothing happens. Also i see in debug this message: MediaCodec discarded an unknown buffer
Code sample
Code sample
import "package:flutter/material.dart";
import "package:nextflix/repositories/preferences.dart";
import "package:nextflix/services/url_modale.dart";
import "package:nextflix/utils/env.dart";
import "package:nextflix/utils/url_utils.dart";
import "package:webview_flutter/webview_flutter.dart";
import "package:webview_flutter_android/webview_flutter_android.dart";
import "package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart";
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late final WebViewController _controller;
late final Preferences preferences;
@override
void initState() {
super.initState();
final PlatformWebViewControllerCreationParams params= WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const {}
);
_controller = WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setUserAgent("Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0")
..setNavigationDelegate(NavigationDelegate(
onProgress: (int progress) {
//loading bar
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onHttpError: (HttpResponseError error) {
print(error.request?.uri.toString());
},
onWebResourceError: (WebResourceError error) {
print(error.url);
},
onUrlChange: (UrlChange change) {
print("Change: ${change.url}");
},
onNavigationRequest: (NavigationRequest request) {
return NavigationDecision.navigate;
}
))
..loadRequest('some_video_ts_iframe_player');
if (_controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(true);
(_controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
(_controller.platform as AndroidWebViewController).setCustomWidgetCallbacks(
onShowCustomWidget: (Widget widget, OnHideCustomWidgetCallback callback) {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) => widget,
fullscreenDialog: true,
));
},
onHideCustomWidget: () {
Navigator.of(context).pop();
},
);
}
}
@override
Widget build(BuildContext context) => Scaffold(body: WebViewWidget(controller: _controller));
}
Screenshots or Video
Visual result
Logs
Logs (after page opening)
D/AAudio ( 6837): AAudioStream_requestStop(s#1) called
D/AAudioStream( 6837): setState(s#1) from 4 to 9
D/AudioTrack( 6837): stop(18): called with 37000 frames delivered
D/AAudioStream( 6837): setState(s#1) from 9 to 10
I/flutter ( 6837): https://sc-b1-06.scws-content.net/hls/30/1/14/114c1804-c26c-4733-8329-3a00a9d3003a/video/720p/0001-0250.ts?token=ahtFbu1fWr04oV9BhKPyKw&expires=1725814108
W/cr_MediaCodecBridge( 6837): Releasing: c2.goldfish.h264.decoder
D/SurfaceUtils( 6837): connecting to surface 0xe97e5c98, reason connectToSurface
I/MediaCodec( 6837): [c2.goldfish.h264.decoder] setting surface generation to 7001092
D/SurfaceUtils( 6837): disconnecting from surface 0xe97e5c98, reason connectToSurface(reconnect)
D/SurfaceUtils( 6837): connecting to surface 0xe97e5c98, reason connectToSurface(reconnect)
D/Codec2-OutputBufferQueue( 6837): remote graphic buffer migration 4/4
D/Codec2Client( 6837): setOutputSurface -- failed to set consumer usage (6/BAD_INDEX)
D/Codec2Client( 6837): setOutputSurface -- generation=7001092 consumer usage=0x900
E/FrameEvents( 6837): updateAcquireFence: Did not find frame.
D/Codec2Client( 6837): Surface configure completed
D/SurfaceUtils( 6837): disconnecting from surface 0xe97ea828, reason disconnectFromSurface
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
D/CCodecBufferChannel( 6837): [c2.goldfish.h264.decoder#820] MediaCodec discarded an unknown buffer
W/cr_MediaCodecBridge( 6837): Codec released
D/SurfaceUtils( 6837): disconnecting from surface 0xe97e5c98, reason disconnectFromSurface
I/hw-BpHwBinder( 6837): onLastStrongRef automatically unlinking death recipients
D/MediaCodec( 6837): flushMediametrics
D/MediaCodec( 6837): flushMediametrics
W/MediaCodec( 6837): no metrics handle found
E/FrameEvents( 6837): updateAcquireFence: Did not find frame.
E/FrameEvents( 6837): updateAcquireFence: Did not find frame.
D/EGL_emulation( 6837): app_time_stats: avg=147.20ms min=35.77ms max=330.37ms count=7
D/EGL_emulation( 6837): app_time_stats: avg=104.40ms min=50.20ms max=168.41ms count=10
D/EGL_emulation( 6837): app_time_stats: avg=148.43ms min=59.03ms max=308.90ms count=7
D/BufferPoolAccessor2.0( 6837): bufferpool2 0xe9690e08 : 0(0 size) total buffers - 0(0 size) used buffers - 9/14 (recycle/alloc) - 5/10 (fetch/transfer)
D/BufferPoolAccessor2.0( 6837): evictor expired: 1, evicted: 1
D/BufferPoolAccessor2.0( 6837): evictor expired: 1, evicted: 0
D/AAudio ( 6837): AAudioStream_close(s#1) called ---------------
D/AAudioStream( 6837): setState(s#1) from 10 to 11
D/AAudioStream( 6837): setState(s#1) from 11 to 12
D/AAudioStream( 6837): ~AudioStream(s#1) mPlayerBase strongCount = 2
D/AAudio ( 6837): AAudioStream_close(s#1) returned 0 ---------
Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.22.1, on Ubuntu 22.04.4 LTS 6.5.0-41-generic, locale it_IT.UTF-8)
• Flutter version 3.22.1 on channel stable at /home/mcolpo/.android/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision a14f74ff3a (7 settimane fa), 2024-05-22 11:08:21 -0500
• Engine revision 55eae6864b
• Dart version 3.4.1
• DevTools version 2.34.3
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
• Android SDK at /home/mcolpo/.android/
• Platform android-35, build-tools 35.0.0
• ANDROID_SDK_ROOT = /home/mcolpo/.android
• Java binary at: /home/mcolpo/.local/share/JetBrains/Toolbox/apps/android-studio/jbr/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
• All Android licenses accepted.
[✓] Chrome - develop for the web
• Chrome at google-chrome
[✓] Linux toolchain - develop for Linux desktop
• Ubuntu clang version 14.0.0-1ubuntu1.1
• cmake version 3.22.1
• ninja version 1.10.1
• pkg-config version 0.29.2
[✓] Android Studio (version 2024.1)
• Android Studio at /home/mcolpo/.local/share/JetBrains/Toolbox/apps/android-studio
• Flutter plugin version 80.0.2
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
[✓] IntelliJ IDEA Ultimate Edition (version 2024.1)
• IntelliJ at /home/mcolpo/.local/share/JetBrains/Toolbox/apps/intellij-idea-ultimate
• Flutter plugin version 80.0.2
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
[✓] VS Code (version 1.91.0)
• VS Code at /usr/share/code
• Flutter extension can be installed from:
🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[✓] Connected device (3 available)
• AOSP TV on x86 (mobile) • emulator-5554 • android-x86 • Android 14 (API 34) (emulator)
• Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.4 LTS 6.5.0-41-generic
• Chrome (web) • chrome • web-javascript • Google Chrome 126.0.6478.126
[✓] Network resources
• All expected network resources are available.
• No issues found!
Hi @colpomatteo, can you share a complete sample code for this? (There are also redundant imports and undefined variables that you can remove them as well)
loadRequest('some_video_ts_iframe_player')
Yep, sorry about that (i was try different things without cleaning after). Here's a better example:
import "package:flutter/material.dart";
import "package:nextflix/repositories/preferences.dart";
import "package:webview_flutter/webview_flutter.dart";
import "package:webview_flutter_android/webview_flutter_android.dart";
import "package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart";
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late final WebViewController _controller;
late final Preferences preferences;
@override
void initState() {
super.initState();
final PlatformWebViewControllerCreationParams params =
WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const {});
_controller = WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setUserAgent(
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0")
..setNavigationDelegate(NavigationDelegate(
onProgress: (int progress) {
//loading bar
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onHttpError: (HttpResponseError error) {},
onWebResourceError: (WebResourceError error) {},
onUrlChange: (UrlChange change) {
print("Change: ${change.url}");
},
onNavigationRequest: (NavigationRequest request) {
List<String> authorizedAuthorities = [
"vixcloud.co",
"scws-content.net",
"streamingcommunity.boston"
];
if (authorizedAuthorities.any((String authority) =>
Uri.parse(request.url).host.contains(authority))) {
return NavigationDecision.navigate;
}
return NavigationDecision.prevent;
}))
..loadRequest(Uri.parse("https://streamingcommunity.boston/watch/4703"));
if (_controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(false);
(_controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
(_controller.platform as AndroidWebViewController)
.setCustomWidgetCallbacks(
onShowCustomWidget:
(Widget widget, OnHideCustomWidgetCallback callback) {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) => widget,
fullscreenDialog: true,
));
},
onHideCustomWidget: () {
Navigator.of(context).pop();
},
);
}
}
@override
Widget build(BuildContext context) =>
Scaffold(body: WebViewWidget(controller: _controller));
}
Thanks, but when I access the url above from my browser (chrome) on desktop machine (MacBook), it's not playable as well. I click on the play button but always prompts a new tab with ads, not sure if it's a correct video. Can you confirm it with different tools (video player app, online player..)?
I also tried playing some ts video files here https://filesamples.com/formats/ts and see that they are playable as normal video on desktop app (VLC for example).
Even though I usually use adblock, I confirm i can play the video when it's disabled (I do see the ads but i just close it):
I'm using Firefox, ads are the reason of this:
List<String> authorizedAuthorities = [
"vixcloud.co",
"scws-content.net",
"streamingcommunity.boston"
];
if (authorizedAuthorities.any((String authority) =>
Uri.parse(request.url).host.contains(authority))) {
return NavigationDecision.navigate;
}
You are right, the video is playable after closing all ads on desktop browser.
I do some tests: The video can play on Flutter iOS (app) and Android native app with WebView but can't play on Flutter Android with WebViewWidget.
The current package version: webview_flutter_android: ^3.16.4
Demo (Android Flutter app and Android native app)
| Android native | Android Flutter |
|---|---|
Complete sample code (removed unnecessary imports)
import "package:flutter/material.dart";
import "package:webview_flutter/webview_flutter.dart";
import "package:webview_flutter_android/webview_flutter_android.dart";
import "package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart";
void main(List<String> args) {
runApp(MaterialApp(home: Home()));
}
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
late final WebViewController _controller;
@override
void initState() {
super.initState();
final PlatformWebViewControllerCreationParams params =
WebKitWebViewControllerCreationParams(
allowsInlineMediaPlayback: true,
mediaTypesRequiringUserAction: const {});
_controller = WebViewController.fromPlatformCreationParams(params)
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setUserAgent(
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0")
..setNavigationDelegate(NavigationDelegate(
onProgress: (int progress) {
//loading bar
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onHttpError: (HttpResponseError error) {},
onWebResourceError: (WebResourceError error) {},
onUrlChange: (UrlChange change) {
print("Change: ${change.url}");
},
onNavigationRequest: (NavigationRequest request) {
List<String> authorizedAuthorities = [
"vixcloud.co",
"scws-content.net",
"streamingcommunity.boston"
];
if (authorizedAuthorities.any((String authority) =>
Uri.parse(request.url).host.contains(authority))) {
return NavigationDecision.navigate;
}
return NavigationDecision.prevent;
}))
..loadRequest(Uri.parse("https://streamingcommunity.boston/watch/4703"));
if (_controller.platform is AndroidWebViewController) {
AndroidWebViewController.enableDebugging(false);
(_controller.platform as AndroidWebViewController)
.setMediaPlaybackRequiresUserGesture(false);
(_controller.platform as AndroidWebViewController)
.setCustomWidgetCallbacks(
onShowCustomWidget:
(Widget widget, OnHideCustomWidgetCallback callback) {
Navigator.of(context).push(MaterialPageRoute<void>(
builder: (BuildContext context) => widget,
fullscreenDialog: true,
));
},
onHideCustomWidget: () {
Navigator.of(context).pop();
},
);
}
}
@override
Widget build(BuildContext context) =>
Scaffold(body: WebViewWidget(controller: _controller));
}
flutter doctor -v (stable and master)
[✓] Flutter (Channel stable, 3.22.2, on macOS 14.1 23B74 darwin-x64, locale en-VN)
• Flutter version 3.22.2 on channel stable at /Users/huynq/Documents/GitHub/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 761747bfc5 (3 weeks ago), 2024-06-05 22:15:13 +0200
• Engine revision edd8546116
• Dart version 3.4.3
• DevTools version 2.34.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.10+0-17.0.10b1087.21-11572160)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
• Xcode at /Applications/Xcode15.4.app/Contents/Developer
• Build 15F31d
• CocoaPods version 1.15.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2023.3)
• 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.10+0-17.0.10b1087.21-11572160)
[✓] VS Code (version 1.90.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.90.0
[✓] Connected device (3 available)
• 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 126.0.6478.127
[✓] Network resources
• All expected network resources are available.
• No issues found!
[!] Flutter (Channel master, 3.24.0-1.0.pre.93, on macOS 14.1 23B74 darwin-x64, locale en-VN)
• Flutter version 3.24.0-1.0.pre.93 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 dddea4d155 (3 hours ago), 2024-07-11 17:16:10 -0700
• Engine revision 36dccf7bb2
• Dart version 3.6.0 (build 3.6.0-26.0.dev)
• DevTools version 2.37.1
• 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.10+0-17.0.10b1087.21-11572160)
• All Android licenses accepted.
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
• Xcode at /Applications/Xcode15.4.app/Contents/Developer
• Build 15F31d
• CocoaPods version 1.15.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[✓] Android Studio (version 2023.3)
• 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.10+0-17.0.10b1087.21-11572160)
[✓] VS Code (version 1.91.0)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.92.0
[✓] Connected device (4 available)
• Pixel 7 (mobile) • 2B171FDH20084L • android-arm64 • Android 14 (API 34)
• 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 126.0.6478.127
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.
solved?
solved?
No
solved?
No
Hi. I also stuck in similar issue. did you solve this issue?
solved?
No
Hi. I also stuck in similar issue. did you solve this issue?
Nope, i tried other settings but nothing seems to work, anyway it seems it’s a codec problem, I don’t get why on normal browser works perfectly.
solved?
No
Hi. I also stuck in similar issue. did you solve this issue?
I solved this by using Kotlin and native code (so i didn't) the problem was (i think) that the page i was visiting opened an "intent://" like link that the webview didn't know how to handle event if I filtered requests with onNavigationRequest. The native webview encountered this problem too but in that case I'm able to block the request before it get processed.