2020-09-17 14:30:39 +00:00
|
|
|
import 'dart:io' as io;
|
2020-06-19 23:03:26 +00:00
|
|
|
import 'package:chewie/chewie.dart';
|
2020-08-14 00:01:37 +00:00
|
|
|
import 'package:flutter/cupertino.dart';
|
2020-06-20 23:51:10 +00:00
|
|
|
import 'package:flutter/material.dart';
|
2020-06-19 23:03:26 +00:00
|
|
|
import 'package:flutter/widgets.dart';
|
2020-07-08 15:39:49 +00:00
|
|
|
import 'package:fluttertoast/fluttertoast.dart';
|
2020-07-07 21:54:11 +00:00
|
|
|
import 'package:logging/logging.dart';
|
2020-06-19 23:03:26 +00:00
|
|
|
import 'package:photos/models/file.dart';
|
2020-07-21 10:17:56 +00:00
|
|
|
import 'package:photos/ui/thumbnail_widget.dart';
|
2020-06-20 23:51:10 +00:00
|
|
|
import 'package:photos/ui/video_controls.dart';
|
2020-08-13 20:03:29 +00:00
|
|
|
import 'package:photos/utils/file_util.dart';
|
2020-07-07 21:54:11 +00:00
|
|
|
import 'package:photos/utils/toast_util.dart';
|
2020-06-19 23:03:26 +00:00
|
|
|
import 'package:video_player/video_player.dart';
|
2020-07-29 19:17:03 +00:00
|
|
|
import 'package:visibility_detector/visibility_detector.dart';
|
2020-06-19 23:03:26 +00:00
|
|
|
|
|
|
|
class VideoWidget extends StatefulWidget {
|
|
|
|
final File file;
|
2020-06-21 17:44:21 +00:00
|
|
|
final bool autoPlay;
|
2020-07-13 21:33:43 +00:00
|
|
|
final String tagPrefix;
|
|
|
|
VideoWidget(
|
|
|
|
this.file, {
|
|
|
|
this.autoPlay = false,
|
|
|
|
this.tagPrefix,
|
|
|
|
Key key,
|
|
|
|
}) : super(key: key);
|
2020-06-19 23:03:26 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
_VideoWidgetState createState() => _VideoWidgetState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _VideoWidgetState extends State<VideoWidget> {
|
2020-07-07 21:54:11 +00:00
|
|
|
Logger _logger = Logger("VideoWidget");
|
2020-06-19 23:03:26 +00:00
|
|
|
VideoPlayerController _videoPlayerController;
|
2020-06-23 14:59:51 +00:00
|
|
|
ChewieController _chewieController;
|
2020-08-14 00:01:37 +00:00
|
|
|
double _progress;
|
2020-06-19 23:03:26 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
|
|
|
super.initState();
|
2020-08-09 22:34:59 +00:00
|
|
|
if (widget.file.localID == null) {
|
2020-08-13 20:03:29 +00:00
|
|
|
if (!widget.file.isEncrypted) {
|
2020-09-17 14:30:39 +00:00
|
|
|
_setVideoPlayerController(url: widget.file.getStreamUrl());
|
2020-08-13 20:03:29 +00:00
|
|
|
_videoPlayerController.addListener(() {
|
|
|
|
if (_videoPlayerController.value.hasError) {
|
|
|
|
_logger.warning(_videoPlayerController.value.errorDescription);
|
|
|
|
showToast(
|
|
|
|
"The video has not been processed yet. Downloading the original one...",
|
|
|
|
toastLength: Toast.LENGTH_SHORT);
|
2020-09-17 14:30:39 +00:00
|
|
|
_setVideoPlayerController(url: widget.file.getDownloadUrl());
|
2020-08-13 20:03:29 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
2020-08-14 00:01:37 +00:00
|
|
|
getFileFromServer(
|
|
|
|
widget.file,
|
|
|
|
progressCallback: (count, total) {
|
|
|
|
setState(() {
|
|
|
|
_progress = count / total;
|
|
|
|
if (_progress == 1) {
|
|
|
|
showToast("Decrypting video...",
|
|
|
|
toastLength: Toast.LENGTH_SHORT);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
},
|
|
|
|
).then((file) {
|
2020-09-17 14:30:39 +00:00
|
|
|
_setVideoPlayerController(file: file);
|
2020-08-13 20:03:29 +00:00
|
|
|
});
|
|
|
|
}
|
2020-06-23 14:59:51 +00:00
|
|
|
} else {
|
|
|
|
widget.file.getAsset().then((asset) {
|
|
|
|
asset.getMediaUrl().then((url) {
|
2020-09-17 14:30:39 +00:00
|
|
|
_setVideoPlayerController(url: url);
|
2020-06-23 14:59:51 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2020-06-19 23:03:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
2020-09-25 20:18:36 +00:00
|
|
|
if (_videoPlayerController != null) {
|
|
|
|
_videoPlayerController.dispose();
|
|
|
|
}
|
2020-06-24 00:49:12 +00:00
|
|
|
if (_chewieController != null) {
|
|
|
|
_chewieController.dispose();
|
|
|
|
}
|
2020-06-19 23:03:26 +00:00
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
2020-09-17 14:30:39 +00:00
|
|
|
VideoPlayerController _setVideoPlayerController({String url, io.File file}) {
|
|
|
|
var videoPlayerController;
|
|
|
|
if (url != null) {
|
|
|
|
videoPlayerController = VideoPlayerController.network(url);
|
|
|
|
} else {
|
|
|
|
videoPlayerController = VideoPlayerController.file(file);
|
|
|
|
}
|
|
|
|
return _videoPlayerController = videoPlayerController
|
2020-06-23 14:59:51 +00:00
|
|
|
..initialize().whenComplete(() {
|
2020-08-13 22:00:19 +00:00
|
|
|
if (mounted) {
|
|
|
|
setState(() {});
|
|
|
|
}
|
2020-06-23 14:59:51 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-19 23:03:26 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2020-06-23 15:05:48 +00:00
|
|
|
final content = _videoPlayerController != null &&
|
2020-06-23 14:59:51 +00:00
|
|
|
_videoPlayerController.value.initialized
|
|
|
|
? _getVideoPlayer()
|
|
|
|
: _getLoadingWidget();
|
2020-07-29 19:17:03 +00:00
|
|
|
return VisibilityDetector(
|
|
|
|
key: Key(widget.file.tag()),
|
|
|
|
onVisibilityChanged: (info) {
|
|
|
|
if (info.visibleFraction < 1) {
|
2020-09-17 14:30:39 +00:00
|
|
|
if (mounted && _chewieController != null) {
|
2020-08-14 00:04:12 +00:00
|
|
|
_chewieController.pause();
|
|
|
|
}
|
2020-07-29 19:17:03 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
child: Hero(
|
|
|
|
tag: widget.tagPrefix + widget.file.tag(),
|
|
|
|
child: content,
|
|
|
|
),
|
2020-06-23 15:05:48 +00:00
|
|
|
);
|
2020-06-23 14:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Widget _getLoadingWidget() {
|
|
|
|
return Stack(children: [
|
|
|
|
_getThumbnail(),
|
2020-06-24 00:49:12 +00:00
|
|
|
Container(
|
|
|
|
color: Colors.black12,
|
|
|
|
constraints: BoxConstraints.expand(),
|
|
|
|
),
|
2020-08-14 00:01:37 +00:00
|
|
|
Center(
|
|
|
|
child: SizedBox.fromSize(
|
|
|
|
size: Size.square(30),
|
|
|
|
child: _progress == null || _progress == 1
|
|
|
|
? CupertinoActivityIndicator()
|
2020-09-27 18:54:53 +00:00
|
|
|
: CircularProgressIndicator(value: _progress),
|
2020-08-14 00:01:37 +00:00
|
|
|
),
|
|
|
|
),
|
2020-06-23 14:59:51 +00:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
2020-06-23 19:14:18 +00:00
|
|
|
Widget _getThumbnail() {
|
|
|
|
return Container(
|
2020-08-13 20:03:29 +00:00
|
|
|
child: ThumbnailWidget(
|
|
|
|
widget.file,
|
|
|
|
fit: BoxFit.contain,
|
|
|
|
),
|
2020-06-23 19:14:18 +00:00
|
|
|
constraints: BoxConstraints.expand(),
|
|
|
|
);
|
2020-06-19 23:03:26 +00:00
|
|
|
}
|
|
|
|
|
2020-06-23 14:59:51 +00:00
|
|
|
Widget _getVideoPlayer() {
|
2020-06-20 22:47:09 +00:00
|
|
|
_chewieController = ChewieController(
|
|
|
|
videoPlayerController: _videoPlayerController,
|
|
|
|
aspectRatio: _videoPlayerController.value.aspectRatio,
|
2020-06-21 17:44:21 +00:00
|
|
|
autoPlay: widget.autoPlay,
|
2020-06-20 22:47:09 +00:00
|
|
|
autoInitialize: true,
|
|
|
|
looping: true,
|
|
|
|
allowFullScreen: false,
|
2020-06-20 23:51:10 +00:00
|
|
|
customControls: VideoControls(),
|
2020-06-20 22:47:09 +00:00
|
|
|
);
|
2020-06-23 14:59:51 +00:00
|
|
|
return Chewie(controller: _chewieController);
|
2020-06-19 23:03:26 +00:00
|
|
|
}
|
|
|
|
}
|