flutter icon indicating copy to clipboard operation
flutter copied to clipboard

[webview_flutter][Android] Non youtube iframe video not showing up

Open yabzec opened this issue 1 year ago • 7 comments

Steps to reproduce

  1. Open a page with an iframe with a player playing .ts videos (some streaming services does that)
  2. 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

immagine

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!

yabzec avatar Jul 10 '24 16:07 yabzec

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

huycozy avatar Jul 11 '24 08:07 huycozy

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));
}

yabzec avatar Jul 12 '24 06:07 yabzec

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

huycozy avatar Jul 12 '24 09:07 huycozy

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): vlcsnap-2024-07-12-11h51m50s850

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;
            }

yabzec avatar Jul 12 '24 09:07 yabzec

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.

huycozy avatar Jul 12 '24 10:07 huycozy

solved?

willy995 avatar Aug 17 '24 12:08 willy995

solved?

No

yabzec avatar Sep 06 '24 11:09 yabzec

solved?

No

Hi. I also stuck in similar issue. did you solve this issue?

AKAPUCH avatar Nov 28 '24 05:11 AKAPUCH

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.

yabzec avatar Nov 30 '24 16:11 yabzec

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.

yabzec avatar May 12 '25 15:05 yabzec