import 'dart:io'; import 'package:flutter/material.dart'; import 'package:chewie/chewie.dart'; import 'package:matrix/matrix.dart'; import 'package:path_provider/path_provider.dart'; import 'package:video_player/video_player.dart'; import 'package:vrouter/vrouter.dart'; import '../../utils/matrix_sdk_extensions.dart/event_extension.dart'; import '../../utils/platform_infos.dart'; import '../../widgets/matrix.dart'; import 'video_viewer_view.dart'; class VideoViewer extends StatefulWidget { final Event event; const VideoViewer(this.event, {Key key}) : super(key: key); @override VideoViewerController createState() => VideoViewerController(); } class VideoViewerController extends State { VideoPlayerController videoPlayerController; ChewieController chewieController; dynamic error; @override void initState() { super.initState(); (() async { try { if (widget.event.content['file'] is Map) { if (PlatformInfos.isWeb) { throw 'Encrypted videos unavailable in web'; } final tempDirectory = (await getTemporaryDirectory()).path; final mxcUri = widget.event.content .tryGet>('file') ?.tryGet('url'); if (mxcUri == null) { throw 'No mxc uri found'; } // somehow the video viewer doesn't like the uri-encoded slashes, so we'll just gonna replace them with hyphons final file = File( '$tempDirectory/videos/${mxcUri.replaceAll(':', '').replaceAll('/', '-')}'); if (await file.exists() == false) { final matrixFile = await widget.event.downloadAndDecryptAttachmentCached(); await file.create(recursive: true); await file.writeAsBytes(matrixFile.bytes); } videoPlayerController = VideoPlayerController.file(file); } else if (widget.event.content['url'] is String) { videoPlayerController = VideoPlayerController.network( widget.event.getAttachmentUrl()?.toString()); } else { throw 'invalid event'; } await videoPlayerController.initialize(); chewieController = ChewieController( videoPlayerController: videoPlayerController, autoPlay: true, looping: false, ); setState(() => null); } catch (e) { setState(() => error = e); } })(); } @override void dispose() { chewieController?.dispose(); videoPlayerController?.dispose(); super.dispose(); } /// Forward this video to another room. void forwardAction() { Matrix.of(context).shareContent = widget.event.content; VRouter.of(context).to('/rooms'); } /// Save this file with a system call. void saveFileAction() => widget.event.saveFile(context); @override Widget build(BuildContext context) => VideoViewerView(this); }