Flutter WebView 插件无法播放某些 YouTube 视频
Posted
技术标签:
【中文标题】Flutter WebView 插件无法播放某些 YouTube 视频【英文标题】:Flutter WebView plugin unable to play some YouTube videos 【发布时间】:2019-10-14 08:33:33 【问题描述】:webview_flutter 插件无法播放某些 YouTube 嵌入视频,这些视频如果在网络应用中播放则可以正常工作。视频显示“视频不可用”。在 Flutter 应用中内联播放 YouTube 视频已成为问题至少一年了。
https://github.com/flutter/flutter/issues/13756
我尝试了各种 Flutter 插件来内联播放 YouTube 视频,但它们要么只支持 android,要么不支持 YouTube。
我尝试在 WebView 插件中直接使用 html 字符串(YouTube iframe),但视频不可用。从网络服务器加载 HTML 允许播放一些视频,否则这些视频不会直接在颤振应用程序中播放,例如一些音乐视频显示“视频不可用。该视频包含来自 Vevo 的内容,该视频已阻止其在网站或应用程序上显示”。
但是,如果我使用 YouTube iframe API(请参阅代码)从 Web 应用程序启动相同的视频,它可以正常工作,即嵌入未被禁用,但这些视频无法在 Flutter 应用程序中播放。我还阅读了在 Android 中播放 YouTube 视频的类似问题,建议使用 WebChromeClient,这在 Flutter 中不可用。
在 WebView 插件中显示 YouTube 视频的 Flutter 应用。
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"));
使用 YouTube iframe API 提供给 Flutter 应用的 index.html 文件
<!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>
【问题讨论】:
【参考方案1】:您可以使用我的插件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)
,
),
),
),
]))
);
【讨论】:
这在 ios 上不起作用。该视频在加载 youtube 和 vimeo 时都卡住了。链接是否需要清理或像角度一样? @IanSamz 您是否将此代码添加到您的 Info.plist 文件中?<key>io.flutter.embedded_views_preview</key> <string>YES</string>
【参考方案2】:
更新:这个插件看起来更好(在 jira 问题 url 上提到)但不是 Flutter 团队的官方插件
https://github.com/hoanglm4/flutter_youtube_view
【讨论】:
一团糟以上是关于Flutter WebView 插件无法播放某些 YouTube 视频的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 如何使用 webview_flutter 包播放 Google Drive 视频预览