我有一个 Flutter 应用程序,它使用 websockets 与后端 python 服务器通信。本质上,应用程序将视频发送到服务器,后端执行一些 ML 操作并以 Uint8List 形式发回 mp4 文件。我将该列表转换为列表,然后创建一个临时文件对象,在其中写入转换后的数据。最后,我使用该文件通过 .file 方法通过“video_player”包播放视频。
Future<void> convertListToVideoFileMobile() async {
final tempDir = await getTemporaryDirectory();
final tempPath = tempDir.path;
// Concatenate the Uint8List chunks into a single Uint8List
final videoData = Uint8List.fromList(
videoList.fold<List<int>>([], (prev, curr) => prev..addAll(curr)),
);
// Create a new File in the temporary directory and write the video data
final file = File('$tempPath/myVideo.mp4');
await file.writeAsBytes(videoData);
videoFileMobile = file;
}
问题是,根据我的研究,使用 Flutter Web 访问临时文件被拒绝。
所以我想知道是否有办法找到替代流程来实现这一点。
说实话,我并没有尝试很多,因为我在网络和 stackoverflow 中都没有找到任何内容,但我并没有失去希望。
您可以使用HtmlElementView。 Html5 音频和视频可以接受数据 URI 作为源。 我们想要的结果(来源):
<video controls>
<source type="video/webm" src="data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8......jVOrhB9DtnVTrIMQTPc=">
<source type="video/mp4" src="data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAG1wNDJpc29....../l/L+X8v5AAAAMgfDg==">
</video>
实现示例:
import 'dart:convert';
import 'dart:ui_web' as ui_web;
import 'package:flutter/material.dart';
import 'package:universal_html/html.dart' as html;
class VideoComponent extends StatelessWidget {
const VideoComponent({
required this.id,
required this.bytes,
required this.minetype,
super.key,
});
// unique id
final String id;
// file type like mp4, webm
final String minetype;
// video data
final Uint8List bytes;
@override
Widget build(BuildContext context) {
final base64Data = base64.encode(bytes);
final sourceElement = html.SourceElement();
sourceElement.type = 'video/$minetype';
sourceElement.src = 'data:video/$minetype;base64,$base64Data';
final videoElement = html.VideoElement();
videoElement.controls = true;
videoElement.children = [sourceElement];
videoElement.style.height = '100%';
videoElement.style.width = '100%';
ui_web.platformViewRegistry
.registerViewFactory(id, (int viewId) => videoElement);
return HtmlElementView(viewType: id);
}
}