Flutter WebView 插件无法播放部分 YouTube 视频

问题描述 投票:0回答:2

webview_flutter 插件无法播放某些在 Web 应用程序中播放时可以使用的 YouTube 嵌入视频。视频显示“视频不可用”。在 Flutter 应用程序中内嵌播放 YouTube 视频已经成为一个问题至少一年了。

https://github.com/flutter/flutter/issues/13756

我尝试过各种 Flutter 插件来内联播放 YouTube 视频,但它们要么只支持 Android,要么不支持 YouTube。

我尝试直接在 WebView 插件中使用 HTML 字符串(YouTube iframe),但视频不可用。从网络服务器加载 HTML 允许播放一些视频,否则这些视频不能直接在 flutter 应用程序中播放,例如某些音乐视频显示“视频不可用。该视频包含来自 Vevo 的内容,Vevo 已阻止其在网站或应用程序上显示”。

但是,如果我使用 YouTube iframe API(请参阅代码)从 Web 应用程序启动相同的视频,它可以正常工作,不会出现任何错误,即嵌入未禁用,但这些视频不会在 Flutter 应用程序中播放。我还读过在 Android 中播放 YouTube 视频的类似问题,其中建议使用 WebChromeClient,但在 Flutter 中不可用。

Flutter 应用程序在 WebView 插件中显示 YouTube 视频。

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

// Use IP instead of localhost to access local webserver
const _youTubeUrl = 'http://localhost:8080';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'YouTube Video',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'YouTube Video'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final String title;

  MyHomePage({Key key, this.title}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  WebViewController _controller;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: WebView(
              initialUrl: '$_youTubeUrl/videos/IyFZznAk69U',
              javascriptMode: JavascriptMode.unrestricted,
              onWebViewCreated: (WebViewController controller) =>
                  _controller = controller,
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.play_arrow),
        onPressed: () async {
          await _controller.evaluateJavascript('player.loadVideoById("d_m5csmrf7I")');
        },
      ),
    );
  }
}

通过快速路由返回index.html的Node.js服务器端代码

const path = require("path");
const express = require("express");

const server = express();

// Define route
api.get("/", (req, res) =>
  res.sendFile(path.join(__dirname + "/index.html"))
);

const port = process.env.PORT || 8080;

server.listen(port, () => console.log(`Server listening on ${port}`));

process.on("exit", () => console.log("Server exited"));

index.html 文件使用 YouTube iframe API 提供给 Flutter 应用程序

<!DOCTYPE html>
<html>

<head>
    <style>
        #player {
            position: relative;
            padding-top: 56.25%;
            min-width: 240px;
            height: 0;
        }

        iframe {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }
    </style>
    <script>
        var player;

        function onYouTubeIframeAPIReady() {
            player = new YT.Player("yt", {
                videoId: "IyFZznAk69U",
                playerVars: {
                    autoplay: 1
                }
            });
        }
    </script>
    <script src="https://www.youtube.com/iframe_api" async></script>
</head>

<body>
    <div id="player">
        <div id="yt"></div>
    </div>
</body>

</html>
webview flutter youtube youtube-iframe-api
2个回答
0
投票

您可以使用我的插件 flutter_inappwebview 在 Web 视图中播放 YouTube 视频。

带有您的 YouTube 视频 ID 的完整示例:

import 'dart:async';

import 'package:flutter/material.dart';

import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  runApp(new MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: InAppWebViewPage()
    );
  }
}

class InAppWebViewPage extends StatefulWidget {
  @override
  _InAppWebViewPageState createState() => new _InAppWebViewPageState();
}

class _InAppWebViewPageState extends State<InAppWebViewPage> {
  InAppWebViewController webView;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text("InAppWebView")
        ),
        body: Container(
            child: Column(children: <Widget>[
              Expanded(
                child: Container(
                  child: InAppWebView(
                    initialUrl: "https://www.youtube.com/embed/IyFZznAk69U",
                    initialHeaders: {},
                    initialOptions: InAppWebViewWidgetOptions(
                      inAppWebViewOptions: InAppWebViewOptions(
                        debuggingEnabled: true,
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      webView = controller;
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {

                    },
                    onLoadStop: (InAppWebViewController controller, String url) {

                    },
                  ),
                ),
              ),
            ]))
    );
  }
}

-4
投票

更新:这个插件看起来更好(在 jira 问题 url 中提到),但不是 Flutter 团队的官方

https://github.com/hoanglm4/flutter_youtube_view

© www.soinside.com 2019 - 2024. All rights reserved.