【发布时间】: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>
【问题讨论】:
标签: webview flutter youtube youtube-iframe-api