如何在Flutter web上播放File视频?

问题描述 投票:0回答:1

我有一个 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 中都没有找到任何内容,但我并没有失去希望。

flutter web local-storage flutter-video-player
1个回答
0
投票

您可以使用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);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.