flutter_inappwebview icon indicating copy to clipboard operation
flutter_inappwebview copied to clipboard

iOS opens a live broadcast screen

Open Nashkim254 opened this issue 2 years ago • 2 comments

i built an app for both android and iOS and it works fine on android , loads the front camera well but in iOS it first loads a live broadcast screen and i have to cancel that view which hides the camera view behind it. How can i remove the live broadcast view in iOS?

Nashkim254 avatar Jul 12 '22 12:07 Nashkim254

👋 @programming6131

NOTE: This comment is auto-generated.

Are you sure you have already searched for the same problem?

Some people open new issues but they didn't search for something similar or for the same issue. Please, search for it using the GitHub issue search box or on the official inappwebview.dev website, or, also, using Google, StackOverflow, etc. before posting a new one. You may already find an answer to your problem!

If this is really a new issue, then thank you for raising it. I will investigate it and get back to you as soon as possible. Please, make sure you have given me as much context as possible! Also, if you didn't already, post a code example that can replicate this issue.

In the meantime, you can already search for some possible solutions online! Because this plugin uses native WebView, you can search online for the same issue adding android WebView [MY ERROR HERE] or ios WKWebView [MY ERROR HERE] keywords.

Following these steps can save you, me, and other people a lot of time, thanks!

github-actions[bot] avatar Jul 12 '22 12:07 github-actions[bot]

having the same problem

aldrin233 avatar Sep 13 '22 06:09 aldrin233

Facing the same issue here.

Whenever the user starts recording from the app, it accidentally redirects them to a live broadcast instead of a video recording.

ezgif com-gif-maker-4

flutter doctor:

[✓] Flutter (Channel stable, 3.3.7, on macOS 13.0 22A380 darwin-x64, locale en-IL)                                                                                         Checking Android licenses is taking an unexpectedly long time...[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.73.1)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

IOS version: 15.2.1

Link to StackOverflow discussion: https://stackoverflow.com/questions/73320367/flutter-inappwebview-ios-goes-to-live-broadcast-instead-of-camera

CartmanGD avatar Nov 30 '22 15:11 CartmanGD

I think it's related to how native iOS WKWebView interprets the video stream element when requested by the web page. I don't have control over showing or not the "Live Broadcast", it's a decision taken by the WKWebView itself and not mine.

Check this answer on Stackoverflow. Does the video HTML element have the playsinline attribute??

pichillilorenzo avatar Dec 04 '22 11:12 pichillilorenzo

Also, if possible, could you post some code that replicates the issue?

pichillilorenzo avatar Dec 04 '22 11:12 pichillilorenzo

Hey @pichillilorenzo thanks for your reply!

I will check the HTML attribute you mentioned. Meanwhile here is my code for reproduction:

import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await [
    Permission.photosAddOnly,
    Permission.camera,
    Permission.microphone,
  ].request();

  /// Getting permission for appTrackingTransparency required a delay between
  if (await AppTrackingTransparency.trackingAuthorizationStatus ==
      TrackingStatus.notDetermined) {
    await Future.delayed(const Duration(seconds: 2));
    await AppTrackingTransparency.requestTrackingAuthorization();
  }

  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool isLoading = true;
  final _key = UniqueKey();

  InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
    crossPlatform: InAppWebViewOptions(
      useShouldOverrideUrlLoading: true,
      mediaPlaybackRequiresUserGesture: false,
    ),
    android: AndroidInAppWebViewOptions(
      useHybridComposition: true,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Builder(builder: (context) {
        return Scaffold(
          body: Stack(
            children: [
              Column(
                children: [
                  SizedBox(height: MediaQuery.of(context).viewPadding.top),
                  Expanded(
                    child: InAppWebView(
                      key: _key,
                      onLoadStop: (controller, url) {
                        setState(() {
                          isLoading = false;
                        });
                      },
                      initialUrlRequest: URLRequest(
                          url: Uri.parse('https://my.url.com')),
                      initialOptions: InAppWebViewGroupOptions(
                        crossPlatform: InAppWebViewOptions(
                          mediaPlaybackRequiresUserGesture: false,
                        ),
                      ),
                      androidOnPermissionRequest:
                          (InAppWebViewController controller, String origin,
                              List<String> resources) async {
                        return PermissionRequestResponse(
                          resources: resources,
                          action: PermissionRequestResponseAction.GRANT,
                        );
                      },
                    ),
                  ),
                ],
              ),
              if (isLoading)
                Container(
                  color: Colors.white,
                  child: const Center(child: CircularProgressIndicator()),
                ),
            ],
          ),
        );
      }),
    );
  }
}

CartmanGD avatar Dec 05 '22 08:12 CartmanGD

@pichillilorenzo Updating that we are using the mentioned attribute:

<video src="" #video playsInline muted></video>

CartmanGD avatar Dec 05 '22 09:12 CartmanGD

I fixed this issue

Nashkim254 avatar Dec 05 '22 10:12 Nashkim254

@programming6131 if it’s working, please share your solution to other people, thanks!

@CartmanGD did you try to set also the IOSInAppWebViewOptions allowsInlineMediaPlayback: true?

pichillilorenzo avatar Dec 05 '22 10:12 pichillilorenzo

Basically if you follow the documentation on setting up InAppWebView in iOS and add these options it works fine

InAppWebViewController? webViewController; InAppWebViewGroupOptions options = InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( useShouldOverrideUrlLoading: true, mediaPlaybackRequiresUserGesture: false, ), android: AndroidInAppWebViewOptions( useHybridComposition: true, ), ios: IOSInAppWebViewOptions( allowsInlineMediaPlayback: true, ));

Nashkim254 avatar Dec 05 '22 11:12 Nashkim254

Thank you both @pichillilorenzo @programming6131,

This part was missing from my code.

ios: IOSInAppWebViewOptions(
allowsInlineMediaPlayback: true,
)

I will check it tomorrow with a physical IOS device to confirm it.

@programming6131 how did you find it? It does not part of the official documentation

image

CartmanGD avatar Dec 05 '22 11:12 CartmanGD

@CartmanGD you should always use the API Reference for more details. Here is the API Reference for that option for plugin version 5: https://pub.dev/documentation/flutter_inappwebview/5.7.2+2/flutter_inappwebview/IOSInAppWebViewOptions/allowingReadAccessTo.html

However, here is the link to the official website using InAppWebViewSettings (for plugin version 6): https://inappwebview.dev/docs/webview/in-app-weview-settings/#allowsinlinemediaplayback

You can consider the InAppWebViewSettings website page as a copy/paste of the same thing from the API Reference!

pichillilorenzo avatar Dec 05 '22 12:12 pichillilorenzo

Basically if you follow the documentation on setting up InAppWebView in iOS and add these options it works fine

InAppWebViewController? webViewController; InAppWebViewGroupOptions options = InAppWebViewGroupOptions( crossPlatform: InAppWebViewOptions( useShouldOverrideUrlLoading: true, mediaPlaybackRequiresUserGesture: false, ), android: AndroidInAppWebViewOptions( useHybridComposition: true, ), ios: IOSInAppWebViewOptions( allowsInlineMediaPlayback: true, ));

I can confirm that it solved my issue. Thank you guys!

@pichillilorenzo @programming6131

CartmanGD avatar Dec 06 '22 08:12 CartmanGD

Adding some useful information from Apple documentation:

allowsInlineMediaPlayback

A Boolean value that indicates whether HTML5 videos play inline or use the native full-screen controller.

Set this property to YES to play videos inline, or NO to use the native full-screen controller. When adding a video element to an HTML document on iPhone, you must also include the playsinline attribute. The default value of this property is NO for iPhone and YES for iPad.

CartmanGD avatar Dec 06 '22 09:12 CartmanGD