5

I am trying to build an application in which the backend generates a short video and returns it as a file in the response. In the Flutter frontend i am parsing the response object to get the bytes representing the video. Using these bytes, I would like to create a Video Player.

Here's my question: How can I initialize the VideoPlayerController the byte array I received from the response?

According to the docs, VideoPlayerController.file() is not working as that would require dart.io which is not available on web. This only leaves me the network or asset options.

masus04
  • 943
  • 8
  • 19

1 Answers1

0

Here is a small code implementation of same.

class VideoPlayerWidget extends StatefulWidget {
  final Uint8List videoBytes;

  const VideoPlayerWidget({super.key, required this.videoBytes});

  @override
  State<VideoPlayerWidget> createState() => _VideoPlayerWidgetState();
}

class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  late VideoPlayerController _controller;
  late html.VideoElement _videoElement;

  @override
  void initState() {
    super.initState();
    _videoElement = html.VideoElement();

    // Register an event listener to track when the video has loaded
    _videoElement.addEventListener('loaded metadata', (_) {
      _initializeVideoPlayer();
    });

    // Convert the byte array to a blob and set it as the video source
    final blob = html.Blob([widget.videoBytes]);
    final url = html.Url.createObjectUrl(blob);
    _videoElement.src = url;
  }

  @override
  void dispose() {
    _controller.dispose();
    _videoElement.pause();
    _videoElement.removeAttribute('src');
    html.Url.revokeObjectUrl(_videoElement.src);
    super.dispose();
  }

  Future<void> _initializeVideoPlayer() async {
    _controller = VideoPlayerController.network(_videoElement.currentSrc!);
    await _controller.initialize();
    await _controller.setLooping(true);
    _controller.play();
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    if (_controller.value.isInitialized) {
      return AspectRatio(
        aspectRatio: _controller.value.aspectRatio,
        child: VideoPlayer(_controller),
      );
    } else {
      return Container();
    }
  }
}

You can use this widget as

final Uint8List videobytes; // initalize your video bytes here
VideoPlayerWidget(videoBytes: videoBytes)