Flutter - 如何使用 webview_flutter 包播放 Google Drive 视频预览

Posted

技术标签:

【中文标题】Flutter - 如何使用 webview_flutter 包播放 Google Drive 视频预览【英文标题】:Flutter - How to play a Google Drive video preview using webview_flutter package 【发布时间】: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)

【问题讨论】:

【参考方案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】:

    将 Google Plus 登录集成到您的项目中。

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

    现在,我们将添加实现 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();
                ,
              ),
            ],
          ),
        ])));
  


【讨论】:

以上是关于Flutter - 如何使用 webview_flutter 包播放 Google Drive 视频预览的主要内容,如果未能解决你的问题,请参考以下文章

如何在flutter中使用flutter_webview_plugin和AndroidX

如何使用 flutter_webview 插件在 Flutter 中启用位置?

如何在 Flutter 上使用 API

如何通过 FlutterView 或 Flutter.createFragment 使用平台通道

Flutter 和 Amplify/Cognito:如何使用 Flutter 更新 Amplify/cognito 中的电话号码

如何在 Flutter 的原生 C++ 中使用 OpenCV 4(2021 年)(支持 Flutter 2.0)? [关闭]