import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Appname',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Sunrion'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<String> initialize() async {
await _getServer();
if (kDebugMode) {
debugPrint('appDocumentsDirectory : ${appDocumentsDirectory.path}');
}
final preferences = await SharedPreferences.getInstance();
final isExtracted = preferences.getBool('isExtracted');
if (isExtracted != true) {
const platform = MethodChannel('flutter.native/zipchannel');
try {
var pathToAssetsZip = 'assets/resources/app.zip';
await platform.invokeMethod('extractAssetsZip', {
'name': pathToAssetsZip,
'path': '${appDocumentsDirectory.path}/'
});
preferences.setBool('isExtracted', true);
} catch (_) {}
}
return appDocumentsDirectory.path;
}
HttpServer? server;
startServer() async {
await for (var request in server!) {
final path = request.uri.path;
var filePath = '${appDocumentsDirectory.path}/app$path';
final file = File(filePath);
var existsString = '';
if (path.endsWith('.mp4')) {
final data = await file.readAsBytes();
request.response
..headers.contentType = ContentType('video', 'mp4')
..add(data)
..close();
} else if (path.endsWith('.png')) {
final exists = file.existsSync();
existsString = ' :: $exists';
request.response
..add(await file.readAsBytes())
..close();
} else if (path.endsWith('.js') || path.endsWith('.css')) {
final fileContent = await file.readAsString();
final exists = file.existsSync();
existsString = ' :: $exists';
final mime = path.endsWith('.js') ? 'javascript' : 'css';
request.response
..headers.contentType = ContentType('text', mime, charset: 'utf-8')
..write(fileContent)
..close();
} else if (path == '/') {
filePath = '${appDocumentsDirectory.path}/app/index.html';
final file = File(filePath);
final fileContent = await file.readAsString();
request.response
..headers.contentType = ContentType("text", "html", charset: "utf-8")
..write(fileContent)
..close();
} else {
request.response
..headers.contentType = ContentType("text", "plain", charset: "utf-8")
..write('Unknown path')
..close();
}
debugPrint('requestpath : $path$existsString');
}
}
late Directory appDocumentsDirectory;
Future<HttpServer> _getServer() async {
if (server == null) {
appDocumentsDirectory = await getApplicationDocumentsDirectory();
server = await HttpServer.bind(InternetAddress.loopbackIPv4, 8080);
startServer();
}
if (kDebugMode) {
print(
"Server running on IP : ${server!.address} On Port : ${server!.port}");
}
return server!;
}
late WebViewController webViewController;
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: initialize(),
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Container();
}
final address = server!.address.address;
var htmlPath = 'http://$address:${server!.port}';
return Column(
children: [
Expanded(
child: WebView(
backgroundColor: Colors.white,
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) async {
webViewController = controller;
await controller.loadUrl(htmlPath);
},
initialMediaPlaybackPolicy:
AutoMediaPlaybackPolicy.always_allow,
),
),
Padding(
padding: const EdgeInsets.all(8),
child: TextButton(
onPressed: () {
webViewController.loadUrl(htmlPath);
},
child: const Text('Hit me'),
),
)
],
);
}),
);
}
}
我试图加载SPA在WebView从reactjs这是放置在应用程序DocumentsDirectory。
Webview正在加载HTML页面,但未加载其中的视频文件。有一个字节范围的概念,我试图在HTTPserver中实现,但未能实现。
我可能在上面的MP4 IF条件中犯了一个错误。如果有人能帮忙的话我会很感激的。
1条答案
按热度按时间jjjwad0x1#
我使用了shelf库(https://pub.dev/packages/shelf),它有助于管理对分块数据的响应。