【问题标题】:Flutter - How to play a Google Drive video preview using webview_flutter packageFlutter - 如何使用 webview_flutter 包播放 Google Drive 视频预览
【发布时间】:2020-08-16 05:34:42
【问题描述】:

我有一个应用程序需要从我的帐户播放 Google Drive 视频,我正在使用这个 webview_flutter 插件也尝试过这个 flutter_webview_plugin,缩略图出现但是当我点击播放时,我收到以下错误:

String url = 'https://drive.google.com/file/d/1O8WF2MsdyoKpQZE2973IFPRpqwKUjm_q/preview';

           WebView(
                onWebViewCreated: (WebViewController controller){

                  webViewController = controller;

                },
                initialUrl: url,
                javascriptMode: JavascriptMode.unrestricted,
                initialMediaPlaybackPolicy: AutoMediaPlaybackPolicy.always_allow,
              ),

错误:

 "The deviceorientation events are blocked by feature policy. See https://github.com/WICG/feature-policy/blo
b/master/features.md#sensor-features", source: https://youtube.googleapis.com/s/player/64dddad9/player_ias.vflset/pt_BR/base.js (263)

我第二次点击播放:

I/chromium(29212): [INFO:CONSOLE(1472)] "Uncaught (in promise) Error: Untrusted URL: https://youtube.googleapis.com/videoplayback?expire=158836583
1&ei=x1GsXtyWNuzPj-8Px_eH2Aw&ip=2804:431:c7da:c52b:854e:e83e:e7c5:eb3e&cp=QVNNWkRfVFhRQlhOOk5mQ0FhT0J5Y0k2T3ZDdjJLa0UzQVRiaHNoQlVHeXpjV3BtYW9YT2Rk
YUM&id=eb79141269cc6ad3&itag=18&source=webdrive&requiressl=yes&mh=F-&mm=32&mn=sn-bg0eznll&ms=su&mv=m&mvi=4&pl=47&ttl=transient&susc=dr&driveid=1O8
WF2MsdyoKpQZE2973IFPRpqwKUjm_q&app=explorer&mime=video/mp4&dur=2.043&lmt=1551969798109476&mt=1588351334&sparams=expire,ei,ip,cp,id,itag,source,req
uiressl,ttl,susc,driveid,app,mime,dur,lmt&sig=AOq0QJ8wRAIgEzxYGpS8RI0CRVPdZrMxdDGfkYfCezdOkiJ7iUcl5XMCIHiDsmbGel8tWT6XIU8dWdfjLJWdOlI_WHNtDNwYszU9
&lsparams=mh,mm,mn,ms,mv,mvi,pl&lsig=AG3C_xAwRAIgTq3W38roufwBwSPXe4fxB25kANk3s42N5x2oBvVWonoCIDaYJVrPpmNzcoU6q4bqogHP6W-Mw4p_5CRrwh59kZM4&cpn=bCev
241Hx8eXmwyo&c=WEB_EMBEDDED_PLAYER&cver=20200429", source: https://youtube.googleapis.com/s/player/64dddad9/player_ias.vflset/pt_BR/base.js (1472)

【问题讨论】:

    标签: flutter webview video-streaming html5-video android-videoview


    【解决方案1】:

    你可以试试我的插件flutter_inappwebview,这是一个 Flutter 插件,可以让你添加内联 WebViews 或打开应用内浏览器窗口,并且有很多事件、方法和选项来控制 WebViews。

    以下是使用您的 Google Drive URL 的代码示例,它运行正常:

    import 'dart:async';
    import 'package:flutter/material.dart';
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    Future main() async {
      WidgetsFlutterBinding.ensureInitialized();
      runApp(MyApp());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      InAppWebViewController webView;
    
      @override
      void initState() {
        super.initState();
      }
    
      @override
      void dispose() {
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('InAppWebView Example'),
            ),
            body: Container(
                child: Column(children: <Widget>[
              Expanded(
                  child: InAppWebView(
                initialUrl: "https://drive.google.com/file/d/1O8WF2MsdyoKpQZE2973IFPRpqwKUjm_q/preview",
                initialHeaders: {},
                initialOptions: InAppWebViewGroupOptions(
                  crossPlatform: InAppWebViewOptions(
                    debuggingEnabled: true,
                  ),
                ),
                onWebViewCreated: (InAppWebViewController controller) {
                  webView = controller;
                },
                onLoadStart: (InAppWebViewController controller, String url) {},
                onLoadStop: (InAppWebViewController controller, String url) {},
              ))
            ])),
          ),
        );
      }
    }
    

    屏幕截图 (.gif):

    【讨论】:

    • 你是救生员。
    【解决方案2】:
    1. 将 Google Plus 登录集成到您的项目中。

    2. 创建了一个 Google Firebase 项目,现在是时候从 Google Developer Console 启用 Google Drive API。

    3. 现在,我们将添加实现 Google Drive 操作的依赖项(Google API、Pick File to Upload & Download file in mobile storage)。请检查以下依赖项。

      依赖关系:
      颤振:
      sdk:颤动
      cupertino_icons: ^0.1.2
      firebase_auth: ^0.15.2
      google_sign_in:^4.1.0
      flutter_secure_storage: ^3.3.1+1
      googleapis:^0.54.0
      googleapis_auth:^0.2.11
      路径提供者:^1.5.1
      文件选择器:^1.3.8

    【讨论】:

    • 身份验证会解决错误吗?因为我只想流式传输文件,所以用户没有上传或下载选项。
    【解决方案3】:

    投票的答案有效,但它已经过时了,所以我想出了这个解决方案,我必须阅读他们的文档并用他们当前的版本修复它。这是文档链接,这里是文档链接InAppWebView Basic Usage Documentaion

    import 'dart:io';
    import 'package:flutter/material.dart';
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    Future main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      if (Platform.isAndroid) {
        await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
      }
    
      runApp(new VideoDetails());
    }
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class VideoDetails extends StatefulWidget {
    
      const VideoDetails(
          {Key? key})
          : super(key: key);
    
      @override
      State<VideoDetails> createState() => _VideoDetailsState();
    }
    class _VideoDetailsState extends State<VideoDetails> {
      late InAppWebViewController webView;
      InAppWebViewController? webViewController;
      final GlobalKey webViewKey = GlobalKey();
    
      InAppWebViewGroupOptions _options = InAppWebViewGroupOptions(
          crossPlatform: InAppWebViewOptions(
            useShouldOverrideUrlLoading: true,
            mediaPlaybackRequiresUserGesture: false,
          ),
          android: AndroidInAppWebViewOptions(
            useHybridComposition: true,
          ),
          ios: IOSInAppWebViewOptions(
            allowsInlineMediaPlayback: true,
          ));
    
      late PullToRefreshController pullToRefreshController;
      String url = "";
      double progress = 0;
      final urlController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
    
        pullToRefreshController = PullToRefreshController(
          options: PullToRefreshOptions(
            color: Colors.blue,
          ),
          onRefresh: () async {
            if (Platform.isAndroid) {
              webViewController?.reload();
            } else if (Platform.isIOS) {
              webViewController?.loadUrl(
                  urlRequest: URLRequest(url: await webViewController?.getUrl()));
            }
          },
        );
      }
    
      @override
      void dispose() {
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(title: Text("Some Random Title")),
            body: SafeArea(
                child: Column(children: <Widget>[
              Expanded(
                child: Stack(
                  children: [
                    InAppWebView(
                      key: webViewKey,
                      initialUrlRequest: URLRequest(
                          url: Uri.parse(
                              "https://drive.google.com/file/d/1-CCTxvNQjayi7gRquNixd7Ss-Qab6G0V/preview")),
                      initialOptions: _options,
                      pullToRefreshController: pullToRefreshController,
                      onWebViewCreated: (controller) {
                        webViewController = controller;
                      },
                      onLoadStart: (controller, url) {
                        setState(() {
                          this.url = url.toString();
                          urlController.text = this.url;
                        });
                      },
                      androidOnPermissionRequest:
                          (controller, origin, resources) async {
                        return PermissionRequestResponse(
                            resources: resources,
                            action: PermissionRequestResponseAction.GRANT);
                      },
                      shouldOverrideUrlLoading:
                          (controller, navigationAction) async {
                        // var uri = navigationAction.request.url!;
    
                        return NavigationActionPolicy.ALLOW;
                      },
                      onLoadStop: (controller, url) async {
                        pullToRefreshController.endRefreshing();
                        setState(() {
                          this.url = url.toString();
                          urlController.text = this.url;
                        });
                      },
                      onLoadError: (controller, url, code, message) {
                        pullToRefreshController.endRefreshing();
                      },
                      onProgressChanged: (controller, progress) {
                        if (progress == 100) {
                          pullToRefreshController.endRefreshing();
                        }
                        setState(() {
                          this.progress = progress / 100;
                          urlController.text = this.url;
                        });
                      },
                      onUpdateVisitedHistory: (controller, url, androidIsReload) {
                        setState(() {
                          this.url = url.toString();
                          urlController.text = this.url;
                        });
                      },
                      onConsoleMessage: (controller, consoleMessage) {
                        print(consoleMessage);
                      },
                    ),
                    progress < 1.0
                        ? LinearProgressIndicator(value: progress)
                        : Container(),
                  ],
                ),
              ),
              ButtonBar(
                alignment: MainAxisAlignment.center,
                children: <Widget>[
                  ElevatedButton(
                    child: Icon(Icons.arrow_back),
                    onPressed: () {
                      webViewController?.goBack();
                    },
                  ),
                  ElevatedButton(
                    child: Icon(Icons.arrow_forward),
                    onPressed: () {
                      webViewController?.goForward();
                    },
                  ),
                  ElevatedButton(
                    child: Icon(Icons.refresh),
                    onPressed: () {
                      webViewController?.reload();
                    },
                  ),
                ],
              ),
            ])));
      }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多