webview_flutter插件无法播放某些YouTube嵌入的视频,这些视频如果从网络应用程序中播放则可以正常工作。视频显示“视频不可用”。在Flutter应用中内嵌播放YouTube视频至少一年来一直是个问题。
https://github.com/flutter/flutter/issues/13756
我尝试了各种Flutter插件来内联播放YouTube视频,但它们要么仅支持Android,要么不支持YouTube。
我曾尝试直接在WebView插件中使用HTML字符串(YouTube iframe),但该视频不可用。从网络服务器加载HTML允许播放一些视频,否则这些视频将无法直接在flutter应用程序中播放,例如某些音乐视频显示“视频不可用。该视频包含Vevo的内容,已阻止其在网站或应用程序上显示”。
但是,如果我从网络应用程序中使用YouTube iframe API(请参见代码)启动同一视频,则该视频可以正常运行,即未禁用嵌入功能,但这些视频无法在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"));
使用YouTube iframe API的index.html文件投放到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>
答案 0 :(得分:0)
更新:此插件似乎更好(在jira问题url上提到),但不是Flutter团队的官方
答案 1 :(得分:0)
您可以使用我的插件flutter_inappwebview在网络视图中播放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) {
},
),
),
),
]))
);
}
}